From 995b809cce95e10a96cbff98aeb327c0fbcd2a44 Mon Sep 17 00:00:00 2001 From: Kathy Darling Date: Mon, 13 Jun 2016 13:47:03 -0500 Subject: [PATCH 001/298] add drag and drop support to select2 inputs. closes #11106 --- assets/js/admin/wc-enhanced-select.js | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/assets/js/admin/wc-enhanced-select.js b/assets/js/admin/wc-enhanced-select.js index 2cae8dd951d..ec548536d17 100644 --- a/assets/js/admin/wc-enhanced-select.js +++ b/assets/js/admin/wc-enhanced-select.js @@ -146,8 +146,19 @@ jQuery( function( $ ) { select2_args = $.extend( select2_args, getEnhancedSelectFormatString() ); $( this ).select2( select2_args ).addClass( 'enhanced' ); + + if( select2_args.multiple == true ){ + $( this ).select2( 'container' ).find( 'ul.select2-choices' ).sortable({ + containment: 'parent', + start: function() { $( this ).select2( 'onSortStart' ); }, + update: function() { $( this ).select2( 'onSortEnd' ); } + }); + } + }); + + // Ajax customer search boxes $( ':input.wc-customer-search' ).filter( ':not(.enhanced)' ).each( function() { var select2_args = { @@ -215,6 +226,15 @@ jQuery( function( $ ) { select2_args = $.extend( select2_args, getEnhancedSelectFormatString() ); $( this ).select2( select2_args ).addClass( 'enhanced' ); + + if( select2_args.multiple == true ){ + $( this ).select2( 'container' ).find( 'ul.select2-choices' ).sortable({ + containment: 'parent', + start: function() { $( this ).select2( 'onSortStart' ); }, + update: function() { $( this ).select2( 'onSortEnd' ); } + }); + } + }); }) From e670dc202b21b7007c1568de61b1d2e6b85c5b90 Mon Sep 17 00:00:00 2001 From: Kathy Darling Date: Mon, 13 Jun 2016 15:01:15 -0500 Subject: [PATCH 002/298] use data attribute data-sortable to toggle sorting --- assets/js/admin/wc-enhanced-select.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/js/admin/wc-enhanced-select.js b/assets/js/admin/wc-enhanced-select.js index ec548536d17..ed00e9541bc 100644 --- a/assets/js/admin/wc-enhanced-select.js +++ b/assets/js/admin/wc-enhanced-select.js @@ -147,7 +147,7 @@ jQuery( function( $ ) { $( this ).select2( select2_args ).addClass( 'enhanced' ); - if( select2_args.multiple == true ){ + if( $( this ).data( 'sortable' ) == true ){ $( this ).select2( 'container' ).find( 'ul.select2-choices' ).sortable({ containment: 'parent', start: function() { $( this ).select2( 'onSortStart' ); }, @@ -227,14 +227,14 @@ jQuery( function( $ ) { $( this ).select2( select2_args ).addClass( 'enhanced' ); - if( select2_args.multiple == true ){ + if( $( this ).data( 'sortable' ) == true ){ $( this ).select2( 'container' ).find( 'ul.select2-choices' ).sortable({ containment: 'parent', start: function() { $( this ).select2( 'onSortStart' ); }, update: function() { $( this ).select2( 'onSortEnd' ); } }); } - + }); }) From 7b18c317880d927abf62aad85a553e16a331f7ad Mon Sep 17 00:00:00 2001 From: Kathy Darling Date: Mon, 13 Jun 2016 15:16:42 -0500 Subject: [PATCH 003/298] add a move cursor to drag and drop enabled select2 tags --- assets/css/select2.scss | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/assets/css/select2.scss b/assets/css/select2.scss index db699b4deca..e7e8ce1c9bc 100644 --- a/assets/css/select2.scss +++ b/assets/css/select2.scss @@ -547,6 +547,11 @@ html[dir="rtl"] .select2-container-multi .select2-choices li background-color: #e4e4e4; } + +.select2-container-multi .ui-sortable .select2-search-choice { + cursor: move; +} + html[dir="rtl"] .select2-container-multi .select2-choices .select2-search-choice { margin: 3px 5px 3px 0; From 538e791165ca77b674126ba2028c773bb32830e6 Mon Sep 17 00:00:00 2001 From: zakalwe2016 Date: Fri, 17 Jun 2016 13:23:02 +0100 Subject: [PATCH 004/298] Add filter for product list --- includes/widgets/class-wc-widget-top-rated-products.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/widgets/class-wc-widget-top-rated-products.php b/includes/widgets/class-wc-widget-top-rated-products.php index c86b079e1ff..a6fad9a7e81 100644 --- a/includes/widgets/class-wc-widget-top-rated-products.php +++ b/includes/widgets/class-wc-widget-top-rated-products.php @@ -74,14 +74,14 @@ class WC_Widget_Top_Rated_Products extends WC_Widget { $this->widget_start( $args, $instance ); - echo '
    '; + echo apply_filters( 'woocommerce_before_widget_product_list', '
      ' ); while ( $r->have_posts() ) { $r->the_post(); wc_get_template( 'content-widget-product.php', array( 'show_rating' => true ) ); } - echo '
    '; + echo apply_filters( 'woocommerce_after_widget_product_list', '
' ); $this->widget_end( $args ); } From 40675d3c5f9281a1f71d1f69ce3f6c3965850da2 Mon Sep 17 00:00:00 2001 From: zakalwe2016 Date: Fri, 17 Jun 2016 13:23:42 +0100 Subject: [PATCH 005/298] Add filter for product list --- includes/widgets/class-wc-widget-recently-viewed.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/widgets/class-wc-widget-recently-viewed.php b/includes/widgets/class-wc-widget-recently-viewed.php index 008ed850fce..a18dcca9b32 100644 --- a/includes/widgets/class-wc-widget-recently-viewed.php +++ b/includes/widgets/class-wc-widget-recently-viewed.php @@ -75,14 +75,14 @@ class WC_Widget_Recently_Viewed extends WC_Widget { $this->widget_start( $args, $instance ); - echo '
    '; + echo apply_filters( 'woocommerce_before_widget_product_list', '
      ' ); while ( $r->have_posts() ) { $r->the_post(); wc_get_template( 'content-widget-product.php' ); } - echo '
    '; + echo apply_filters( 'woocommerce_after_widget_product_list', '
' ); $this->widget_end( $args ); } From 122ad3a4793f2a8921e46ed32d77aa3bca676e92 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 21 Jun 2016 20:03:56 +0100 Subject: [PATCH 006/298] Abstract order class --- includes/abstracts/abstract-wc-order.php | 3555 ++++++++-------------- 1 file changed, 1247 insertions(+), 2308 deletions(-) diff --git a/includes/abstracts/abstract-wc-order.php b/includes/abstracts/abstract-wc-order.php index e1fd9fe9f53..45734c971cc 100644 --- a/includes/abstracts/abstract-wc-order.php +++ b/includes/abstracts/abstract-wc-order.php @@ -1,94 +1,80 @@ 0, + 'parent_id' => 0, + 'status' => '', + 'type' => 'shop_order', + 'order_key' => '', + 'currency' => '', + 'version' => '', + 'prices_include_tax' => false, + 'date_created' => '', + 'date_modified' => '', + 'customer_id' => 0, + 'discount_total' => 0, + 'discount_tax' => 0, + 'shipping_total' => 0, + 'shipping_tax' => 0, + 'cart_tax' => 0, + 'total' => 0, + 'total_tax' => 0, + ); - /** @var $post WP_Post. */ - public $post = null; + /** + * Data stored in meta keys, but not considered "meta" for an order. + * @since 2.7.0 + * @var array + */ + protected $_internal_meta_keys = array( + '_customer_user', '_order_key', '_order_currency', '_cart_discount', + '_cart_discount_tax', '_order_shipping', '_order_shipping_tax', + '_order_tax', '_order_total', '_order_version', '_prices_include_tax', + '_payment_tokens', + ); - /** @public string Order type. */ - public $order_type = false; + /** + * Internal meta type used to store order data. + * @var string + */ + protected $_meta_type = 'post'; - /** @public string Order Date. */ - public $order_date = ''; - - /** @public string Order Modified Date. */ - public $modified_date = ''; - - /** @public string Customer Message (excerpt). */ - public $customer_message = ''; - - /** @public string Customer Note */ - public $customer_note = ''; - - /** @public string Order Status. */ - public $post_status = ''; - - /** @public bool Do prices include tax? */ - public $prices_include_tax = false; - - /** @public string Display mode for taxes in cart. */ - public $tax_display_cart = ''; - - /** @public bool Do totals display ex tax? */ - public $display_totals_ex_tax = false; - - /** @public bool Do cart prices display ex tax? */ - public $display_cart_ex_tax = false; - - /** @protected string Formatted address. Accessed via get_formatted_billing_address(). */ - protected $formatted_billing_address = ''; - - /** @protected string Formatted address. Accessed via get_formatted_shipping_address(). */ - protected $formatted_shipping_address = ''; + /** + * Stores meta in cache for future reads. + * A group must be set to to enable caching. + * @var string + */ + protected $_cache_group = 'order'; /** * Get the order if ID is passed, otherwise the order is new and empty. @@ -99,51 +85,990 @@ abstract class WC_Abstract_Order { * @param int|object|WC_Order $order Order to init. */ public function __construct( $order = 0 ) { - $this->prices_include_tax = get_option('woocommerce_prices_include_tax') == 'yes' ? true : false; - $this->tax_display_cart = get_option( 'woocommerce_tax_display_cart' ); - $this->display_totals_ex_tax = $this->tax_display_cart == 'excl' ? true : false; - $this->display_cart_ex_tax = $this->tax_display_cart == 'excl' ? true : false; - $this->init( $order ); + if ( is_numeric( $order ) && $order > 0 ) { + $this->read( $order ); + } elseif ( $order instanceof self ) { + $this->read( absint( $order->get_id() ) ); + } elseif ( ! empty( $order->ID ) ) { + $this->read( absint( $order->ID ) ); + } + } + + /* + |-------------------------------------------------------------------------- + | CRUD methods + |-------------------------------------------------------------------------- + | + | Methods which create, read, update and delete orders from the database. + | Written in abstract fashion so that the way orders are stored can be + | changed more easily in the future. + | + | A save method is included for convenience (chooses update or create based + | on if the order exists yet). + | + */ + + /** + * Get internal type (post type.) + * @return string + */ + public function get_type() { + return 'shop_order'; } /** - * Init/load the order object. Called from the constructor. - * - * @param int|object|WC_Order $order Order to init. + * Get a title for the new post type. */ - protected function init( $order ) { - if ( is_numeric( $order ) ) { - $this->id = absint( $order ); - $this->post = get_post( $order ); - $this->get_order( $this->id ); - } elseif ( $order instanceof WC_Order ) { - $this->id = absint( $order->id ); - $this->post = $order->post; - $this->get_order( $this->id ); - } elseif ( isset( $order->ID ) ) { - $this->id = absint( $order->ID ); - $this->post = $order; - $this->get_order( $this->id ); + protected function get_post_title() { + return sprintf( __( 'Order – %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ) ) ); + } + + /** + * Insert data into the database. + * @since 2.7.0 + */ + public function create() { + $this->set_order_key( 'wc_' . apply_filters( 'woocommerce_generate_order_key', uniqid( 'order_' ) ) ); + $this->set_date_created( current_time( 'timestamp' ) ); + + $order_id = wp_insert_post( apply_filters( 'woocommerce_new_order_data', array( + 'post_date' => date( 'Y-m-d H:i:s', $this->get_date_created() ), + 'post_date_gmt' => get_gmt_from_date( date( 'Y-m-d H:i:s', $this->get_date_created() ) ), + 'post_type' => $this->get_type(), + 'post_status' => 'wc-' . ( $this->get_status() ? $this->get_status() : apply_filters( 'woocommerce_default_order_status', 'pending' ) ), + 'ping_status' => 'closed', + 'post_author' => 1, + 'post_title' => $this->get_post_title(), + 'post_password' => uniqid( 'order_' ), + 'post_parent' => $this->get_parent_id(), + ) ), true ); + + if ( $order_id ) { + $this->set_id( $order_id ); + + // Set meta data + $this->update_post_meta( '_customer_user', $this->get_customer_id() ); + $this->update_post_meta( '_order_currency', $this->get_currency() ); + $this->update_post_meta( '_order_key', $this->get_order_key() ); + $this->update_post_meta( '_cart_discount', $this->get_discount_total( true ) ); + $this->update_post_meta( '_cart_discount_tax', $this->get_discount_tax( true ) ); + $this->update_post_meta( '_order_shipping', $this->get_shipping_total( true ) ); + $this->update_post_meta( '_order_shipping_tax', $this->get_shipping_tax( true ) ); + $this->update_post_meta( '_order_tax', $this->get_cart_tax( true ) ); + $this->update_post_meta( '_order_total', $this->get_total( true ) ); + $this->update_post_meta( '_order_version', $this->get_version() ); + $this->update_post_meta( '_prices_include_tax', $this->get_prices_include_tax() ); + $this->save_meta_data(); } } /** - * Remove all line items (products, coupons, shipping, taxes) from the order. + * Read from the database. + * @since 2.7.0 + * @param int $id ID of object to read. + */ + public function read( $id ) { + if ( empty( $id ) || ! ( $post_object = get_post( $id ) ) ) { + return; + } + $order_id = absint( $post_object->ID ); + + // Map standard post data + $this->set_id( $order_id ); + $this->set_date_created( $post_object->post_date ); + $this->set_date_modified( $post_object->post_modified ); + $this->set_status( $post_object->post_status ); + $this->set_order_type( $post_object->post_type ); + $this->set_customer_id( get_post_meta( $order_id, '_customer_user', true ) ); + $this->set_order_key( get_post_meta( $order_id, '_order_key', true ) ); + $this->set_currency( get_post_meta( $order_id, '_order_currency', true ) ); + $this->set_discount_total( get_post_meta( $order_id, '_cart_discount', true ) ); + $this->set_discount_tax( get_post_meta( $order_id, '_cart_discount_tax', true ) ); + $this->set_shipping_total( get_post_meta( $order_id, '_order_shipping', true ) ); + $this->set_shipping_tax( get_post_meta( $order_id, '_order_shipping_tax', true ) ); + $this->set_cart_tax( get_post_meta( $order_id, '_order_tax', true ) ); + $this->set_total( get_post_meta( $order_id, '_order_total', true ) ); + + // Orders store the state of prices including tax when created. + $this->set_prices_include_tax( metadata_exists( 'post', $order_id, '_prices_include_tax' ) ? 'yes' === get_post_meta( $order_id, '_prices_include_tax', true ) : 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); + + // Load meta data + $this->read_meta_data(); + } + + /** + * Post meta update wrapper. Sets or deletes based on value. + * @since 2.7.0 + * @return bool Was it changed? + */ + protected function update_post_meta( $key, $value ) { + if ( '' !== $value ) { + return update_post_meta( $this->get_id(), $key, $value ); + } else { + return delete_post_meta( $this->get_id(), $key ); + } + } + + /** + * Update data in the database. + * @since 2.7.0 + */ + public function update() { + global $wpdb; + + $order_id = $this->get_id(); + + $wpdb->update( + $wpdb->posts, + array( + 'post_date' => date( 'Y-m-d H:i:s', $this->get_date_created() ), + 'post_date_gmt' => get_gmt_from_date( date( 'Y-m-d H:i:s', $this->get_date_created() ) ), + 'post_status' => 'wc-' . ( $this->get_status() ? $this->get_status() : apply_filters( 'woocommerce_default_order_status', 'pending' ) ), + 'post_parent' => $this->get_parent_id(), + ), + array( + 'ID' => $order_id + ) + ); + + // Update meta data + $this->update_post_meta( '_customer_user', $this->get_customer_id() ); + $this->update_post_meta( '_order_currency', $this->get_currency() ); + $this->update_post_meta( '_order_key', $this->get_order_key() ); + $this->update_post_meta( '_cart_discount', $this->get_discount_total( true ) ); + $this->update_post_meta( '_cart_discount_tax', $this->get_discount_tax( true ) ); + $this->update_post_meta( '_order_shipping', $this->get_shipping_total( true ) ); + $this->update_post_meta( '_order_shipping_tax', $this->get_shipping_tax( true ) ); + $this->update_post_meta( '_order_tax', $this->get_cart_tax( true ) ); + $this->update_post_meta( '_order_total', $this->get_total( true ) ); + $this->update_post_meta( '_prices_include_tax', $this->get_prices_include_tax() ); + $this->save_meta_data(); + } + + /** + * Delete data from the database. + * @since 2.7.0 + */ + public function delete() { + wp_delete_post( $this->get_id() ); + } + + /** + * Save data to the database. + * @since 2.7.0 + * @return int order ID + */ + public function save() { + $this->set_version( WC_VERSION ); + + if ( ! $this->get_id() ) { + $this->create(); + } else { + $this->update(); + } + + clean_post_cache( $this->get_id() ); + wc_delete_shop_order_transients( $this->get_id() ); + + return $this->get_id(); + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + | + | Methods for getting data from the order object. + | + */ + + /** + * Get all class data in array format. + * @since 2.7.0 + * @return array + */ + public function get_data() { + return array_merge( + $this->_data, + array( + 'meta_data' => $this->get_meta_data(), + 'line_items' => $this->get_items( 'line_item' ), + 'tax_lines' => $this->get_items( 'tax' ), + 'shipping_lines' => $this->get_items( 'shipping' ), + 'fee_lines' => $this->get_items( 'fee' ), + 'coupon_lines' => $this->get_items( 'coupon' ), + ) + ); + } + + /** + * Get order ID. + * @since 2.7.0 + * @return integer + */ + public function get_id() { + return absint( $this->_data['id'] ); + } + + /** + * Get parent order ID. + * @since 2.7.0 + * @return integer + */ + public function get_parent_id() { + return absint( $this->_data['parent_id'] ); + } + + /** + * get_order_number function. * + * Gets the order number for display (by default, order ID). + * + * @return string + */ + public function get_order_number() { + return apply_filters( 'woocommerce_order_number', $this->get_id(), $this ); + } + + /** + * Get order key. + * @since 2.7.0 + * @return string + */ + public function get_order_key() { + return $this->_data['order_key']; + } + + /** + * Gets order currency. + * @return string + */ + public function get_currency() { + return apply_filters( 'woocommerce_get_currency', $this->_data['currency'], $this ); + } + + /** + * Get order_version + * @return string + */ + public function get_version() { + return $this->_data['version']; + } + + /** + * Get prices_include_tax + * @return bool + */ + public function get_prices_include_tax() { + return (bool) $this->_data['prices_include_tax']; + } + + /** + * Get Order Type + * @return string + */ + public function get_order_type() { + return $this->_data['type']; + } + + /** + * Get date_created + * @return int + */ + public function get_date_created() { + return absint( $this->_data['date_created'] ); + } + + /** + * Get date_modified + * @return int + */ + public function get_date_modified() { + return absint( $this->_data['date_modified'] ); + } + + /** + * Get customer_id + * @return int + */ + public function get_customer_id() { + return absint( $this->_data['customer_id'] ); + } + + /** + * Return the order statuses without wc- internal prefix. + * @return string + */ + public function get_status() { + return apply_filters( 'woocommerce_order_get_status', 'wc-' === substr( $this->_data['status'], 0, 3 ) ? substr( $this->_data['status'], 3 ) : $this->_data['status'], $this ); + } + + /** + * Alias for get_customer_id(). + * @since 2.2 + * @return int + */ + public function get_user_id() { + return $this->get_customer_id(); + } + + /** + * Get the user associated with the order. False for guests. + * + * @since 2.2 + * @return WP_User|false + */ + public function get_user() { + return $this->get_user_id() ? get_user_by( 'id', $this->get_user_id() ) : false; + } + + /** + * Get discount_total + * @param bool $raw Gets raw unfiltered value. + * @return string + */ + public function get_discount_total( $raw = false ) { + $value = wc_format_decimal( $this->_data['discount_total'] ); + return $raw ? $value : apply_filters( 'woocommerce_order_amount_discount_total', $value, $this ); + } + + /** + * Get discount_tax + * @param bool $raw Gets raw unfiltered value. + * @return string + */ + public function get_discount_tax( $raw = false ) { + $value = wc_format_decimal( $this->_data['discount_tax'] ); + return $raw ? $value : apply_filters( 'woocommerce_order_amount_discount_tax', $value, $this ); + } + + /** + * Get shipping_total + * @param bool $raw Gets raw unfiltered value. + * @return string + */ + public function get_shipping_total( $raw = false ) { + $value = wc_format_decimal( $this->_data['shipping_total'] ); + return $raw ? $value : apply_filters( 'woocommerce_order_amount_shipping_total', $value, $this ); + } + + /** + * Get shipping_tax. + * @param bool $raw Gets raw unfiltered value. + * @return string + */ + public function get_shipping_tax( $raw = false ) { + $value = wc_format_decimal( $this->_data['shipping_tax'] ); + return $raw ? $value : apply_filters( 'woocommerce_order_amount_shipping_tax', $value, $this ); + } + + /** + * Gets cart tax amount. + * @param bool $raw Gets raw unfiltered value. + * @return float + */ + public function get_cart_tax( $raw = false ) { + $value = wc_format_decimal( $this->_data['cart_tax'] ); + return $raw ? $value : apply_filters( 'woocommerce_order_amount_cart_tax', $value, $this ); + } + + /** + * Gets order grand total. incl. taxes. Used in gateways. Filtered. + * @param bool $raw Gets raw unfiltered value. + * @return float + */ + public function get_total( $raw = false ) { + $value = wc_format_decimal( $this->_data['total'], wc_get_price_decimals() ); + return $raw ? $value : apply_filters( 'woocommerce_order_amount_total', $value, $this ); + } + + /** + * Get total tax amount. Alias for get_order_tax(). + * + * @since 2.7.0 woocommerce_order_amount_total_tax filter has been removed to avoid + * these values being modified and then saved back to the DB. There are + * other, later hooks available to change totals on display. e.g. + * woocommerce_get_order_item_totals. + * @param bool $raw Gets raw unfiltered value. + * @return float + */ + public function get_total_tax( $raw = false ) { + $value = wc_format_decimal( $this->_data['total_tax'] ); + return $raw ? $value : apply_filters( 'woocommerce_order_amount_total_tax', $value, $this ); + } + + /** + * Gets the total discount amount. + * @param bool $ex_tax Show discount excl any tax. + * @return float + */ + public function get_total_discount( $ex_tax = true ) { + if ( $ex_tax ) { + $total_discount = $this->get_discount_total(); + } else { + $total_discount = $this->get_discount_total() + $this->get_discount_tax(); + } + return apply_filters( 'woocommerce_order_amount_total_discount', round( $total_discount, WC_ROUNDING_PRECISION ), $this ); + } + + /** + * Gets order subtotal. + * @return float + */ + public function get_subtotal() { + $subtotal = 0; + + foreach ( $this->get_items() as $item ) { + $subtotal += $item->get_subtotal(); + } + + return apply_filters( 'woocommerce_order_amount_subtotal', (double) $subtotal, $this ); + } + + /** + * Get taxes, merged by code, formatted ready for output. + * + * @return array + */ + public function get_tax_totals() { + $tax_totals = array(); + + foreach ( $this->get_items( 'tax' ) as $key => $tax ) { + $code = $tax->get_rate_code(); + + if ( ! isset( $tax_totals[ $code ] ) ) { + $tax_totals[ $code ] = new stdClass(); + $tax_totals[ $code ]->amount = 0; + } + + $tax_totals[ $code ]->id = $key; + $tax_totals[ $code ]->rate_id = $tax->get_rate_id(); + $tax_totals[ $code ]->is_compound = $tax->is_compound(); + $tax_totals[ $code ]->label = $tax->get_label(); + $tax_totals[ $code ]->amount += $tax->get_tax_total() + $tax->get_shipping_tax_total(); + $tax_totals[ $code ]->formatted_amount = wc_price( wc_round_tax_total( $tax_totals[ $code ]->amount ), array( 'currency' => $this->get_currency() ) ); + } + + if ( apply_filters( 'woocommerce_order_hide_zero_taxes', true ) ) { + $amounts = array_filter( wp_list_pluck( $tax_totals, 'amount' ) ); + $tax_totals = array_intersect_key( $tax_totals, $amounts ); + } + + return apply_filters( 'woocommerce_order_tax_totals', $tax_totals, $this ); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + | + | Functions for setting order data. These should not update anything in the + | database itself and should only change what is stored in the class + | object. However, for backwards compatibility pre 2.7.0 some of these + | setters may handle both. + | + */ + + /** + * Set order ID. + * @since 2.7.0 + * @param int $value + */ + public function set_id( $value ) { + $this->_data['id'] = absint( $value ); + } + + /** + * Set parent order ID. + * @since 2.7.0 + * @param int $value + */ + public function set_parent_id( $value ) { + $this->_data['parent_id'] = absint( $value ); + } + + /** + * Set order status. + * @since 2.7.0 + * @param string $new_status Status to change the order to. No internal wc- prefix is required. + * @param array details of change + */ + public function set_status( $new_status ) { + $old_status = $this->get_status(); + $new_status = 'wc-' === substr( $new_status, 0, 3 ) ? substr( $new_status, 3 ) : $new_status; + + // If the old status is unknown (e.g. draft) assume its pending for action usage. + if ( ! in_array( 'wc-' . $old_status, array_keys( wc_get_order_statuses() ) ) ) { + $old_status = 'pending'; + } + + if ( in_array( 'wc-' . $new_status, array_keys( wc_get_order_statuses() ) ) && $new_status !== $old_status ) { + $this->_data['status'] = 'wc-' . $new_status; + } else { + $new_status = $old_status; + } + + return array( + 'from' => $old_status, + 'to' => $new_status + ); + } + + /** + * Set Order Type + * @param string $value + */ + public function set_order_type( $value ) { + $this->_data['type'] = $value; + } + + /** + * Set order_key. + * @param string $value Max length 20 chars. + */ + public function set_order_key( $value ) { + $this->_data['order_key'] = substr( $value, 0, 20 ); + } + + /** + * Set order_version + * @param string $value + */ + public function set_version( $value ) { + $this->_data['version'] = $value; + } + + /** + * Set order_currency + * @param string $value + */ + public function set_currency( $value ) { + $this->_data['currency'] = $value; + } + + /** + * Set prices_include_tax + * @param bool $value + */ + public function set_prices_include_tax( $value ) { + $this->_data['prices_include_tax'] = (bool) $value; + } + + /** + * Set date_created + * @param string $timestamp Timestamp + */ + public function set_date_created( $timestamp ) { + $this->_data['date_created'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp ); + } + + /** + * Set date_modified + * @param string $timestamp + */ + public function set_date_modified( $timestamp ) { + $this->_data['date_modified'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp ); + } + + /** + * Set customer_id + * @param int $value + */ + public function set_customer_id( $value ) { + $this->_data['customer_id'] = absint( $value ); + } + + /** + * Set discount_total + * @param string $value + */ + public function set_discount_total( $value ) { + $this->_data['discount_total'] = wc_format_decimal( $value ); + } + + /** + * Set discount_tax + * @param string $value + */ + public function set_discount_tax( $value ) { + $this->_data['discount_tax'] = wc_format_decimal( $value ); + } + + /** + * Set shipping_total + * @param string $value + */ + public function set_shipping_total( $value ) { + $this->_data['shipping_total'] = wc_format_decimal( $value ); + } + + /** + * Set shipping_tax + * @param string $value + */ + public function set_shipping_tax( $value ) { + $this->_data['shipping_tax'] = wc_format_decimal( $value ); + $this->set_total_tax( $this->get_cart_tax() + $this->get_shipping_tax() ); + } + + /** + * Set cart tax + * @param string $value + */ + public function set_cart_tax( $value ) { + $this->_data['cart_tax'] = wc_format_decimal( $value ); + $this->set_total_tax( $this->get_cart_tax() + $this->get_shipping_tax() ); + } + + /** + * Sets order tax (sum of cart and shipping tax). Used internaly only. + * @param string $value + */ + protected function set_total_tax( $value ) { + $this->_data['total_tax'] = wc_format_decimal( $value ); + } + + /** + * Set total + * @param string $value + * @param string $deprecated Function used to set different totals based on this. + */ + public function set_total( $value, $deprecated = '' ) { + if ( $deprecated ) { + _deprecated_argument( 'total_type', '2.7', 'Use dedicated total setter methods instead.' ); + return $this->legacy_set_total( $value, $deprecated ); + } + $this->_data['total'] = wc_format_decimal( $value, wc_get_price_decimals() ); + } + + /* + |-------------------------------------------------------------------------- + | Order Item Handling + |-------------------------------------------------------------------------- + | + | Order items are used for products, taxes, shipping, and fees within + | each order. + | + */ + + /** + * Remove all line items (products, coupons, shipping, taxes) from the order. * @param string $type Order item type. Default null. */ public function remove_order_items( $type = null ) { global $wpdb; - if ( ! empty( $type ) ) { - $wpdb->query( $wpdb->prepare( "DELETE FROM itemmeta USING {$wpdb->prefix}woocommerce_order_itemmeta itemmeta INNER JOIN {$wpdb->prefix}woocommerce_order_items items WHERE itemmeta.order_item_id = items.order_item_id AND items.order_id = %d AND items.order_item_type = %s", $this->id, $type ) ); - $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = %s", $this->id, $type ) ); + $wpdb->query( $wpdb->prepare( "DELETE FROM itemmeta USING {$wpdb->prefix}woocommerce_order_itemmeta itemmeta INNER JOIN {$wpdb->prefix}woocommerce_order_items items WHERE itemmeta.order_item_id = items.order_item_id AND items.order_id = %d AND items.order_item_type = %s", $this->get_id(), $type ) ); + $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d AND order_item_type = %s", $this->get_id(), $type ) ); } else { - $wpdb->query( $wpdb->prepare( "DELETE FROM itemmeta USING {$wpdb->prefix}woocommerce_order_itemmeta itemmeta INNER JOIN {$wpdb->prefix}woocommerce_order_items items WHERE itemmeta.order_item_id = items.order_item_id and items.order_id = %d", $this->id ) ); - $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d", $this->id ) ); + $wpdb->query( $wpdb->prepare( "DELETE FROM itemmeta USING {$wpdb->prefix}woocommerce_order_itemmeta itemmeta INNER JOIN {$wpdb->prefix}woocommerce_order_items items WHERE itemmeta.order_item_id = items.order_item_id and items.order_id = %d", $this->get_id() ) ); + $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d", $this->get_id() ) ); } } + /** + * Return an array of items/products within this order. + * @param string|array $type Types of line items to get (array or string). + * @return Array of WC_Order_item + */ + public function get_items( $type = 'line_item' ) { + global $wpdb; + $get_items_sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d ", $this->get_id() ) . "AND order_item_type IN ( '" . implode( "','", array_map( 'esc_sql', (array) $type ) ) . "' ) ORDER BY order_item_id;"; + $items = $wpdb->get_results( $get_items_sql ); + $items = array_map( array( $this, 'get_item' ), array_combine( wp_list_pluck( $items, 'order_item_id' ), $items ) ); + + return apply_filters( 'woocommerce_order_get_items', $items, $this ); + } + + /** + * Return an array of fees within this order. + * @return array + */ + public function get_fees() { + return $this->get_items( 'fee' ); + } + + /** + * Return an array of taxes within this order. + * @return array + */ + public function get_taxes() { + return $this->get_items( 'tax' ); + } + + /** + * Return an array of shipping costs within this order. + * @return array + */ + public function get_shipping_methods() { + return $this->get_items( 'shipping' ); + } + + /** + * Gets formatted shipping method title. + * @return string + */ + public function get_shipping_method() { + $names = array(); + foreach ( $this->get_shipping_methods() as $shipping_method ) { + $names[] = $shipping_method->get_name(); + } + return apply_filters( 'woocommerce_order_shipping_method', implode( ', ', $names ), $this ); + } + + /** + * Get coupon codes only. + * @return array + */ + public function get_used_coupons() { + return array_map( 'trim', wp_list_pluck( $this->get_items( 'coupon' ), 'name' ) ); + } + + /** + * Gets the count of order items of a certain type. + * + * @param string $item_type + * @return string + */ + public function get_item_count( $item_type = '' ) { + $items = $this->get_items( empty( $item_type ) ? 'line_item' : $item_type ); + $count = 0; + + foreach ( $items as $item ) { + $count += $item->get_qty(); + } + + return apply_filters( 'woocommerce_get_item_count', $count, $item_type, $this ); + } + + /** + * Get an order item object, based on it's type. + * @since 2.7.0 + * @param int $item_id + * @return WC_Order_Item + */ + public function get_item( $item_id ) { + return WC_Order_Factory::get_order_item( $item_id ); + } + + /** + * Add a product line item to the order. + * Order must be saved prior to adding items. + * @param \WC_Product $product + * @param array $args + * @param array $deprecated qty was passed as arg 2 prior to 2.7.0 + * @return int order item ID + */ + public function add_product( $product, $args = array(), $deprecated = array() ) { + if ( ! is_array( $args ) ) { + _deprecated_argument( 'qty', '2.7', 'Pass only product and args' ); + $qty = $args; + $args = $deprecated; + $args['qty'] = $qty; + } + + $args = wp_parse_args( $args, array( + 'qty' => 1, + 'name' => $product ? $product->get_title() : '', + 'tax_class' => $product ? $product->get_tax_class() : '', + 'product_id' => $product ? $product->get_id() : '', + 'variation_id' => $product && isset( $product->variation_id ) ? $product->variation_id : 0, + 'subtotal' => $product ? $product->get_price_excluding_tax( $args['qty'] ) : '', + 'total' => $product ? $product->get_price_excluding_tax( $args['qty'] ) : '', + 'subtotal_tax' => 0, + 'total_tax' => 0, + 'variation' => array(), + 'taxes' => array( + 'subtotal' => array(), + 'total' => array(), + ), + ) ); + + // BW compatibility with old args + if ( isset( $args['totals'] ) ) { + foreach ( $args['totals'] as $key => $value ) { + if ( 'tax' === $key ) { + $args['total_tax'] = $value; + } elseif ( 'tax_data' === $key ) { + $args['taxes'] = $value; + } else { + $args[ $key ] = $value; + } + } + } + + $item = new WC_Order_Item_Product( $args ); + + // Handle backorders + if ( $product->backorders_require_notification() && $product->is_on_backorder( $args['qty'] ) ) { + $item->add_meta_data( apply_filters( 'woocommerce_backordered_item_meta_name', __( 'Backordered', 'woocommerce' ) ), $args['qty'] - max( 0, $product->get_total_stock() ), true ); + } + + $item->set_order_id( $this->get_id() ? $this->get_id() : $this->save() ); + $item->save(); + + if ( has_action( 'woocommerce_order_add_product' ) ) { + _deprecated_function( 'Action: woocommerce_order_add_product', '2.7', 'Use woocommerce_new_order_item action instead.' ); + do_action( 'woocommerce_order_add_product', $this->get_id(), $item->get_id(), $product, $qty, $args ); + } + + return $item->get_id(); + } + + /** + * Add coupon code to the order. + * Order must be saved prior to adding items. + * @param array $args + * @param int $deprecated1 2.7.0 code, discount, tax were passed. + * @param int $deprecated2 2.7.0 code, discount, tax were passed. + * @return int order item ID + */ + public function add_coupon( $args = array(), $deprecated1 = 0, $deprecated2 = 0 ) { + if ( ! is_array( $args ) ) { + _deprecated_argument( 'code', '2.7', 'Pass only an array of args' ); + $args = array( + 'code' => $args, + 'discount' => $deprecated1, + 'discount_tax' => $deprecated2, + ); + } + + $args = wp_parse_args( $args, array( + 'code' => '', + 'discount' => 0, + 'discount_tax' => 0, + ) ); + + $item = new WC_Order_Item_Coupon( $args ); + $item->set_order_id( $this->get_id() ? $this->get_id() : $this->save() ); + $item->save(); + + if ( has_action( 'woocommerce_order_add_coupon' ) ) { + _deprecated_function( 'Action: woocommerce_order_add_coupon', '2.7', 'Use woocommerce_new_order_item action instead.' ); + do_action( 'woocommerce_order_add_coupon', $this->get_id(), $item->get_id(), $args['code'], $args['discount'], $args['discount_tax'] ); + } + + return $item->get_id(); + } + + /** + * Add a tax row to the order. + * Order must be saved prior to adding items. + * @since 2.2 + * @param array $args + * @param int $deprecated1 2.7.0 tax_rate_id, amount, shipping amount. + * @param int $deprecated2 2.7.0 tax_rate_id, amount, shipping amount. + * @return int order item ID + */ + public function add_tax( $args = array(), $deprecated1 = 0, $deprecated2 = 0 ) { + if ( ! is_array( $args ) ) { + _deprecated_argument( 'tax_rate_id', '2.7', 'Pass only an array of args' ); + $args = array( + 'rate_id' => $args, + 'tax_total' => $deprecated1, + 'shipping_tax_total' => $deprecated2, + ); + } + + $args = wp_parse_args( $args, array( + 'rate_id' => '', + 'tax_total' => 0, + 'shipping_tax_total' => 0, + 'rate_code' => isset( $args['rate_id'] ) ? WC_Tax::get_rate_code( $args['rate_id'] ) : '', + 'label' => isset( $args['rate_id'] ) ? WC_Tax::get_rate_label( $args['rate_id'] ) : '', + 'compound' => isset( $args['rate_id'] ) ? WC_Tax::is_compound( $args['rate_id'] ) : '', + ) ); + + $item = new WC_Order_Item_Tax( $args ); + $item->set_order_id( $this->get_id() ? $this->get_id() : $this->save() ); + $item->save(); + + if ( has_action( 'woocommerce_order_add_tax' ) ) { + _deprecated_function( 'Action: woocommerce_order_add_tax', '2.7', 'Use woocommerce_new_order_item action instead.' ); + do_action( 'woocommerce_order_add_tax', $this->get_id(), $item->get_id(), $args['rate_id'], $args['tax_total'], $args['shipping_tax_total'] ); + } + + return $item->get_id(); + } + + /** + * Add a shipping row to the order. + * Order must be saved prior to adding items. + * @param WC_Shipping_Rate shipping_rate + * @return int order item ID + */ + public function add_shipping( $shipping_rate ) { + $item = new WC_Order_Item_Shipping( array( + 'method_title' => $shipping_rate->label, + 'method_id' => $shipping_rate->id, + 'total' => wc_format_decimal( $shipping_rate->cost ), + 'taxes' => $shipping_rate->taxes, + 'meta_data' => $shipping_rate->get_meta_data(), + ) ); + $item->set_order_id( $this->get_id() ? $this->get_id() : $this->save() ); + $item->save(); + + if ( has_action( 'woocommerce_order_add_shipping' ) ) { + _deprecated_function( 'Action: woocommerce_order_add_shipping', '2.7', 'Use woocommerce_new_order_item action instead.' ); + do_action( 'woocommerce_order_add_shipping', $this->get_id(), $item->get_id(), $shipping_rate ); + } + + return $item->get_id(); + } + + /** + * Add a fee to the order. + * Order must be saved prior to adding items. + * @param object $fee + * @return int updated order item ID + */ + public function add_fee( $fee ) { + $item = new WC_Order_Item_Fee( array( + 'name' => $fee->name, + 'tax_class' => $fee->taxable ? $fee->tax_class : 0, + 'total' => $fee->amount, + 'total_tax' => $fee->tax, + 'taxes' => array( + 'total' => $fee->tax_data, + ), + ) ); + + $item->set_order_id( $this->get_id() ? $this->get_id() : $this->save() ); + $item->save(); + + if ( has_action( 'woocommerce_order_add_fee' ) ) { + _deprecated_function( 'Action: woocommerce_order_add_fee', '2.7', 'Use woocommerce_new_order_item action instead.' ); + do_action( 'woocommerce_order_add_fee', $this->get_id(), $item->get_id(), $fee ); + } + + return $item->get_id(); + } + + /** + * Add a payment token to an order + * + * @since 2.6 + * @param WC_Payment_Token $token Payment token object + * @return boolean|int The new token ID or false if it failed. + */ + public function add_payment_token( $token ) { + if ( empty( $token ) || ! ( $token instanceof WC_Payment_Token ) ) { + return false; + } + + $token_ids = get_post_meta( $this->get_id(), '_payment_tokens', true ); + + if ( empty ( $token_ids ) ) { + $token_ids = array(); + } + + $token_ids[] = $token->get_id(); + + update_post_meta( $this->get_id(), '_payment_tokens', $token_ids ); + do_action( 'woocommerce_payment_token_added_to_order', $this->get_id(), $token->get_id(), $token, $token_ids ); + return $token->get_id(); + } + /** * Returns a list of all payment tokens associated with the current order * @@ -151,585 +1076,90 @@ abstract class WC_Abstract_Order { * @return array An array of payment token objects */ public function get_payment_tokens() { - return WC_Payment_Tokens::get_order_tokens( $this->id ); + return WC_Payment_Tokens::get_order_tokens( $this->get_id() ); } - /** - * Add a payment token to an order - * - * @since 2.6 - * @param WC_Payment_Token $token Payment token object - * @return boolean True if the token was added, false if not - */ - public function add_payment_token( $token ) { - if ( empty( $token ) || ! ( $token instanceof WC_Payment_Token ) ) { - return false; - } - - $token_ids = get_post_meta( $this->id, '_payment_tokens', true ); - if ( empty ( $token_ids ) ) { - $token_ids = array(); - } - $token_ids[] = $token->get_id(); - - update_post_meta( $this->id, '_payment_tokens', $token_ids ); - do_action( 'woocommerce_payment_token_added_to_order', $this->id, $token->get_id(), $token, $token_ids ); - return true; - } + /* + |-------------------------------------------------------------------------- + | Calculations. + |-------------------------------------------------------------------------- + | + | These methods calculate order totals and taxes based on the current data. + | + */ /** - * Set the payment method for the order. - * - * @param WC_Payment_Gateway|string $payment_method - */ - public function set_payment_method( $payment_method = '' ) { - if ( is_object( $payment_method ) ) { - update_post_meta( $this->id, '_payment_method', $payment_method->id ); - update_post_meta( $this->id, '_payment_method_title', $payment_method->get_title() ); - } else { - update_post_meta( $this->id, '_payment_method', '' ); - update_post_meta( $this->id, '_payment_method_title', '' ); - } - } - - /** - * Set the customer address. - * - * @param array $address Address data. - * @param string $type billing or shipping. - */ - public function set_address( $address, $type = 'billing' ) { - - foreach ( $address as $key => $value ) { - update_post_meta( $this->id, "_{$type}_" . $key, $value ); - } - } - - /** - * Returns the requested address in raw, non-formatted way. - * @since 2.4.0 - * @param string $type Billing or shipping. Anything else besides 'billing' will return shipping address. - * @return array The stored address after filter. - */ - public function get_address( $type = 'billing' ) { - - if ( 'billing' === $type ) { - $address = array( - 'first_name' => $this->billing_first_name, - 'last_name' => $this->billing_last_name, - 'company' => $this->billing_company, - 'address_1' => $this->billing_address_1, - 'address_2' => $this->billing_address_2, - 'city' => $this->billing_city, - 'state' => $this->billing_state, - 'postcode' => $this->billing_postcode, - 'country' => $this->billing_country, - 'email' => $this->billing_email, - 'phone' => $this->billing_phone, - ); - } else { - $address = array( - 'first_name' => $this->shipping_first_name, - 'last_name' => $this->shipping_last_name, - 'company' => $this->shipping_company, - 'address_1' => $this->shipping_address_1, - 'address_2' => $this->shipping_address_2, - 'city' => $this->shipping_city, - 'state' => $this->shipping_state, - 'postcode' => $this->shipping_postcode, - 'country' => $this->shipping_country, - ); - } - - return apply_filters( 'woocommerce_get_order_address', $address, $type, $this ); - } - - /** - * Add a product line item to the order. + * Calculate shipping total. * * @since 2.2 - * @param \WC_Product $product - * @param int $qty Line item quantity. - * @param array $args - * @return int|bool Item ID or false. + * @return float */ - public function add_product( $product, $qty = 1, $args = array() ) { - $args = wp_parse_args( $args, array( - 'variation' => array(), - 'totals' => array() - ) ); + public function calculate_shipping() { + $shipping_total = 0; - if ( ! $product ) { - return false; + foreach ( $this->get_shipping_methods() as $shipping ) { + $shipping_total += $shipping->get_total(); } - $item_id = wc_add_order_item( $this->id, array( - 'order_item_name' => $product->get_title(), - 'order_item_type' => 'line_item' - ) ); + $this->set_shipping_total( $shipping_total ); + $this->save(); - if ( ! $item_id ) { - return false; - } - - wc_add_order_item_meta( $item_id, '_qty', wc_stock_amount( $qty ) ); - wc_add_order_item_meta( $item_id, '_tax_class', $product->get_tax_class() ); - wc_add_order_item_meta( $item_id, '_product_id', $product->id ); - wc_add_order_item_meta( $item_id, '_variation_id', isset( $product->variation_id ) ? $product->variation_id : 0 ); - - // Set line item totals, either passed in or from the product - wc_add_order_item_meta( $item_id, '_line_subtotal', wc_format_decimal( isset( $args['totals']['subtotal'] ) ? $args['totals']['subtotal'] : $product->get_price_excluding_tax( $qty ) ) ); - wc_add_order_item_meta( $item_id, '_line_total', wc_format_decimal( isset( $args['totals']['total'] ) ? $args['totals']['total'] : $product->get_price_excluding_tax( $qty ) ) ); - wc_add_order_item_meta( $item_id, '_line_subtotal_tax', wc_format_decimal( isset( $args['totals']['subtotal_tax'] ) ? $args['totals']['subtotal_tax'] : 0 ) ); - wc_add_order_item_meta( $item_id, '_line_tax', wc_format_decimal( isset( $args['totals']['tax'] ) ? $args['totals']['tax'] : 0 ) ); - - // Save tax data - Since 2.2 - if ( isset( $args['totals']['tax_data'] ) ) { - - $tax_data = array(); - $tax_data['total'] = array_map( 'wc_format_decimal', $args['totals']['tax_data']['total'] ); - $tax_data['subtotal'] = array_map( 'wc_format_decimal', $args['totals']['tax_data']['subtotal'] ); - - wc_add_order_item_meta( $item_id, '_line_tax_data', $tax_data ); - } else { - wc_add_order_item_meta( $item_id, '_line_tax_data', array( 'total' => array(), 'subtotal' => array() ) ); - } - - // Add variation meta - if ( ! empty( $args['variation'] ) ) { - foreach ( $args['variation'] as $key => $value ) { - wc_add_order_item_meta( $item_id, str_replace( 'attribute_', '', $key ), $value ); - } - } - - // Backorders - if ( $product->backorders_require_notification() && $product->is_on_backorder( $qty ) ) { - wc_add_order_item_meta( $item_id, apply_filters( 'woocommerce_backordered_item_meta_name', __( 'Backordered', 'woocommerce' ) ), $qty - max( 0, $product->get_total_stock() ) ); - } - - do_action( 'woocommerce_order_add_product', $this->id, $item_id, $product, $qty, $args ); - - return $item_id; - } - - - /** - * Update a line item for the order. - * - * Note this does not update order totals. - * - * @since 2.2 - * @param int $item_id order item ID. - * @param array $args data to update. - * @param WC_Product $product - * @return bool - */ - public function update_product( $item_id, $product, $args ) { - - if ( ! $item_id || ! is_object( $product ) ) { - return false; - } - - // quantity - if ( isset( $args['qty'] ) ) { - wc_update_order_item_meta( $item_id, '_qty', wc_stock_amount( $args['qty'] ) ); - } - - // tax class - if ( isset( $args['tax_class'] ) ) { - wc_update_order_item_meta( $item_id, '_tax_class', $args['tax_class'] ); - } - - // set item totals, either provided or from product - if ( isset( $args['qty'] ) ) { - wc_update_order_item_meta( $item_id, '_line_subtotal', wc_format_decimal( isset( $args['totals']['subtotal'] ) ? $args['totals']['subtotal'] : $product->get_price_excluding_tax( $args['qty'] ) ) ); - wc_update_order_item_meta( $item_id, '_line_total', wc_format_decimal( isset( $args['totals']['total'] ) ? $args['totals']['total'] : $product->get_price_excluding_tax( $args['qty'] ) ) ); - } - - // set item tax totals - wc_update_order_item_meta( $item_id, '_line_subtotal_tax', wc_format_decimal( isset( $args['totals']['subtotal_tax'] ) ? $args['totals']['subtotal_tax'] : 0 ) ); - wc_update_order_item_meta( $item_id, '_line_tax', wc_format_decimal( isset( $args['totals']['tax'] ) ? $args['totals']['tax'] : 0 ) ); - - // variation meta - if ( isset( $args['variation'] ) && is_array( $args['variation'] ) ) { - - foreach ( $args['variation'] as $key => $value ) { - wc_update_order_item_meta( $item_id, str_replace( 'attribute_', '', $key ), $value ); - } - } - - // backorders - if ( isset( $args['qty'] ) && $product->backorders_require_notification() && $product->is_on_backorder( $args['qty'] ) ) { - wc_update_order_item_meta( $item_id, apply_filters( 'woocommerce_backordered_item_meta_name', __( 'Backordered', 'woocommerce' ) ), $args['qty'] - max( 0, $product->get_total_stock() ) ); - } - - do_action( 'woocommerce_order_edit_product', $this->id, $item_id, $args, $product ); - - return true; - } - - - /** - * Add coupon code to the order. - * - * @param string $code - * @param int $discount_amount - * @param int $discount_amount_tax "Discounted" tax - used for tax inclusive prices. - * @return int|bool Item ID or false. - */ - public function add_coupon( $code, $discount_amount = 0, $discount_amount_tax = 0 ) { - $item_id = wc_add_order_item( $this->id, array( - 'order_item_name' => $code, - 'order_item_type' => 'coupon' - ) ); - - if ( ! $item_id ) { - return false; - } - - wc_add_order_item_meta( $item_id, 'discount_amount', $discount_amount ); - wc_add_order_item_meta( $item_id, 'discount_amount_tax', $discount_amount_tax ); - - do_action( 'woocommerce_order_add_coupon', $this->id, $item_id, $code, $discount_amount, $discount_amount_tax ); - - return $item_id; - } - - /** - * Update coupon for order. - * - * Note this does not update order totals. - * - * @since 2.2 - * @param int $item_id - * @param array $args - * @return bool - */ - public function update_coupon( $item_id, $args ) { - if ( ! $item_id ) { - return false; - } - - // code - if ( isset( $args['code'] ) ) { - wc_update_order_item( $item_id, array( 'order_item_name' => $args['code'] ) ); - } - - // amount - if ( isset( $args['discount_amount'] ) ) { - wc_update_order_item_meta( $item_id, 'discount_amount', wc_format_decimal( $args['discount_amount'] ) ); - } - if ( isset( $args['discount_amount_tax'] ) ) { - wc_add_order_item_meta( $item_id, 'discount_amount_tax', wc_format_decimal( $args['discount_amount_tax'] ) ); - } - - do_action( 'woocommerce_order_update_coupon', $this->id, $item_id, $args ); - - return true; - } - - /** - * Add a tax row to the order. - * - * @since 2.2 - * @param int tax_rate_id - * @return int|bool Item ID or false. - */ - public function add_tax( $tax_rate_id, $tax_amount = 0, $shipping_tax_amount = 0 ) { - - $code = WC_Tax::get_rate_code( $tax_rate_id ); - - if ( ! $code ) { - return false; - } - - $item_id = wc_add_order_item( $this->id, array( - 'order_item_name' => $code, - 'order_item_type' => 'tax' - ) ); - - if ( ! $item_id ) { - return false; - } - - wc_add_order_item_meta( $item_id, 'rate_id', $tax_rate_id ); - wc_add_order_item_meta( $item_id, 'label', WC_Tax::get_rate_label( $tax_rate_id ) ); - wc_add_order_item_meta( $item_id, 'compound', WC_Tax::is_compound( $tax_rate_id ) ? 1 : 0 ); - wc_add_order_item_meta( $item_id, 'tax_amount', wc_format_decimal( $tax_amount ) ); - wc_add_order_item_meta( $item_id, 'shipping_tax_amount', wc_format_decimal( $shipping_tax_amount ) ); - - do_action( 'woocommerce_order_add_tax', $this->id, $item_id, $tax_rate_id, $tax_amount, $shipping_tax_amount ); - - return $item_id; - } - - /** - * Add a shipping row to the order. - * - * @param WC_Shipping_Rate shipping_rate - * @return int|bool Item ID or false. - */ - public function add_shipping( $shipping_rate ) { - - $item_id = wc_add_order_item( $this->id, array( - 'order_item_name' => $shipping_rate->label, - 'order_item_type' => 'shipping' - ) ); - - if ( ! $item_id ) { - return false; - } - - wc_add_order_item_meta( $item_id, 'method_id', $shipping_rate->id ); - wc_add_order_item_meta( $item_id, 'cost', wc_format_decimal( $shipping_rate->cost ) ); - - // Save shipping taxes - Since 2.2 - $taxes = array_map( 'wc_format_decimal', $shipping_rate->taxes ); - wc_add_order_item_meta( $item_id, 'taxes', $taxes ); - - // Store meta - $shipping_meta = $shipping_rate->get_meta_data(); - if ( ! empty( $shipping_meta ) ) { - foreach ( $shipping_rate->get_meta_data() as $key => $value ) { - wc_add_order_item_meta( $item_id, $key, $value ); - } - } - - do_action( 'woocommerce_order_add_shipping', $this->id, $item_id, $shipping_rate ); - - // Update total - $this->set_total( $this->order_shipping + wc_format_decimal( $shipping_rate->cost ), 'shipping' ); - - return $item_id; - } - - /** - * Update shipping method for order. - * - * Note this does not update the order total. - * - * @since 2.2 - * @param int $item_id - * @param array $args - * @return bool - */ - public function update_shipping( $item_id, $args ) { - - if ( ! $item_id ) { - return false; - } - - // method title - if ( isset( $args['method_title'] ) ) { - wc_update_order_item( $item_id, array( 'order_item_name' => $args['method_title'] ) ); - } - - // method ID - if ( isset( $args['method_id'] ) ) { - wc_update_order_item_meta( $item_id, 'method_id', $args['method_id'] ); - } - - // method cost - if ( isset( $args['cost'] ) ) { - // Get old cost before updating - $old_cost = wc_get_order_item_meta( $item_id, 'cost' ); - - // Update - wc_update_order_item_meta( $item_id, 'cost', wc_format_decimal( $args['cost'] ) ); - - // Update total - $this->set_total( $this->order_shipping - wc_format_decimal( $old_cost ) + wc_format_decimal( $args['cost'] ), 'shipping' ); - } - - do_action( 'woocommerce_order_update_shipping', $this->id, $item_id, $args ); - - return true; - } - - /** - * Add a fee to the order. - * - * @param object $fee - * @return int|bool Item ID or false. - */ - public function add_fee( $fee ) { - - $item_id = wc_add_order_item( $this->id, array( - 'order_item_name' => $fee->name, - 'order_item_type' => 'fee' - ) ); - - if ( ! $item_id ) { - return false; - } - - if ( $fee->taxable ) { - wc_add_order_item_meta( $item_id, '_tax_class', $fee->tax_class ); - } else { - wc_add_order_item_meta( $item_id, '_tax_class', '0' ); - } - - wc_add_order_item_meta( $item_id, '_line_total', wc_format_decimal( $fee->amount ) ); - wc_add_order_item_meta( $item_id, '_line_tax', wc_format_decimal( $fee->tax ) ); - - // Save tax data - Since 2.2 - $tax_data = array_map( 'wc_format_decimal', $fee->tax_data ); - wc_add_order_item_meta( $item_id, '_line_tax_data', array( 'total' => $tax_data ) ); - - do_action( 'woocommerce_order_add_fee', $this->id, $item_id, $fee ); - - return $item_id; - } - - /** - * Update fee for order. - * - * Note this does not update order totals. - * - * @since 2.2 - * @param int $item_id - * @param array $args - * @return bool - */ - public function update_fee( $item_id, $args ) { - - if ( ! $item_id ) { - return false; - } - - // name - if ( isset( $args['name'] ) ) { - wc_update_order_item( $item_id, array( 'order_item_name' => $args['name'] ) ); - } - - // tax class - if ( isset( $args['tax_class'] ) ) { - wc_update_order_item_meta( $item_id, '_tax_class', $args['tax_class'] ); - } - - // total - if ( isset( $args['line_total'] ) ) { - wc_update_order_item_meta( $item_id, '_line_total', wc_format_decimal( $args['line_total'] ) ); - } - - // total tax - if ( isset( $args['line_tax'] ) ) { - wc_update_order_item_meta( $item_id, '_line_tax', wc_format_decimal( $args['line_tax'] ) ); - } - - do_action( 'woocommerce_order_update_fee', $this->id, $item_id, $args ); - - return true; - } - - /** - * Set an order total. - * - * @param float $amount - * @param string $total_type - * - * @return bool - */ - public function set_total( $amount, $total_type = 'total' ) { - - if ( ! in_array( $total_type, array( 'shipping', 'tax', 'shipping_tax', 'total', 'cart_discount', 'cart_discount_tax' ) ) ) { - return false; - } - - switch ( $total_type ) { - case 'total' : - $key = '_order_total'; - $amount = wc_format_decimal( $amount, wc_get_price_decimals() ); - break; - case 'cart_discount' : - case 'cart_discount_tax' : - $key = '_' . $total_type; - $amount = wc_format_decimal( $amount ); - break; - default : - $key = '_order_' . $total_type; - $amount = wc_format_decimal( $amount ); - break; - } - - update_post_meta( $this->id, $key, $amount ); - - return true; + return $this->get_shipping_total(); } /** * Calculate taxes for all line items and shipping, and store the totals and tax rows. * * Will use the base country unless customer addresses are set. - * - * @return bool success or fail. + * @param $args array Added in 2.7.0 to pass things like location. */ - public function calculate_taxes() { - $tax_total = 0; - $shipping_tax_total = 0; - $taxes = array(); - $shipping_taxes = array(); - $tax_based_on = get_option( 'woocommerce_tax_based_on' ); - - // If is_vat_exempt is 'yes', or wc_tax_enabled is false, return and do nothing. - if ( 'yes' === $this->is_vat_exempt || ! wc_tax_enabled() ) { - return false; - } - - if ( 'billing' === $tax_based_on ) { - $country = $this->billing_country; - $state = $this->billing_state; - $postcode = $this->billing_postcode; - $city = $this->billing_city; - } elseif ( 'shipping' === $tax_based_on ) { - $country = $this->shipping_country; - $state = $this->shipping_state; - $postcode = $this->shipping_postcode; - $city = $this->shipping_city; - } + public function calculate_taxes( $args = array() ) { + $found_tax_classes = array(); + $tax_based_on = get_option( 'woocommerce_tax_based_on' ); + $args = wp_parse_args( $args, array( + 'country' => 'billing' === $tax_based_on ? $this->get_billing_country() : $this->get_shipping_country(), + 'state' => 'billing' === $tax_based_on ? $this->get_billing_state() : $this->get_shipping_state(), + 'postcode' => 'billing' === $tax_based_on ? $this->get_billing_postcode() : $this->get_shipping_postcode(), + 'city' => 'billing' === $tax_based_on ? $this->get_billing_city() : $this->get_shipping_city(), + ) ); // Default to base - if ( 'base' === $tax_based_on || empty( $country ) ) { - $default = wc_get_base_location(); - $country = $default['country']; - $state = $default['state']; - $postcode = ''; - $city = ''; + if ( 'base' === $tax_based_on || empty( $args['country'] ) ) { + $default = wc_get_base_location(); + $args['country'] = $default['country']; + $args['state'] = $default['state']; + $args['postcode'] = ''; + $args['city'] = ''; } - // Get items + // Calc taxes for line items foreach ( $this->get_items( array( 'line_item', 'fee' ) ) as $item_id => $item ) { + $tax_class = $item->get_tax_class(); + $tax_status = $item->get_tax_status(); + $found_tax_classes[] = $tax_class; - $product = $this->get_product_from_item( $item ); - $line_total = isset( $item['line_total'] ) ? $item['line_total'] : 0; - $line_subtotal = isset( $item['line_subtotal'] ) ? $item['line_subtotal'] : 0; - $tax_class = $item['tax_class']; - $item_tax_status = $product ? $product->get_tax_status() : 'taxable'; - - if ( '0' !== $tax_class && 'taxable' === $item_tax_status ) { - + if ( '0' !== $tax_class && 'taxable' === $tax_status ) { $tax_rates = WC_Tax::find_rates( array( - 'country' => $country, - 'state' => $state, - 'postcode' => $postcode, - 'city' => $city, - 'tax_class' => $tax_class + 'country' => $args['country'], + 'state' => $args['state'], + 'postcode' => $args['postcode'], + 'city' => $args['city'], + 'tax_class' => $tax_class, ) ); - $line_subtotal_taxes = WC_Tax::calc_tax( $line_subtotal, $tax_rates, false ); - $line_taxes = WC_Tax::calc_tax( $line_total, $tax_rates, false ); - $line_subtotal_tax = max( 0, array_sum( $line_subtotal_taxes ) ); - $line_tax = max( 0, array_sum( $line_taxes ) ); - $tax_total += $line_tax; + $total = $item->get_total(); + $taxes = WC_Tax::calc_tax( $total, $tax_rates, false ); - wc_update_order_item_meta( $item_id, '_line_subtotal_tax', wc_format_decimal( $line_subtotal_tax ) ); - wc_update_order_item_meta( $item_id, '_line_tax', wc_format_decimal( $line_tax ) ); - wc_update_order_item_meta( $item_id, '_line_tax_data', array( 'total' => $line_taxes, 'subtotal' => $line_subtotal_taxes ) ); - - // Sum the item taxes - foreach ( array_keys( $taxes + $line_taxes ) as $key ) { - $taxes[ $key ] = ( isset( $line_taxes[ $key ] ) ? $line_taxes[ $key ] : 0 ) + ( isset( $taxes[ $key ] ) ? $taxes[ $key ] : 0 ); + if ( $item->is_type( 'line_item' ) ) { + $subtotal = $item->get_subtotal(); + $subtotal_taxes = WC_Tax::calc_tax( $subtotal, $tax_rates, false ); + $subtotal_tax = max( 0, array_sum( $subtotal_taxes ) ); + $item->set_subtotal_tax( $subtotal_tax ); + $item->set_taxes( array( 'total' => $taxes, 'subtotal' => $subtotal_taxes ) ); + } else { + $item->set_taxes( array( 'total' => $taxes ) ); } + $item->save(); } } @@ -745,10 +1175,10 @@ abstract class WC_Abstract_Order { $tax_class = sanitize_title( $tax_class ); if ( in_array( $tax_class, $found_tax_classes ) ) { $tax_rates = WC_Tax::find_shipping_rates( array( - 'country' => $country, - 'state' => $state, - 'postcode' => $postcode, - 'city' => $city, + 'country' => $args['country'], + 'state' => $args['state'], + 'postcode' => $args['postcode'], + 'city' => $args['city'], 'tax_class' => $tax_class, ) ); break; @@ -756,100 +1186,37 @@ abstract class WC_Abstract_Order { } } else { $tax_rates = WC_Tax::find_shipping_rates( array( - 'country' => $country, - 'state' => $state, - 'postcode' => $postcode, - 'city' => $city, + 'country' => $args['country'], + 'state' => $args['state'], + 'postcode' => $args['postcode'], + 'city' => $args['city'], 'tax_class' => 'standard' === $shipping_tax_class ? '' : $shipping_tax_class, ) ); } - - $line_taxes = WC_Tax::calc_tax( $item['cost'], $tax_rates, false ); - $line_tax = max( 0, array_sum( $line_taxes ) ); - $shipping_tax_total += $line_tax; - - wc_update_order_item_meta( $item_id, '_line_tax', wc_format_decimal( $line_tax ) ); - wc_update_order_item_meta( $item_id, '_line_tax_data', array( 'total' => $line_taxes ) ); - - // Sum the item taxes - foreach ( array_keys( $shipping_taxes + $line_taxes ) as $key ) { - $shipping_taxes[ $key ] = ( isset( $line_taxes[ $key ] ) ? $line_taxes[ $key ] : 0 ) + ( isset( $shipping_taxes[ $key ] ) ? $shipping_taxes[ $key ] : 0 ); - } + $item->set_taxes( array( 'total' => WC_Tax::calc_tax( $item->get_total(), $tax_rates, false ) ) ); + $item->save(); } - - // Save tax totals - $this->set_total( $shipping_tax_total, 'shipping_tax' ); - $this->set_total( $tax_total, 'tax' ); - - // Tax rows - $this->remove_order_items( 'tax' ); - - // Now merge to keep tax rows - foreach ( array_keys( $taxes + $shipping_taxes ) as $tax_rate_id ) { - $this->add_tax( $tax_rate_id, isset( $taxes[ $tax_rate_id ] ) ? $taxes[ $tax_rate_id ] : 0, isset( $shipping_taxes[ $tax_rate_id ] ) ? $shipping_taxes[ $tax_rate_id ] : 0 ); - } - - return true; - } - - - /** - * Calculate shipping total. - * - * @since 2.2 - * @return float - */ - public function calculate_shipping() { - - $shipping_total = 0; - - foreach ( $this->get_shipping_methods() as $shipping ) { - $shipping_total += $shipping['cost']; - } - - $this->set_total( $shipping_total, 'shipping' ); - - return $this->get_total_shipping(); + $this->update_taxes(); } /** - * Update tax lines at order level by looking at the line item taxes themselves. - * - * @return bool success or fail. + * Update tax lines for the order based on the line item taxes themselves. */ public function update_taxes() { - $order_taxes = array(); - $order_shipping_taxes = array(); + $cart_taxes = array(); + $shipping_taxes = array(); foreach ( $this->get_items( array( 'line_item', 'fee' ) ) as $item_id => $item ) { - - $line_tax_data = maybe_unserialize( $item['line_tax_data'] ); - - if ( isset( $line_tax_data['total'] ) ) { - - foreach ( $line_tax_data['total'] as $tax_rate_id => $tax ) { - - if ( ! isset( $order_taxes[ $tax_rate_id ] ) ) { - $order_taxes[ $tax_rate_id ] = 0; - } - - $order_taxes[ $tax_rate_id ] += $tax; - } + $taxes = $item->get_taxes(); + foreach ( $taxes['total'] as $tax_rate_id => $tax ) { + $cart_taxes[ $tax_rate_id ] = isset( $cart_taxes[ $tax_rate_id ] ) ? $cart_taxes[ $tax_rate_id ] + $tax : $tax; } } - foreach ( $this->get_items( array( 'shipping' ) ) as $item_id => $item ) { - - $line_tax_data = maybe_unserialize( $item['taxes'] ); - - if ( isset( $line_tax_data ) ) { - foreach ( $line_tax_data as $tax_rate_id => $tax ) { - if ( ! isset( $order_shipping_taxes[ $tax_rate_id ] ) ) { - $order_shipping_taxes[ $tax_rate_id ] = 0; - } - - $order_shipping_taxes[ $tax_rate_id ] += $tax; - } + foreach ( $this->get_shipping_methods() as $item_id => $item ) { + $taxes = $item->get_taxes(); + foreach ( $taxes['total'] as $tax_rate_id => $tax ) { + $shipping_taxes[ $tax_rate_id ] = isset( $shipping_taxes[ $tax_rate_id ] ) ? $shipping_taxes[ $tax_rate_id ] + $tax : $tax; } } @@ -857,15 +1224,18 @@ abstract class WC_Abstract_Order { $this->remove_order_items( 'tax' ); // Now merge to keep tax rows. - foreach ( array_keys( $order_taxes + $order_shipping_taxes ) as $tax_rate_id ) { - $this->add_tax( $tax_rate_id, isset( $order_taxes[ $tax_rate_id ] ) ? $order_taxes[ $tax_rate_id ] : 0, isset( $order_shipping_taxes[ $tax_rate_id ] ) ? $order_shipping_taxes[ $tax_rate_id ] : 0 ); + foreach ( array_keys( $cart_taxes + $shipping_taxes ) as $tax_rate_id ) { + $this->add_tax( array( + 'rate_id' => $tax_rate_id, + 'tax_total' => isset( $cart_taxes[ $tax_rate_id ] ) ? $cart_taxes[ $tax_rate_id ] : 0, + 'shipping_tax_total' => isset( $shipping_taxes[ $tax_rate_id ] ) ? $shipping_taxes[ $tax_rate_id ] : 0, + ) ); } // Save tax totals - $this->set_total( WC_Tax::round( array_sum( $order_shipping_taxes ) ), 'shipping_tax' ); - $this->set_total( WC_Tax::round( array_sum( $order_taxes ) ), 'tax' ); - - return true; + $this->set_shipping_tax( WC_Tax::round( array_sum( $shipping_taxes ) ) ); + $this->set_cart_tax( WC_Tax::round( array_sum( $cart_taxes ) ) ); + $this->save(); } /** @@ -888,809 +1258,148 @@ abstract class WC_Abstract_Order { // line items foreach ( $this->get_items() as $item ) { - $cart_subtotal += wc_format_decimal( isset( $item['line_subtotal'] ) ? $item['line_subtotal'] : 0 ); - $cart_total += wc_format_decimal( isset( $item['line_total'] ) ? $item['line_total'] : 0 ); - $cart_subtotal_tax += wc_format_decimal( isset( $item['line_subtotal_tax'] ) ? $item['line_subtotal_tax'] : 0 ); - $cart_total_tax += wc_format_decimal( isset( $item['line_tax'] ) ? $item['line_tax'] : 0 ); + $cart_subtotal += wc_format_decimal( $item->get_subtotal() ); + $cart_total += wc_format_decimal( $item->get_total() ); + $cart_subtotal_tax += wc_format_decimal( $item->get_subtotal_tax() ); + $cart_total_tax += wc_format_decimal( $item->get_total_tax() ); } $this->calculate_shipping(); foreach ( $this->get_fees() as $item ) { - $fee_total += $item['line_total']; + $fee_total += $item->get_total(); } - $this->set_total( $cart_subtotal - $cart_total, 'cart_discount' ); - $this->set_total( $cart_subtotal_tax - $cart_total_tax, 'cart_discount_tax' ); + $grand_total = round( $cart_total + $fee_total + $this->get_shipping_total() + $this->get_cart_tax() + $this->get_shipping_tax(), wc_get_price_decimals() ); - $grand_total = round( $cart_total + $fee_total + $this->get_total_shipping() + $this->get_cart_tax() + $this->get_shipping_tax(), wc_get_price_decimals() ); - - $this->set_total( $grand_total, 'total' ); + $this->set_discount_total( $cart_subtotal - $cart_total ); + $this->set_discount_tax( $cart_subtotal_tax - $cart_total_tax ); + $this->set_total( $grand_total ); + $this->save(); return $grand_total; } - /** - * Gets an order from the database. - * - * @param int $id (default: 0). - * @return bool - */ - public function get_order( $id = 0 ) { - - if ( ! $id ) { - return false; - } - - if ( $result = get_post( $id ) ) { - $this->populate( $result ); - return true; - } - - return false; - } - - /** - * Populates an order from the loaded post data. - * - * @param mixed $result - */ - public function populate( $result ) { - - // Standard post data - $this->id = $result->ID; - $this->order_date = $result->post_date; - $this->modified_date = $result->post_modified; - $this->customer_message = $result->post_excerpt; - $this->customer_note = $result->post_excerpt; - $this->post_status = $result->post_status; - - // Billing email can default to user if set. - if ( empty( $this->billing_email ) && ! empty( $this->customer_user ) && ( $user = get_user_by( 'id', $this->customer_user ) ) ) { - $this->billing_email = $user->user_email; - } - - // Orders store the state of prices including tax when created. - $this->prices_include_tax = metadata_exists( 'post', $this->id, '_prices_include_tax' ) ? get_post_meta( $this->id, '_prices_include_tax', true ) === 'yes' : $this->prices_include_tax; - } - - /** - * __isset function. - * - * @param mixed $key - * @return bool - */ - public function __isset( $key ) { - - if ( ! $this->id ) { - return false; - } - - return metadata_exists( 'post', $this->id, '_' . $key ); - } - - /** - * __get function. - * - * @param mixed $key - * @return mixed - */ - public function __get( $key ) { - // Get values or default if not set. - if ( 'completed_date' === $key ) { - $value = ( $value = get_post_meta( $this->id, '_completed_date', true ) ) ? $value : $this->modified_date; - } elseif ( 'user_id' === $key ) { - $value = ( $value = get_post_meta( $this->id, '_customer_user', true ) ) ? absint( $value ) : ''; - } elseif ( 'status' === $key ) { - $value = $this->get_status(); - } else { - $value = get_post_meta( $this->id, '_' . $key, true ); - } - - return $value; - } - - /** - * Return the order statuses without wc- internal prefix. - * - * Queries get_post_status() directly to avoid having out of date statuses, if updated elsewhere. - * - * @return string - */ - public function get_status() { - $this->post_status = get_post_status( $this->id ); - return apply_filters( 'woocommerce_order_get_status', 'wc-' === substr( $this->post_status, 0, 3 ) ? substr( $this->post_status, 3 ) : $this->post_status, $this ); - } - - /** - * Checks the order status against a passed in status. - * - * @return bool - */ - public function has_status( $status ) { - return apply_filters( 'woocommerce_order_has_status', ( is_array( $status ) && in_array( $this->get_status(), $status ) ) || $this->get_status() === $status ? true : false, $this, $status ); - } - - /** - * Gets the user ID associated with the order. Guests are 0. - * - * @since 2.2 - * @return int - */ - public function get_user_id() { - return $this->customer_user ? intval( $this->customer_user ) : 0; - } - - /** - * Get the user associated with the order. False for guests. - * - * @since 2.2 - * @return WP_User|false - */ - public function get_user() { - return $this->get_user_id() ? get_user_by( 'id', $this->get_user_id() ) : false; - } - - /** - * Get transaction id for the order. - * - * @return string - */ - public function get_transaction_id() { - return get_post_meta( $this->id, '_transaction_id', true ); - } - - /** - * Check if an order key is valid. - * - * @param mixed $key - * @return bool - */ - public function key_is_valid( $key ) { - - if ( $key == $this->order_key ) { - return true; - } - - return false; - } - - /** - * get_order_number function. - * - * Gets the order number for display (by default, order ID). - * - * @return string - */ - public function get_order_number() { - return apply_filters( 'woocommerce_order_number', $this->id, $this ); - } - - /** - * Get a formatted billing address for the order. - * - * @return string - */ - public function get_formatted_billing_address() { - if ( ! $this->formatted_billing_address ) { - - // Formatted Addresses. - $address = apply_filters( 'woocommerce_order_formatted_billing_address', array( - 'first_name' => $this->billing_first_name, - 'last_name' => $this->billing_last_name, - 'company' => $this->billing_company, - 'address_1' => $this->billing_address_1, - 'address_2' => $this->billing_address_2, - 'city' => $this->billing_city, - 'state' => $this->billing_state, - 'postcode' => $this->billing_postcode, - 'country' => $this->billing_country - ), $this ); - - $this->formatted_billing_address = WC()->countries->get_formatted_address( $address ); - } - - return $this->formatted_billing_address; - } - - /** - * Get a formatted shipping address for the order. - * - * @return string - */ - public function get_formatted_shipping_address() { - if ( ! $this->formatted_shipping_address ) { - - if ( $this->shipping_address_1 || $this->shipping_address_2 ) { - - // Formatted Addresses - $address = apply_filters( 'woocommerce_order_formatted_shipping_address', array( - 'first_name' => $this->shipping_first_name, - 'last_name' => $this->shipping_last_name, - 'company' => $this->shipping_company, - 'address_1' => $this->shipping_address_1, - 'address_2' => $this->shipping_address_2, - 'city' => $this->shipping_city, - 'state' => $this->shipping_state, - 'postcode' => $this->shipping_postcode, - 'country' => $this->shipping_country - ), $this ); - - $this->formatted_shipping_address = WC()->countries->get_formatted_address( $address ); - } - } - - return $this->formatted_shipping_address; - } - - /** - * Get a formatted shipping address for the order. - * - * @return string - */ - public function get_shipping_address_map_url() { - $address = apply_filters( 'woocommerce_shipping_address_map_url_parts', array( - 'address_1' => $this->shipping_address_1, - 'address_2' => $this->shipping_address_2, - 'city' => $this->shipping_city, - 'state' => $this->shipping_state, - 'postcode' => $this->shipping_postcode, - 'country' => $this->shipping_country - ), $this ); - - return apply_filters( 'woocommerce_shipping_address_map_url', 'https://maps.google.com/maps?&q=' . urlencode( implode( ', ', $address ) ) . '&z=16', $this ); - } - - /** - * Get the billing address in an array. - * @deprecated 2.3 - * @return string - */ - public function get_billing_address() { - _deprecated_function( 'get_billing_address', '2.3', 'get_formatted_billing_address' ); - return $this->get_formatted_billing_address(); - } - - /** - * Get the shipping address in an array. - * @deprecated 2.3 - * @return string - */ - public function get_shipping_address() { - _deprecated_function( 'get_shipping_address', '2.3', 'get_formatted_shipping_address' ); - return $this->get_formatted_shipping_address(); - } - - /** - * Get a formatted billing full name. - * - * @since 2.4.0 - * - * @return string - */ - public function get_formatted_billing_full_name() { - return sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $this->billing_first_name, $this->billing_last_name ); - } - - /** - * Get a formatted shipping full name. - * - * @since 2.4.0 - * - * @return string - */ - public function get_formatted_shipping_full_name() { - return sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $this->shipping_first_name, $this->shipping_last_name ); - } - - /** - * Return an array of items/products within this order. - * - * @param string|array $type Types of line items to get (array or string). - * @return array - */ - public function get_items( $type = '' ) { - global $wpdb; - - if ( empty( $type ) ) { - $type = array( 'line_item' ); - } - - if ( ! is_array( $type ) ) { - $type = array( $type ); - } - - $items = array(); - $get_items_sql = $wpdb->prepare( "SELECT order_item_id, order_item_name, order_item_type FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d ", $this->id ); - $get_items_sql .= "AND order_item_type IN ( '" . implode( "','", array_map( 'esc_sql', $type ) ) . "' ) ORDER BY order_item_id;"; - $line_items = $wpdb->get_results( $get_items_sql ); - - // Loop items - foreach ( $line_items as $item ) { - $items[ $item->order_item_id ]['name'] = $item->order_item_name; - $items[ $item->order_item_id ]['type'] = $item->order_item_type; - $items[ $item->order_item_id ]['item_meta'] = $this->get_item_meta( $item->order_item_id ); - $items[ $item->order_item_id ]['item_meta_array'] = $this->get_item_meta_array( $item->order_item_id ); - $items[ $item->order_item_id ] = $this->expand_item_meta( $items[ $item->order_item_id ] ); - } - - return apply_filters( 'woocommerce_order_get_items', $items, $this ); - } - - /** - * Expand item meta into the $item array. - * @since 2.4.0 - * @param array $item before expansion. - * @return array - */ - public function expand_item_meta( $item ) { - // Reserved meta keys - $reserved_item_meta_keys = array( - 'name', - 'type', - 'item_meta', - 'item_meta_array', - 'qty', - 'tax_class', - 'product_id', - 'variation_id', - 'line_subtotal', - 'line_total', - 'line_tax', - 'line_subtotal_tax' - ); - - // Expand item meta if set. - if ( ! empty( $item['item_meta'] ) ) { - foreach ( $item['item_meta'] as $name => $value ) { - if ( in_array( $name, $reserved_item_meta_keys ) ) { - continue; - } - if ( '_' === substr( $name, 0, 1 ) ) { - $item[ substr( $name, 1 ) ] = $value[0]; - } elseif ( ! in_array( $name, $reserved_item_meta_keys ) ) { - $item[ $name ] = make_clickable( $value[0] ); - } - } - } - return $item; - } - - /** - * Gets the count of order items of a certain type. - * - * @param string $item_type - * @return string - */ - public function get_item_count( $item_type = '' ) { - if ( empty( $item_type ) ) { - $item_type = array( 'line_item' ); - } - if ( ! is_array( $item_type ) ) { - $item_type = array( $item_type ); - } - - $items = $this->get_items( $item_type ); - $count = 0; - - foreach ( $items as $item ) { - $count += empty( $item['qty'] ) ? 1 : $item['qty']; - } - - return apply_filters( 'woocommerce_get_item_count', $count, $item_type, $this ); - } - - /** - * Get refunds - * @return array - */ - public function get_refunds() { return array(); } - - /** - * Return an array of fees within this order. - * - * @return array - */ - public function get_fees() { - return $this->get_items( 'fee' ); - } - - /** - * Return an array of taxes within this order. - * - * @return array - */ - public function get_taxes() { - return $this->get_items( 'tax' ); - } - - /** - * Return an array of shipping costs within this order. - * - * @return array - */ - public function get_shipping_methods() { - return $this->get_items( 'shipping' ); - } - - /** - * Check whether this order has a specific shipping method or not. - * - * @param string $method_id - * - * @return bool - */ - public function has_shipping_method( $method_id ) { - - $shipping_methods = $this->get_shipping_methods(); - $has_method = false; - - if ( empty( $shipping_methods ) ) { - return false; - } - - foreach ( $shipping_methods as $shipping_method ) { - if ( $shipping_method['method_id'] == $method_id ) { - $has_method = true; - } - } - - return $has_method; - } - - /** - * Get taxes, merged by code, formatted ready for output. - * - * @return array - */ - public function get_tax_totals() { - - $taxes = $this->get_items( 'tax' ); - $tax_totals = array(); - - foreach ( $taxes as $key => $tax ) { - - $code = $tax[ 'name' ]; - - if ( ! isset( $tax_totals[ $code ] ) ) { - $tax_totals[ $code ] = new stdClass(); - $tax_totals[ $code ]->amount = 0; - } - - $tax_totals[ $code ]->id = $key; - $tax_totals[ $code ]->rate_id = $tax['rate_id']; - $tax_totals[ $code ]->is_compound = $tax[ 'compound' ]; - $tax_totals[ $code ]->label = isset( $tax[ 'label' ] ) ? $tax[ 'label' ] : $tax[ 'name' ]; - $tax_totals[ $code ]->amount += $tax[ 'tax_amount' ] + $tax[ 'shipping_tax_amount' ]; - $tax_totals[ $code ]->formatted_amount = wc_price( wc_round_tax_total( $tax_totals[ $code ]->amount ), array('currency' => $this->get_order_currency()) ); - } - - if ( apply_filters( 'woocommerce_order_hide_zero_taxes', true ) ) { - $amounts = array_filter( wp_list_pluck( $tax_totals, 'amount' ) ); - $tax_totals = array_intersect_key( $tax_totals, $amounts ); - } - - return apply_filters( 'woocommerce_order_tax_totals', $tax_totals, $this ); - } - - /** - * has_meta function for order items. - * - * @param string $order_item_id - * @return array of meta data. - */ - public function has_meta( $order_item_id ) { - global $wpdb; - - return $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value, meta_id, order_item_id - FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id = %d - ORDER BY meta_id", absint( $order_item_id ) ), ARRAY_A ); - } - - /** - * Get all item meta data in array format in the order it was saved. Does not group meta by key like get_item_meta(). - * - * @param mixed $order_item_id - * @return array of objects - */ - public function get_item_meta_array( $order_item_id ) { - global $wpdb; - - // Get cache key - uses get_cache_prefix to invalidate when needed - $cache_key = WC_Cache_Helper::get_cache_prefix( 'orders' ) . 'item_meta_array_' . $order_item_id; - $item_meta_array = wp_cache_get( $cache_key, 'orders' ); - - if ( false === $item_meta_array ) { - $item_meta_array = array(); - $metadata = $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value, meta_id FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id = %d ORDER BY meta_id", absint( $order_item_id ) ) ); - foreach ( $metadata as $metadata_row ) { - $item_meta_array[ $metadata_row->meta_id ] = (object) array( 'key' => $metadata_row->meta_key, 'value' => $metadata_row->meta_value ); - } - wp_cache_set( $cache_key, $item_meta_array, 'orders' ); - } - - return $item_meta_array ; - } - - /** - * Display meta data belonging to an item. - * @param array $item - */ - public function display_item_meta( $item ) { - $product = $this->get_product_from_item( $item ); - $item_meta = new WC_Order_Item_Meta( $item, $product ); - $item_meta->display(); - } - - /** - * Get order item meta. - * - * @param mixed $order_item_id - * @param string $key (default: '') - * @param bool $single (default: false) - * @return array|string - */ - public function get_item_meta( $order_item_id, $key = '', $single = false ) { - return get_metadata( 'order_item', $order_item_id, $key, $single ); - } - - /** Total Getters *******************************************************/ - - /** - * Gets the total discount amount. - * @param bool $ex_tax Show discount excl any tax. - * @return float - */ - public function get_total_discount( $ex_tax = true ) { - if ( ! $this->order_version || version_compare( $this->order_version, '2.3.7', '<' ) ) { - // Backwards compatible total calculation - totals were not stored consistently in old versions. - if ( $ex_tax ) { - if ( $this->prices_include_tax ) { - $total_discount = (double) $this->cart_discount - (double) $this->cart_discount_tax; - } else { - $total_discount = (double) $this->cart_discount; - } - } else { - if ( $this->prices_include_tax ) { - $total_discount = (double) $this->cart_discount; - } else { - $total_discount = (double) $this->cart_discount + (double) $this->cart_discount_tax; - } - } - // New logic - totals are always stored exclusive of tax, tax total is stored in cart_discount_tax - } else { - if ( $ex_tax ) { - $total_discount = (double) $this->cart_discount; - } else { - $total_discount = (double) $this->cart_discount + (double) $this->cart_discount_tax; - } - } - return apply_filters( 'woocommerce_order_amount_total_discount', round( $total_discount, WC_ROUNDING_PRECISION ), $this ); - } - - /** - * Gets the discount amount. - * @deprecated in favour of get_total_discount() since we now only have one discount type. - * @return float - */ - public function get_cart_discount() { - _deprecated_function( 'get_cart_discount', '2.3', 'get_total_discount' ); - return apply_filters( 'woocommerce_order_amount_cart_discount', $this->get_total_discount(), $this ); - } - - /** - * Get cart discount (formatted). - * - * @deprecated order (after tax) discounts removed in 2.3.0. - * @return string - */ - public function get_order_discount_to_display() { - _deprecated_function( 'get_order_discount_to_display', '2.3' ); - } - - /** - * Gets the total (order) discount amount - these are applied after tax. - * - * @deprecated order (after tax) discounts removed in 2.3.0. - * @return float - */ - public function get_order_discount() { - _deprecated_function( 'get_order_discount', '2.3' ); - return apply_filters( 'woocommerce_order_amount_order_discount', (double) $this->order_discount, $this ); - } - - /** - * Gets cart tax amount. - * - * @return float - */ - public function get_cart_tax() { - return apply_filters( 'woocommerce_order_amount_cart_tax', (double) $this->order_tax, $this ); - } - - /** - * Gets shipping tax amount. - * - * @return float - */ - public function get_shipping_tax() { - return apply_filters( 'woocommerce_order_amount_shipping_tax', (double) $this->order_shipping_tax, $this ); - } - - /** - * Gets shipping and product tax. - * - * @return float - */ - public function get_total_tax() { - return apply_filters( 'woocommerce_order_amount_total_tax', wc_round_tax_total( $this->get_cart_tax() + $this->get_shipping_tax() ), $this ); - } - - /** - * Gets shipping total. - * - * @return float - */ - public function get_total_shipping() { - return apply_filters( 'woocommerce_order_amount_total_shipping', (double) $this->order_shipping, $this ); - } - - /** - * Gets order total. - * - * @return float - */ - public function get_total() { - return apply_filters( 'woocommerce_order_amount_total', (double) $this->order_total, $this ); - } - - /** - * Gets order subtotal. - * - * @return mixed|void - */ - public function get_subtotal() { - $subtotal = 0; - - foreach ( $this->get_items() as $item ) { - $subtotal += ( isset( $item['line_subtotal'] ) ) ? $item['line_subtotal'] : 0; - } - - return apply_filters( 'woocommerce_order_amount_subtotal', (double) $subtotal, $this ); - } - /** * Get item subtotal - this is the cost before discount. * - * @param mixed $item + * @param object $item * @param bool $inc_tax (default: false). * @param bool $round (default: true). * @return float */ public function get_item_subtotal( $item, $inc_tax = false, $round = true ) { - if ( $inc_tax ) { - $price = ( $item['line_subtotal'] + $item['line_subtotal_tax'] ) / max( 1, $item['qty'] ); - } else { - $price = ( $item['line_subtotal'] / max( 1, $item['qty'] ) ); + $subtotal = 0; + + if ( is_callable( array( $item, 'get_subtotal' ) ) ) { + if ( $inc_tax ) { + $subtotal = ( $item->get_subtotal() + $item->get_subtotal_tax() ) / max( 1, $item->get_qty() ); + } else { + $subtotal = ( $item->get_subtotal() / max( 1, $item->get_qty() ) ); + } + + $subtotal = $round ? number_format( (float) $subtotal, wc_get_price_decimals(), '.', '' ) : $subtotal; } - $price = $round ? number_format( (float) $price, wc_get_price_decimals(), '.', '' ) : $price; - - return apply_filters( 'woocommerce_order_amount_item_subtotal', $price, $this, $item, $inc_tax, $round ); + return apply_filters( 'woocommerce_order_amount_item_subtotal', $subtotal, $this, $item, $inc_tax, $round ); } /** * Get line subtotal - this is the cost before discount. * - * @param mixed $item + * @param object $item * @param bool $inc_tax (default: false). * @param bool $round (default: true). * @return float */ public function get_line_subtotal( $item, $inc_tax = false, $round = true ) { - if ( $inc_tax ) { - $price = $item['line_subtotal'] + $item['line_subtotal_tax']; - } else { - $price = $item['line_subtotal']; + $subtotal = 0; + + if ( is_callable( array( $item, 'get_subtotal' ) ) ) { + if ( $inc_tax ) { + $subtotal = $item->get_subtotal() + $item->get_subtotal_tax(); + } else { + $subtotal = $item->get_subtotal(); + } + + $subtotal = $round ? round( $subtotal, wc_get_price_decimals() ) : $subtotal; } - $price = $round ? round( $price, wc_get_price_decimals() ) : $price; - - return apply_filters( 'woocommerce_order_amount_line_subtotal', $price, $this, $item, $inc_tax, $round ); + return apply_filters( 'woocommerce_order_amount_line_subtotal', $subtotal, $this, $item, $inc_tax, $round ); } /** * Calculate item cost - useful for gateways. * - * @param mixed $item + * @param object $item * @param bool $inc_tax (default: false). * @param bool $round (default: true). * @return float */ public function get_item_total( $item, $inc_tax = false, $round = true ) { + $total = 0; - $qty = ( ! empty( $item['qty'] ) ) ? $item['qty'] : 1; + if ( is_callable( array( $item, 'get_total' ) ) ) { + if ( $inc_tax ) { + $total = ( $item->get_total() + $item->get_total_tax() ) / max( 1, $item->get_qty() ); + } else { + $total = $item->get_total() / max( 1, $item->get_qty() ); + } - if ( $inc_tax ) { - $price = ( $item['line_total'] + $item['line_tax'] ) / max( 1, $qty ); - } else { - $price = $item['line_total'] / max( 1, $qty ); + $total = $round ? round( $total, wc_get_price_decimals() ) : $total; } - $price = $round ? round( $price, wc_get_price_decimals() ) : $price; - - return apply_filters( 'woocommerce_order_amount_item_total', $price, $this, $item, $inc_tax, $round ); + return apply_filters( 'woocommerce_order_amount_item_total', $total, $this, $item, $inc_tax, $round ); } /** * Calculate line total - useful for gateways. * - * @param mixed $item + * @param object $item * @param bool $inc_tax (default: false). * @param bool $round (default: true). * @return float */ public function get_line_total( $item, $inc_tax = false, $round = true ) { + $total = 0; - // Check if we need to add line tax to the line total. - $line_total = $inc_tax ? $item['line_total'] + $item['line_tax'] : $item['line_total']; + if ( is_callable( array( $item, 'get_total' ) ) ) { + // Check if we need to add line tax to the line total. + $total = $inc_tax ? $item->get_total() + $item->get_total_tax() : $item->get_total(); - // Check if we need to round. - $line_total = $round ? round( $line_total, wc_get_price_decimals() ) : $line_total; + // Check if we need to round. + $total = $round ? round( $total, wc_get_price_decimals() ) : $total; + } - return apply_filters( 'woocommerce_order_amount_line_total', $line_total, $this, $item, $inc_tax, $round ); + return apply_filters( 'woocommerce_order_amount_line_total', $total, $this, $item, $inc_tax, $round ); } /** - * Calculate item tax - useful for gateways. + * Get item tax - useful for gateways. * * @param mixed $item * @param bool $round (default: true). * @return float */ public function get_item_tax( $item, $round = true ) { + $tax = 0; - $price = $item['line_tax'] / max( 1, $item['qty'] ); - $price = $round ? wc_round_tax_total( $price ) : $price; + if ( is_callable( array( $item, 'get_total_tax' ) ) ) { + $tax = $item->get_total_tax() / max( 1, $item->get_qty() ); + $tax = $round ? wc_round_tax_total( $tax ) : $tax; + } - return apply_filters( 'woocommerce_order_amount_item_tax', $price, $item, $round, $this ); + return apply_filters( 'woocommerce_order_amount_item_tax', $tax, $item, $round, $this ); } /** - * Calculate line tax - useful for gateways. + * Get line tax - useful for gateways. * * @param mixed $item * @return float */ public function get_line_tax( $item ) { - return apply_filters( 'woocommerce_order_amount_line_tax', wc_round_tax_total( $item['line_tax'] ), $item, $this ); - } - - /** End Total Getters *******************************************************/ - - /** - * Gets formatted shipping method title. - * - * @return string - */ - public function get_shipping_method() { - - $labels = array(); - - // Backwards compat < 2.1 - get shipping title stored in meta. - if ( $this->shipping_method_title ) { - $labels[] = $this->shipping_method_title; - } else { - - // 2.1+ get line items for shipping. - $shipping_methods = $this->get_shipping_methods(); - - foreach ( $shipping_methods as $shipping ) { - $labels[] = $shipping['name'] ? $shipping['name'] : __( 'Shipping', 'woocommerce' ); - } - } - - return apply_filters( 'woocommerce_order_shipping_method', implode( ', ', $labels ), $this ); + return apply_filters( 'woocommerce_order_amount_line_tax', is_callable( array( $item, 'get_total_tax' ) ) ? wc_round_tax_total( $item->get_total_tax() ) : 0, $item, $this ); } /** @@ -1701,42 +1410,25 @@ abstract class WC_Abstract_Order { * @return string */ public function get_formatted_line_subtotal( $item, $tax_display = '' ) { - - if ( ! $tax_display ) { - $tax_display = $this->tax_display_cart; - } - - if ( ! isset( $item['line_subtotal'] ) || ! isset( $item['line_subtotal_tax'] ) ) { - return ''; - } + $tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' ); if ( 'excl' == $tax_display ) { - $ex_tax_label = $this->prices_include_tax ? 1 : 0; + $ex_tax_label = $this->get_prices_include_tax() ? 1 : 0; - $subtotal = wc_price( $this->get_line_subtotal( $item ), array( 'ex_tax_label' => $ex_tax_label, 'currency' => $this->get_order_currency() ) ); + $subtotal = wc_price( $this->get_line_subtotal( $item ), array( 'ex_tax_label' => $ex_tax_label, 'currency' => $this->get_currency() ) ); } else { - $subtotal = wc_price( $this->get_line_subtotal( $item, true ), array('currency' => $this->get_order_currency()) ); + $subtotal = wc_price( $this->get_line_subtotal( $item, true ), array('currency' => $this->get_currency()) ); } return apply_filters( 'woocommerce_order_formatted_line_subtotal', $subtotal, $item, $this ); } - /** - * Gets order currency. - * - * @return string - */ - public function get_order_currency() { - return apply_filters( 'woocommerce_get_order_currency', $this->order_currency, $this ); - } - /** * Gets order total - formatted for display. - * * @return string */ public function get_formatted_order_total() { - $formatted_total = wc_price( $this->get_total(), array( 'currency' => $this->get_order_currency() ) ); + $formatted_total = wc_price( $this->get_total(), array( 'currency' => $this->get_currency() ) ); return apply_filters( 'woocommerce_get_formatted_order_total', $formatted_total, $this ); } @@ -1748,96 +1440,77 @@ abstract class WC_Abstract_Order { * @return string */ public function get_subtotal_to_display( $compound = false, $tax_display = '' ) { - - if ( ! $tax_display ) { - $tax_display = $this->tax_display_cart; - } - - $subtotal = 0; + $tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' ); + $subtotal = 0; if ( ! $compound ) { foreach ( $this->get_items() as $item ) { + $subtotal += $item->get_subtotal(); - if ( ! isset( $item['line_subtotal'] ) || ! isset( $item['line_subtotal_tax'] ) ) { - return ''; - } - - $subtotal += $item['line_subtotal']; - - if ( 'incl' == $tax_display ) { - $subtotal += $item['line_subtotal_tax']; + if ( 'incl' === $tax_display ) { + $subtotal += $item->get_subtotal_tax(); } } - $subtotal = wc_price( $subtotal, array('currency' => $this->get_order_currency()) ); + $subtotal = wc_price( $subtotal, array( 'currency' => $this->get_currency() ) ); - if ( $tax_display == 'excl' && $this->prices_include_tax ) { + if ( 'excl' === $tax_display && $this->get_prices_include_tax() ) { $subtotal .= ' ' . WC()->countries->ex_tax_or_vat() . ''; } } else { - - if ( 'incl' == $tax_display ) { + if ( 'incl' === $tax_display ) { return ''; } foreach ( $this->get_items() as $item ) { - - $subtotal += $item['line_subtotal']; - + $subtotal += $item->get_subtotal(); } // Add Shipping Costs. - $subtotal += $this->get_total_shipping(); + $subtotal += $this->get_shipping_total(); // Remove non-compound taxes. foreach ( $this->get_taxes() as $tax ) { - - if ( ! empty( $tax['compound'] ) ) { + if ( $this->is_compound() ) { continue; } - - $subtotal = $subtotal + $tax['tax_amount'] + $tax['shipping_tax_amount']; - + $subtotal = $subtotal + $tax->get_tax_total() + $tax->get_shipping_tax_total(); } // Remove discounts. $subtotal = $subtotal - $this->get_total_discount(); - - $subtotal = wc_price( $subtotal, array('currency' => $this->get_order_currency()) ); + $subtotal = wc_price( $subtotal, array( 'currency' => $this->get_currency() ) ); } return apply_filters( 'woocommerce_order_subtotal_to_display', $subtotal, $compound, $this ); } - /** * Gets shipping (formatted). * * @return string */ public function get_shipping_to_display( $tax_display = '' ) { - if ( ! $tax_display ) { - $tax_display = $this->tax_display_cart; - } + $tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' ); - if ( $this->order_shipping != 0 ) { + if ( $this->get_shipping_total() != 0 ) { if ( $tax_display == 'excl' ) { // Show shipping excluding tax. - $shipping = wc_price( $this->order_shipping, array('currency' => $this->get_order_currency()) ); + $shipping = wc_price( $this->get_shipping_total(), array('currency' => $this->get_currency()) ); - if ( $this->order_shipping_tax != 0 && $this->prices_include_tax ) { + if ( $this->get_shipping_tax() != 0 && $this->get_prices_include_tax() ) { $shipping .= apply_filters( 'woocommerce_order_shipping_to_display_tax_label', ' ' . WC()->countries->ex_tax_or_vat() . '', $this, $tax_display ); } } else { // Show shipping including tax. - $shipping = wc_price( $this->order_shipping + $this->order_shipping_tax, array('currency' => $this->get_order_currency()) ); + $shipping = wc_price( $this->get_shipping_total() + $this->get_shipping_tax(), array('currency' => $this->get_currency()) ); - if ( $this->order_shipping_tax != 0 && ! $this->prices_include_tax ) { + if ( $this->get_shipping_tax() != 0 && ! $this->get_prices_include_tax() ) { $shipping .= apply_filters( 'woocommerce_order_shipping_to_display_tax_label', ' ' . WC()->countries->inc_tax_or_vat() . '', $this, $tax_display ); } @@ -1860,42 +1533,10 @@ abstract class WC_Abstract_Order { * @return string */ public function get_discount_to_display( $tax_display = '' ) { - if ( ! $tax_display ) { - $tax_display = $this->tax_display_cart; - } - return apply_filters( 'woocommerce_order_discount_to_display', wc_price( $this->get_total_discount( $tax_display === 'excl' && $this->display_totals_ex_tax ), array( 'currency' => $this->get_order_currency() ) ), $this ); + $tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' ); + return apply_filters( 'woocommerce_order_discount_to_display', wc_price( $this->get_total_discount( 'excl' === $tax_display && 'excl' === get_option( 'woocommerce_tax_display_cart' ) ), array( 'currency' => $this->get_currency() ) ), $this ); } - /** - * Get cart discount (formatted). - * @deprecated - * @return string - */ - public function get_cart_discount_to_display( $tax_display = '' ) { - _deprecated_function( 'get_cart_discount_to_display', '2.3', 'get_discount_to_display' ); - return apply_filters( 'woocommerce_order_cart_discount_to_display', $this->get_discount_to_display( $tax_display ), $this ); - } - - /** - * Get a product (either product or variation). - * - * @param mixed $item - * @return WC_Product - */ - public function get_product_from_item( $item ) { - - if ( ! empty( $item['variation_id'] ) && 'product_variation' === get_post_type( $item['variation_id'] ) ) { - $_product = wc_get_product( $item['variation_id'] ); - } elseif ( ! empty( $item['product_id'] ) ) { - $_product = wc_get_product( $item['product_id'] ); - } else { - $_product = false; - } - - return apply_filters( 'woocommerce_get_product_from_item', $_product, $item, $this ); - } - - /** * Get totals for display on pages and in emails. * @@ -1903,55 +1544,39 @@ abstract class WC_Abstract_Order { * @return array */ public function get_order_item_totals( $tax_display = '' ) { - - if ( ! $tax_display ) { - $tax_display = $this->tax_display_cart; - } - - $total_rows = array(); + $tax_display = $tax_display ? $tax_display : get_option( 'woocommerce_tax_display_cart' ); + $total_rows = array(); if ( $subtotal = $this->get_subtotal_to_display( false, $tax_display ) ) { $total_rows['cart_subtotal'] = array( 'label' => __( 'Subtotal:', 'woocommerce' ), - 'value' => $subtotal + 'value' => $subtotal, ); } if ( $this->get_total_discount() > 0 ) { $total_rows['discount'] = array( 'label' => __( 'Discount:', 'woocommerce' ), - 'value' => '-' . $this->get_discount_to_display( $tax_display ) + 'value' => '-' . $this->get_discount_to_display( $tax_display ), ); } if ( $this->get_shipping_method() ) { $total_rows['shipping'] = array( 'label' => __( 'Shipping:', 'woocommerce' ), - 'value' => $this->get_shipping_to_display( $tax_display ) + 'value' => $this->get_shipping_to_display( $tax_display ), ); } if ( $fees = $this->get_fees() ) { foreach ( $fees as $id => $fee ) { - - if ( apply_filters( 'woocommerce_get_order_item_totals_excl_free_fees', $fee['line_total'] + $fee['line_tax'] == 0, $id ) ) { + if ( apply_filters( 'woocommerce_get_order_item_totals_excl_free_fees', empty( $fee['line_total'] ) && empty( $fee['line_tax'] ), $id ) ) { continue; } - - if ( 'excl' == $tax_display ) { - - $total_rows[ 'fee_' . $id ] = array( - 'label' => ( $fee['name'] ? $fee['name'] : __( 'Fee', 'woocommerce' ) ) . ':', - 'value' => wc_price( $fee['line_total'], array('currency' => $this->get_order_currency()) ) - ); - - } else { - - $total_rows[ 'fee_' . $id ] = array( - 'label' => $fee['name'] . ':', - 'value' => wc_price( $fee['line_total'] + $fee['line_tax'], array('currency' => $this->get_order_currency()) ) - ); - } + $total_rows[ 'fee_' . $fee->get_order_item_id() ] = array( + 'label' => $fee->get_name() . ':', + 'value' => wc_price( 'excl' === $tax_display ? $fee->get_total() : $fee->get_total() + $fee->get_total_tax(), array('currency' => $this->get_currency()) ) + ); } } @@ -1964,7 +1589,7 @@ abstract class WC_Abstract_Order { $total_rows[ sanitize_title( $code ) ] = array( 'label' => $tax->label . ':', - 'value' => $tax->formatted_amount + 'value' => $tax->formatted_amount, ); } @@ -1972,15 +1597,15 @@ abstract class WC_Abstract_Order { $total_rows['tax'] = array( 'label' => WC()->countries->tax_or_vat() . ':', - 'value' => wc_price( $this->get_total_tax(), array( 'currency' => $this->get_order_currency() ) ) + 'value' => wc_price( $this->get_total_tax(), array( 'currency' => $this->get_currency() ) ), ); } } - if ( $this->get_total() > 0 && $this->payment_method_title ) { + if ( $this->get_total() > 0 && $this->get_payment_method_title() ) { $total_rows['payment_method'] = array( 'label' => __( 'Payment Method:', 'woocommerce' ), - 'value' => $this->payment_method_title + 'value' => $this->get_payment_method_title(), ); } @@ -1988,97 +1613,62 @@ abstract class WC_Abstract_Order { foreach ( $refunds as $id => $refund ) { $total_rows[ 'refund_' . $id ] = array( 'label' => $refund->get_refund_reason() ? $refund->get_refund_reason() : __( 'Refund', 'woocommerce' ) . ':', - 'value' => wc_price( '-' . $refund->get_refund_amount(), array( 'currency' => $this->get_order_currency() ) ) + 'value' => wc_price( '-' . $refund->get_refund_amount(), array( 'currency' => $this->get_currency() ) ), ); } } $total_rows['order_total'] = array( 'label' => __( 'Total:', 'woocommerce' ), - 'value' => $this->get_formatted_order_total( $tax_display ) + 'value' => $this->get_formatted_order_total( $tax_display ), ); return apply_filters( 'woocommerce_get_order_item_totals', $total_rows, $this ); } + /* + |-------------------------------------------------------------------------- + | Conditionals + |-------------------------------------------------------------------------- + | + | Checks if a condition is true or false. + | + */ /** - * Output items for display in html emails. - * - * @param array $args Items args. - * @param null $deprecated1 Deprecated arg. - * @param null $deprecated2 Deprecated arg. - * @param null $deprecated3 Deprecated arg. - * @param null $deprecated4 Deprecated arg. - * @param null $deprecated5 Deprecated arg. - * @return string - */ - public function email_order_items_table( $args = array(), $deprecated1 = null, $deprecated2 = null, $deprecated3 = null, $deprecated4 = null, $deprecated5 = null ) { - ob_start(); - - if ( ! is_null( $deprecated1 ) || ! is_null( $deprecated2 ) || ! is_null( $deprecated3 ) || ! is_null( $deprecated4 ) || ! is_null( $deprecated5 ) ) { - _deprecated_argument( __FUNCTION__, '2.5.0' ); - } - - $defaults = array( - 'show_sku' => false, - 'show_image' => false, - 'image_size' => array( 32, 32 ), - 'plain_text' => false, - 'sent_to_admin' => false - ); - - $args = wp_parse_args( $args, $defaults ); - $template = $args['plain_text'] ? 'emails/plain/email-order-items.php' : 'emails/email-order-items.php'; - - wc_get_template( $template, apply_filters( 'woocommerce_email_order_items_args', array( - 'order' => $this, - 'items' => $this->get_items(), - 'show_download_links' => $this->is_download_permitted() && ! $args['sent_to_admin'], - 'show_sku' => $args['show_sku'], - 'show_purchase_note' => $this->is_paid() && ! $args['sent_to_admin'], - 'show_image' => $args['show_image'], - 'image_size' => $args['image_size'], - 'plain_text' => $args['plain_text'], - 'sent_to_admin' => $args['sent_to_admin'] - ) ) ); - - return apply_filters( 'woocommerce_email_order_items_table', ob_get_clean(), $this ); - } - - /** - * Returns if an order has been paid for based on the order status. - * @since 2.5.0 - * @return bool - */ - public function is_paid() { - return apply_filters( 'woocommerce_order_is_paid', $this->has_status( apply_filters( 'woocommerce_order_is_paid_statuses', array( 'processing', 'completed' ) ) ), $this ); - } - - /** - * Checks if product download is permitted. + * Checks the order status against a passed in status. * * @return bool */ - public function is_download_permitted() { - return apply_filters( 'woocommerce_order_is_download_permitted', $this->has_status( 'completed' ) || ( get_option( 'woocommerce_downloads_grant_access_after_payment' ) == 'yes' && $this->has_status( 'processing' ) ), $this ); + public function has_status( $status ) { + return apply_filters( 'woocommerce_order_has_status', ( is_array( $status ) && in_array( $this->get_status(), $status ) ) || $this->get_status() === $status ? true : false, $this, $status ); } /** - * Returns true if the order contains a downloadable product. + * Check whether this order has a specific shipping method or not. + * + * @param string $method_id * @return bool */ - public function has_downloadable_item() { - foreach ( $this->get_items() as $item ) { - $_product = $this->get_product_from_item( $item ); - - if ( $_product && $_product->exists() && $_product->is_downloadable() && $_product->has_file() ) { + public function has_shipping_method( $method_id ) { + foreach ( $this->get_shipping_methods() as $shipping_method ) { + if ( $shipping_method->get_method_id() === $method_id ) { return true; } } return false; } + /** + * Check if an order key is valid. + * + * @param mixed $key + * @return bool + */ + public function key_is_valid( $key ) { + return $key === $this->get_order_key(); + } + /** * Returns true if the order contains a free product. * @since 2.5.0 @@ -2086,661 +1676,10 @@ abstract class WC_Abstract_Order { */ public function has_free_item() { foreach ( $this->get_items() as $item ) { - if ( ! $item['line_total'] ) { + if ( ! $item->get_total() ) { return true; } } return false; } - - /** - * Generates a URL so that a customer can pay for their (unpaid - pending) order. Pass 'true' for the checkout version which doesn't offer gateway choices. - * - * @param bool $on_checkout - * @return string - */ - public function get_checkout_payment_url( $on_checkout = false ) { - - $pay_url = wc_get_endpoint_url( 'order-pay', $this->id, wc_get_page_permalink( 'checkout' ) ); - - if ( 'yes' == get_option( 'woocommerce_force_ssl_checkout' ) || is_ssl() ) { - $pay_url = str_replace( 'http:', 'https:', $pay_url ); - } - - if ( $on_checkout ) { - $pay_url = add_query_arg( 'key', $this->order_key, $pay_url ); - } else { - $pay_url = add_query_arg( array( 'pay_for_order' => 'true', 'key' => $this->order_key ), $pay_url ); - } - - return apply_filters( 'woocommerce_get_checkout_payment_url', $pay_url, $this ); - } - - /** - * Generates a URL for the thanks page (order received). - * - * @return string - */ - public function get_checkout_order_received_url() { - - $order_received_url = wc_get_endpoint_url( 'order-received', $this->id, wc_get_page_permalink( 'checkout' ) ); - - if ( 'yes' == get_option( 'woocommerce_force_ssl_checkout' ) || is_ssl() ) { - $order_received_url = str_replace( 'http:', 'https:', $order_received_url ); - } - - $order_received_url = add_query_arg( 'key', $this->order_key, $order_received_url ); - - return apply_filters( 'woocommerce_get_checkout_order_received_url', $order_received_url, $this ); - } - - /** - * Generates a URL so that a customer can cancel their (unpaid - pending) order. - * - * @param string $redirect - * - * @return string - */ - public function get_cancel_order_url( $redirect = '' ) { - - // Get cancel endpoint - $cancel_endpoint = $this->get_cancel_endpoint(); - - return apply_filters( 'woocommerce_get_cancel_order_url', esc_url( add_query_arg( array( - 'cancel_order' => 'true', - 'order' => $this->order_key, - 'order_id' => $this->id, - 'redirect' => $redirect, - ), $cancel_endpoint ) ) ); - } - - /** - * Generates a raw (unescaped) cancel-order URL for use by payment gateways. - * - * @param string $redirect - * @return string The unescaped cancel-order URL. - */ - public function get_cancel_order_url_raw( $redirect = '' ) { - - // Get cancel endpoint - $cancel_endpoint = $this->get_cancel_endpoint(); - - return apply_filters( 'woocommerce_get_cancel_order_url_raw', add_query_arg( array( - 'cancel_order' => 'true', - 'order' => $this->order_key, - 'order_id' => $this->id, - 'redirect' => $redirect, - ), $cancel_endpoint ) ); - } - - - /** - * Helper method to return the cancel endpoint. - * - * @return string the cancel endpoint; either the cart page or the home page. - */ - public function get_cancel_endpoint() { - - $cancel_endpoint = wc_get_page_permalink( 'cart' ); - if ( ! $cancel_endpoint ) { - $cancel_endpoint = home_url(); - } - - if ( false === strpos( $cancel_endpoint, '?' ) ) { - $cancel_endpoint = trailingslashit( $cancel_endpoint ); - } - - return $cancel_endpoint; - } - - - /** - * Generates a URL to view an order from the my account page. - * - * @return string - */ - public function get_view_order_url() { - - $view_order_url = wc_get_endpoint_url( 'view-order', $this->id, wc_get_page_permalink( 'myaccount' ) ); - - return apply_filters( 'woocommerce_get_view_order_url', $view_order_url, $this ); - } - - /** - * Get the downloadable files for an item in this order. - * - * @param array $item - * @return array - */ - public function get_item_downloads( $item ) { - global $wpdb; - - $product_id = $item['variation_id'] > 0 ? $item['variation_id'] : $item['product_id']; - $product = wc_get_product( $product_id ); - if ( ! $product ) { - /** - * $product can be `false`. Example: checking an old order, when a product or variation has been deleted. - * @see \WC_Product_Factory::get_product - */ - return array(); - } - $download_ids = $wpdb->get_col( $wpdb->prepare(" - SELECT download_id - FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions - WHERE user_email = %s - AND order_key = %s - AND product_id = %s - ORDER BY permission_id - ", $this->billing_email, $this->order_key, $product_id ) ); - - $files = array(); - - foreach ( $download_ids as $download_id ) { - - if ( $product->has_file( $download_id ) ) { - $files[ $download_id ] = $product->get_file( $download_id ); - $files[ $download_id ]['download_url'] = $this->get_download_url( $product_id, $download_id ); - } - } - - return apply_filters( 'woocommerce_get_item_downloads', $files, $item, $this ); - } - - /** - * Display download links for an order item. - * @param array $item - */ - public function display_item_downloads( $item ) { - $product = $this->get_product_from_item( $item ); - - if ( $product && $product->exists() && $product->is_downloadable() && $this->is_download_permitted() ) { - $download_files = $this->get_item_downloads( $item ); - $i = 0; - $links = array(); - - foreach ( $download_files as $download_id => $file ) { - $i++; - $prefix = count( $download_files ) > 1 ? sprintf( __( 'Download %d', 'woocommerce' ), $i ) : __( 'Download', 'woocommerce' ); - $links[] = '' . $prefix . ': ' . esc_html( $file['name'] ) . '' . "\n"; - } - - echo '
' . implode( '
', $links ); - } - } - - /** - * Get the Download URL. - * - * @param int $product_id - * @param int $download_id - * @return string - */ - public function get_download_url( $product_id, $download_id ) { - return add_query_arg( array( - 'download_file' => $product_id, - 'order' => $this->order_key, - 'email' => urlencode( $this->billing_email ), - 'key' => $download_id - ), trailingslashit( home_url() ) ); - } - - /** - * Adds a note (comment) to the order. - * - * @param string $note Note to add. - * @param int $is_customer_note (default: 0) Is this a note for the customer? - * @param bool added_by_user Was the note added by a user? - * @return int Comment ID. - */ - public function add_order_note( $note, $is_customer_note = 0, $added_by_user = false ) { - if ( is_user_logged_in() && current_user_can( 'edit_shop_order', $this->id ) && $added_by_user ) { - $user = get_user_by( 'id', get_current_user_id() ); - $comment_author = $user->display_name; - $comment_author_email = $user->user_email; - } else { - $comment_author = __( 'WooCommerce', 'woocommerce' ); - $comment_author_email = strtolower( __( 'WooCommerce', 'woocommerce' ) ) . '@'; - $comment_author_email .= isset( $_SERVER['HTTP_HOST'] ) ? str_replace( 'www.', '', $_SERVER['HTTP_HOST'] ) : 'noreply.com'; - $comment_author_email = sanitize_email( $comment_author_email ); - } - - $comment_post_ID = $this->id; - $comment_author_url = ''; - $comment_content = $note; - $comment_agent = 'WooCommerce'; - $comment_type = 'order_note'; - $comment_parent = 0; - $comment_approved = 1; - $commentdata = apply_filters( 'woocommerce_new_order_note_data', compact( 'comment_post_ID', 'comment_author', 'comment_author_email', 'comment_author_url', 'comment_content', 'comment_agent', 'comment_type', 'comment_parent', 'comment_approved' ), array( 'order_id' => $this->id, 'is_customer_note' => $is_customer_note ) ); - - $comment_id = wp_insert_comment( $commentdata ); - - if ( $is_customer_note ) { - add_comment_meta( $comment_id, 'is_customer_note', 1 ); - - do_action( 'woocommerce_new_customer_note', array( 'order_id' => $this->id, 'customer_note' => $commentdata['comment_content'] ) ); - } - - return $comment_id; - } - - /** - * Updates status of order. - * - * @param string $new_status Status to change the order to. No internal wc- prefix is required. - * @param string $note (default: '') Optional note to add. - * @param bool $manual is this a manual order status change? - * @return bool Successful change or not - */ - public function update_status( $new_status, $note = '', $manual = false ) { - if ( ! $this->id ) { - return false; - } - - // Standardise status names. - $new_status = 'wc-' === substr( $new_status, 0, 3 ) ? substr( $new_status, 3 ) : $new_status; - $old_status = $this->get_status(); - - // If the old status is unknown (e.g. draft) assume its pending for action usage. - if ( ! in_array( 'wc-' . $old_status, array_keys( wc_get_order_statuses() ) ) ) { - $old_status = 'pending'; - } - - // If the statuses are the same there is no need to update, unless the post status is not a valid 'wc' status. - if ( $new_status === $old_status && in_array( $this->post_status, array_keys( wc_get_order_statuses() ) ) ) { - return false; - } - - $this->post_status = 'wc-' . $new_status; - $update_post_data = array( - 'ID' => $this->id, - 'post_status' => $this->post_status, - ); - - if ( 'pending' === $old_status && ! $manual ) { - $update_post_data[ 'post_date' ] = current_time( 'mysql', 0 ); - $update_post_data[ 'post_date_gmt' ] = current_time( 'mysql', 1 ); - } - - if ( ! wp_update_post( $update_post_data ) ) { - $this->add_order_note( sprintf( __( 'Unable to update order from %1$s to %2$s.', 'woocommerce' ), wc_get_order_status_name( $old_status ), wc_get_order_status_name( $new_status ) ), 0, $manual ); - return false; - } - - // Status was set. - do_action( 'woocommerce_order_status_' . $new_status, $this->id ); - - // Status was changed. - if ( $new_status !== $old_status ) { - $this->add_order_note( trim( $note . ' ' . sprintf( __( 'Order status changed from %1$s to %2$s.', 'woocommerce' ), wc_get_order_status_name( $old_status ), wc_get_order_status_name( $new_status ) ) ), 0, $manual ); - do_action( 'woocommerce_order_status_' . $old_status . '_to_' . $new_status, $this->id ); - do_action( 'woocommerce_order_status_changed', $this->id, $old_status, $new_status ); - } else { - $this->add_order_note( trim( $note . ' ' . sprintf( __( 'Order status changed to %s.', 'woocommerce' ), wc_get_order_status_name( $new_status ) ) ), 0, $manual ); - } - - switch ( $new_status ) { - - case 'completed' : - // Record the sales. - $this->record_product_sales(); - - // Increase coupon usage counts. - $this->increase_coupon_usage_counts(); - - // Record the completed date of the order. - update_post_meta( $this->id, '_completed_date', current_time('mysql') ); - - // Update reports. - wc_delete_shop_order_transients( $this->id ); - break; - - case 'processing' : - case 'on-hold' : - // Record the sales. - $this->record_product_sales(); - - // Increase coupon usage counts. - $this->increase_coupon_usage_counts(); - - // Update reports. - wc_delete_shop_order_transients( $this->id ); - break; - - case 'cancelled' : - // If the order is cancelled, restore used coupons. - $this->decrease_coupon_usage_counts(); - - // Update reports. - wc_delete_shop_order_transients( $this->id ); - break; - } - - return true; - } - - - /** - * Cancel the order and restore the cart (before payment). - * - * @param string $note (default: '') Optional note to add. - */ - public function cancel_order( $note = '' ) { - WC()->session->set( 'order_awaiting_payment', false ); - $this->update_status( 'cancelled', $note ); - } - - /** - * When a payment is complete this function is called. - * - * Most of the time this should mark an order as 'processing' so that admin can process/post the items. - * If the cart contains only downloadable items then the order is 'completed' since the admin needs to take no action. - * Stock levels are reduced at this point. - * Sales are also recorded for products. - * Finally, record the date of payment. - * - * @param string $transaction_id Optional transaction id to store in post meta. - */ - public function payment_complete( $transaction_id = '' ) { - do_action( 'woocommerce_pre_payment_complete', $this->id ); - - if ( null !== WC()->session ) { - WC()->session->set( 'order_awaiting_payment', false ); - } - - $valid_order_statuses = apply_filters( 'woocommerce_valid_order_statuses_for_payment_complete', array( 'on-hold', 'pending', 'failed', 'cancelled' ), $this ); - - if ( $this->id && $this->has_status( $valid_order_statuses ) ) { - $order_needs_processing = false; - - if ( sizeof( $this->get_items() ) > 0 ) { - foreach ( $this->get_items() as $item ) { - if ( $_product = $this->get_product_from_item( $item ) ) { - $virtual_downloadable_item = $_product->is_downloadable() && $_product->is_virtual(); - - if ( apply_filters( 'woocommerce_order_item_needs_processing', ! $virtual_downloadable_item, $_product, $this->id ) ) { - $order_needs_processing = true; - break; - } - } else { - $order_needs_processing = true; - break; - } - } - } - - $this->update_status( apply_filters( 'woocommerce_payment_complete_order_status', $order_needs_processing ? 'processing' : 'completed', $this->id ) ); - - add_post_meta( $this->id, '_paid_date', current_time( 'mysql' ), true ); - - if ( ! empty( $transaction_id ) ) { - update_post_meta( $this->id, '_transaction_id', $transaction_id ); - } - - // Payment is complete so reduce stock levels - if ( apply_filters( 'woocommerce_payment_complete_reduce_order_stock', ! get_post_meta( $this->id, '_order_stock_reduced', true ), $this->id ) ) { - $this->reduce_order_stock(); - } - - do_action( 'woocommerce_payment_complete', $this->id ); - } else { - do_action( 'woocommerce_payment_complete_order_status_' . $this->get_status(), $this->id ); - } - } - - - /** - * Record sales. - */ - public function record_product_sales() { - if ( 'yes' === get_post_meta( $this->id, '_recorded_sales', true ) ) { - return; - } - - if ( sizeof( $this->get_items() ) > 0 ) { - - foreach ( $this->get_items() as $item ) { - - if ( $item['product_id'] > 0 ) { - $sales = (int) get_post_meta( $item['product_id'], 'total_sales', true ); - $sales += (int) $item['qty']; - - if ( $sales ) { - update_post_meta( $item['product_id'], 'total_sales', $sales ); - } - } - } - } - - update_post_meta( $this->id, '_recorded_sales', 'yes' ); - - /** - * Called when sales for an order are recorded - * - * @param int $order_id order id - */ - do_action( 'woocommerce_recorded_sales', $this->id ); - } - - - /** - * Get coupon codes only. - * - * @return array - */ - public function get_used_coupons() { - - $codes = array(); - $coupons = $this->get_items( 'coupon' ); - - foreach ( $coupons as $item_id => $item ) { - $codes[] = trim( $item['name'] ); - } - - return $codes; - } - - - /** - * Increase applied coupon counts. - */ - public function increase_coupon_usage_counts() { - if ( 'yes' == get_post_meta( $this->id, '_recorded_coupon_usage_counts', true ) ) { - return; - } - - if ( sizeof( $this->get_used_coupons() ) > 0 ) { - - foreach ( $this->get_used_coupons() as $code ) { - if ( ! $code ) { - continue; - } - - $coupon = new WC_Coupon( $code ); - - $used_by = $this->get_user_id(); - - if ( ! $used_by ) { - $used_by = $this->billing_email; - } - - $coupon->inc_usage_count( $used_by ); - } - - update_post_meta( $this->id, '_recorded_coupon_usage_counts', 'yes' ); - } - } - - - /** - * Decrease applied coupon counts. - */ - public function decrease_coupon_usage_counts() { - - if ( 'yes' != get_post_meta( $this->id, '_recorded_coupon_usage_counts', true ) ) { - return; - } - - if ( sizeof( $this->get_used_coupons() ) > 0 ) { - - foreach ( $this->get_used_coupons() as $code ) { - - if ( ! $code ) { - continue; - } - - $coupon = new WC_Coupon( $code ); - - $used_by = $this->get_user_id(); - if ( ! $used_by ) { - $used_by = $this->billing_email; - } - - $coupon->dcr_usage_count( $used_by ); - } - - delete_post_meta( $this->id, '_recorded_coupon_usage_counts' ); - } - } - - /** - * Reduce stock levels for all line items in the order. - * Runs if stock management is enabled, but can be disabled on per-order basis by extensions @since 2.4.0 via woocommerce_can_reduce_order_stock hook. - */ - public function reduce_order_stock() { - if ( 'yes' === get_option( 'woocommerce_manage_stock' ) && apply_filters( 'woocommerce_can_reduce_order_stock', true, $this ) && sizeof( $this->get_items() ) > 0 ) { - foreach ( $this->get_items() as $item ) { - if ( $item['product_id'] > 0 ) { - $_product = $this->get_product_from_item( $item ); - - if ( $_product && $_product->exists() && $_product->managing_stock() ) { - $qty = apply_filters( 'woocommerce_order_item_quantity', $item['qty'], $this, $item ); - $new_stock = $_product->reduce_stock( $qty ); - $item_name = $_product->get_sku() ? $_product->get_sku(): $item['product_id']; - - if ( isset( $item['variation_id'] ) && $item['variation_id'] ) { - $this->add_order_note( sprintf( __( 'Item %1$s variation #%2$s stock reduced from %3$s to %4$s.', 'woocommerce' ), $item_name, $item['variation_id'], $new_stock + $qty, $new_stock) ); - } else { - $this->add_order_note( sprintf( __( 'Item %1$s stock reduced from %2$s to %3$s.', 'woocommerce' ), $item_name, $new_stock + $qty, $new_stock) ); - } - $this->send_stock_notifications( $_product, $new_stock, $item['qty'] ); - } - } - } - - add_post_meta( $this->id, '_order_stock_reduced', '1', true ); - - do_action( 'woocommerce_reduce_order_stock', $this ); - } - } - - /** - * Send the stock notifications. - * - * @param WC_Product $product - * @param int $new_stock - * @param int $qty_ordered - */ - public function send_stock_notifications( $product, $new_stock, $qty_ordered ) { - - // Backorders - if ( $new_stock < 0 ) { - do_action( 'woocommerce_product_on_backorder', array( 'product' => $product, 'order_id' => $this->id, 'quantity' => $qty_ordered ) ); - } - - // stock status notifications - $notification_sent = false; - - if ( 'yes' == get_option( 'woocommerce_notify_no_stock' ) && get_option( 'woocommerce_notify_no_stock_amount' ) >= $new_stock ) { - do_action( 'woocommerce_no_stock', $product ); - $notification_sent = true; - } - - if ( ! $notification_sent && 'yes' == get_option( 'woocommerce_notify_low_stock' ) && get_option( 'woocommerce_notify_low_stock_amount' ) >= $new_stock ) { - do_action( 'woocommerce_low_stock', $product ); - } - - do_action( 'woocommerce_after_send_stock_notifications', $product, $new_stock, $qty_ordered ); - } - - - /** - * List order notes (public) for the customer. - * - * @return array - */ - public function get_customer_order_notes() { - $notes = array(); - $args = array( - 'post_id' => $this->id, - 'approve' => 'approve', - 'type' => '' - ); - - remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ) ); - - $comments = get_comments( $args ); - - foreach ( $comments as $comment ) { - if ( ! get_comment_meta( $comment->comment_ID, 'is_customer_note', true ) ) { - continue; - } - $comment->comment_content = make_clickable( $comment->comment_content ); - $notes[] = $comment; - } - - add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ) ); - - return $notes; - } - - /** - * Checks if an order needs payment, based on status and order total. - * - * @return bool - */ - public function needs_payment() { - - $valid_order_statuses = apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'failed' ), $this ); - - if ( $this->has_status( $valid_order_statuses ) && $this->get_total() > 0 ) { - $needs_payment = true; - } else { - $needs_payment = false; - } - - return apply_filters( 'woocommerce_order_needs_payment', $needs_payment, $this, $valid_order_statuses ); - } - - /** - * Checks if an order needs display the shipping address, based on shipping method. - * - * @return boolean - */ - public function needs_shipping_address() { - if ( ! wc_shipping_enabled() ) { - return false; - } - - $hide = apply_filters( 'woocommerce_order_hide_shipping_address', array( 'local_pickup' ), $this ); - $needs_address = false; - - foreach ( $this->get_shipping_methods() as $shipping_method ) { - if ( ! in_array( $shipping_method['method_id'], $hide ) ) { - $needs_address = true; - break; - } - } - - return apply_filters( 'woocommerce_order_needs_shipping_address', $needs_address, $hide, $this ); - } - - /** - * Checks if an order can be edited, specifically for use on the Edit Order screen. - * - * @return bool - */ - public function is_editable() { - return apply_filters( 'wc_order_is_editable', in_array( $this->get_status(), array( 'pending', 'on-hold', 'auto-draft', 'failed' ) ), $this ); - } } From fe3e61b75408d831b0ab2302240bc487f9f8079c Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 21 Jun 2016 20:04:49 +0100 Subject: [PATCH 007/298] Legacy order class --- .../abstracts/abstract-wc-legacy-order.php | 628 ++++++++++++++++++ 1 file changed, 628 insertions(+) create mode 100644 includes/abstracts/abstract-wc-legacy-order.php diff --git a/includes/abstracts/abstract-wc-legacy-order.php b/includes/abstracts/abstract-wc-legacy-order.php new file mode 100644 index 00000000000..8f4076373e3 --- /dev/null +++ b/includes/abstracts/abstract-wc-legacy-order.php @@ -0,0 +1,628 @@ +get_item( $item ); + } + if ( ! is_object( $item ) || ! $item->is_type( 'line_item' ) ) { + return false; + } + if ( ! $this->get_id() ) { + $this->save(); // Order must exist + } + + // BW compatibility with old args + if ( isset( $args['totals'] ) ) { + foreach ( $args['totals'] as $key => $value ) { + if ( 'tax' === $key ) { + $args['total_tax'] = $value; + } elseif ( 'tax_data' === $key ) { + $args['taxes'] = $value; + } else { + $args[ $key ] = $value; + } + } + } + + // Handly qty if set + if ( isset( $args['qty'] ) ) { + if ( $product->backorders_require_notification() && $product->is_on_backorder( $args['qty'] ) ) { + $item->add_meta_data( apply_filters( 'woocommerce_backordered_item_meta_name', __( 'Backordered', 'woocommerce' ) ), $args['qty'] - max( 0, $product->get_total_stock() ), true ); + } + $args['subtotal'] = $args['subtotal'] ? $args['subtotal'] : $product->get_price_excluding_tax( $args['qty'] ); + $args['total'] = $args['total'] ? $args['total'] : $product->get_price_excluding_tax( $args['qty'] ); + } + + $item->set_order_id( $this->get_id() ); + $item->set_all( $args ); + $item->save(); + do_action( 'woocommerce_order_edit_product', $this->get_id(), $item->get_id(), $args, $product ); + + return $item->get_id(); + } + + /** + * Update coupon for order. Note this does not update order totals. + * @since 2.2 + * @param object|int $item + * @param array $args + * @return int updated order item ID + */ + public function update_coupon( $item, $args ) { + _deprecated_function( 'WC_Order::update_coupon', '2.7', 'Interact with WC_Order_Item_Coupon class' ); + if ( is_numeric( $item ) ) { + $item = $this->get_item( $item ); + } + if ( ! is_object( $item ) || ! $item->is_type( 'coupon' ) ) { + return false; + } + if ( ! $this->get_id() ) { + $this->save(); // Order must exist + } + + // BW compatibility for old args + if ( isset( $args['discount_amount'] ) ) { + $args['discount'] = $args['discount_amount']; + } + if ( isset( $args['discount_amount_tax'] ) ) { + $args['discount_tax'] = $args['discount_amount_tax']; + } + + $item->set_order_id( $this->get_id() ); + $item->set_all( $args ); + $item->save(); + + do_action( 'woocommerce_order_update_coupon', $this->get_id(), $item->get_id(), $args ); + + return $item->get_id(); + } + + /** + * Update shipping method for order. + * + * Note this does not update the order total. + * + * @since 2.2 + * @param object|int $item + * @param array $args + * @return int updated order item ID + */ + public function update_shipping( $item, $args ) { + _deprecated_function( 'WC_Order::update_shipping', '2.7', 'Interact with WC_Order_Item_Shipping class' ); + if ( is_numeric( $item ) ) { + $item = $this->get_item( $item ); + } + if ( ! is_object( $item ) || ! $item->is_type( 'shipping' ) ) { + return false; + } + if ( ! $this->get_id() ) { + $this->save(); // Order must exist + } + + // BW compatibility for old args + if ( isset( $args['cost'] ) ) { + $args['total'] = $args['cost']; + } + + $item->set_order_id( $this->get_id() ); + $item->set_all( $args ); + $item->save(); + $this->calculate_shipping(); + + do_action( 'woocommerce_order_update_shipping', $this->get_id(), $item->get_id(), $args ); + + return $item->get_id(); + } + + /** + * Update fee for order. + * + * Note this does not update order totals. + * + * @since 2.2 + * @param object|int $item + * @param array $args + * @return int updated order item ID + */ + public function update_fee( $item, $args ) { + _deprecated_function( 'WC_Order::update_fee', '2.7', 'Interact with WC_Order_Item_Fee class' ); + if ( is_numeric( $item ) ) { + $item = $this->get_item( $item ); + } + if ( ! is_object( $item ) || ! $item->is_type( 'fee' ) ) { + return false; + } + if ( ! $this->get_id() ) { + $this->save(); // Order must exist + } + + $item->set_order_id( $this->get_id() ); + $item->set_all( $args ); + $item->save(); + + do_action( 'woocommerce_order_update_fee', $this->get_id(), $item->get_id(), $args ); + + return $item->get_id(); + } + + /** + * Update tax line on order. + * Note this does not update order totals. + * + * @since 2.7 + * @param object|int $item + * @param array $args + * @return int updated order item ID + */ + public function update_tax( $item, $args ) { + _deprecated_function( 'WC_Order::update_tax', '2.7', 'Interact with WC_Order_Item_Tax class' ); + if ( is_numeric( $item ) ) { + $item = $this->get_item( $item ); + } + if ( ! is_object( $item ) || ! $item->is_type( 'tax' ) ) { + return false; + } + if ( ! $this->get_id() ) { + $this->save(); // Order must exist + } + + $item->set_order_id( $this->get_id() ); + $item->set_all( $args ); + $item->save(); + + do_action( 'woocommerce_order_update_tax', $this->get_id(), $item->get_id(), $args ); + + return $item->get_id(); + } + + /** + * Get a product (either product or variation). + * @deprecated Add deprecation notices in future release. Replaced with $item->get_product() + * @param object $item + * @return WC_Product|bool + */ + public function get_product_from_item( $item ) { + if ( is_callable( array( $item, 'get_product' ) ) ) { + $product = $item->get_product(); + } else { + $product = false; + } + return apply_filters( 'woocommerce_get_product_from_item', $product, $item, $this ); + } + + /** + * Set the customer address. + * @since 2.2.0 + * @param array $address Address data. + * @param string $type billing or shipping. + */ + public function set_address( $address, $type = 'billing' ) { + foreach ( $address as $key => $value ) { + update_post_meta( $this->get_id(), "_{$type}_" . $key, $value ); + if ( is_callable( array( $this, "set_{$type}_{$key}" ) ) ) { + $this->{"set_{$type}_{$key}"}( $value ); + } + } + } + + /** + * Set an order total. + * @since 2.2.0 + * @param float $amount + * @param string $total_type + * @return bool + */ + public function legacy_set_total( $amount, $total_type = 'total' ) { + if ( ! in_array( $total_type, array( 'shipping', 'tax', 'shipping_tax', 'total', 'cart_discount', 'cart_discount_tax' ) ) ) { + return false; + } + + switch ( $total_type ) { + case 'total' : + $amount = wc_format_decimal( $amount, wc_get_price_decimals() ); + $this->set_total( $amount ); + update_post_meta( $this->get_id(), '_order_total', $amount ); + break; + case 'cart_discount' : + $amount = wc_format_decimal( $amount ); + $this->set_discount_total( $amount ); + update_post_meta( $this->get_id(), '_cart_discount', $amount ); + break; + case 'cart_discount_tax' : + $amount = wc_format_decimal( $amount ); + $this->set_discount_tax( $amount ); + update_post_meta( $this->get_id(), '_cart_discount_tax', $amount ); + break; + case 'shipping' : + $amount = wc_format_decimal( $amount ); + $this->set_shipping_total( $amount ); + update_post_meta( $this->get_id(), '_order_shipping', $amount ); + break; + case 'shipping_tax' : + $amount = wc_format_decimal( $amount ); + $this->set_shipping_tax( $amount ); + update_post_meta( $this->get_id(), '_order_shipping_tax', $amount ); + break; + case 'tax' : + $amount = wc_format_decimal( $amount ); + $this->set_cart_tax( $amount ); + update_post_meta( $this->get_id(), '_order_tax', $amount ); + break; + } + + return true; + } + + /** + * Magic __isset method for backwards compatibility. + * @param string $key + * @return bool + */ + public function __isset( $key ) { + // Legacy properties which could be accessed directly in the past. + $legacy_props = array( 'completed_date', 'id', 'order_type', 'post', 'status', 'post_status', 'customer_note', 'customer_message', 'user_id', 'customer_user', 'prices_include_tax', 'tax_display_cart', 'display_totals_ex_tax', 'display_cart_ex_tax', 'order_date', 'modified_date', 'cart_discount', 'cart_discount_tax', 'order_shipping', 'order_shipping_tax', 'order_total', 'order_tax', 'billing_first_name', 'billing_last_name', 'billing_company', 'billing_address_1', 'billing_address_2', 'billing_city', 'billing_state', 'billing_postcode', 'billing_country', 'billing_phone', 'billing_email', 'shipping_first_name', 'shipping_last_name', 'shipping_company', 'shipping_address_1', 'shipping_address_2', 'shipping_city', 'shipping_state', 'shipping_postcode', 'shipping_country', 'customer_ip_address', 'customer_user_agent', 'payment_method_title', 'payment_method', 'order_currency' ); + return $this->get_id() ? ( in_array( $key, $legacy_props ) || metadata_exists( 'post', $this->get_id(), '_' . $key ) ) : false; + } + + /** + * Magic __get method for backwards compatibility. + * @param string $key + * @return mixed + */ + public function __get( $key ) { + _doing_it_wrong( $key, 'Order properties should not be accessed directly.', '2.7' ); + + if ( 'completed_date' === $key ) { + return $this->get_date_completed(); + } elseif ( 'paid_date' === $key ) { + return $this->get_date_paid(); + } elseif ( 'modified_date' === $key ) { + return $this->get_date_modified(); + } elseif ( 'order_date' === $key ) { + return $this->get_date_created(); + } elseif ( 'id' === $key ) { + return $this->get_id(); + } elseif ( 'post' === $key ) { + return get_post( $this->get_id() ); + } elseif ( 'status' === $key || 'post_status' === $key ) { + return $this->get_status(); + } elseif ( 'customer_message' === $key || 'customer_note' === $key ) { + return $this->get_customer_note(); + } elseif ( in_array( $key, array( 'user_id', 'customer_user' ) ) ) { + return $this->get_customer_id(); + } elseif ( 'tax_display_cart' === $key ) { + return get_option( 'woocommerce_tax_display_cart' ); + } elseif ( 'display_totals_ex_tax' === $key ) { + return 'excl' === get_option( 'woocommerce_tax_display_cart' ); + } elseif ( 'display_cart_ex_tax' === $key ) { + return 'excl' === get_option( 'woocommerce_tax_display_cart' ); + } elseif ( 'cart_discount' === $key ) { + return $this->get_discount(); + } elseif ( 'cart_discount_tax' === $key ) { + return $this->get_discount_tax(); + } elseif ( 'order_tax' === $key ) { + return $this->get_cart_tax(); + } elseif ( 'order_shipping_tax' === $key ) { + return $this->get_shipping_tax(); + } elseif ( 'order_shipping' === $key ) { + return $this->get_shipping_total(); + } elseif ( 'order_total' === $key ) { + return $this->get_total(); + } elseif ( 'order_type' === $key ) { + return $this->get_type(); + } elseif ( 'order_currency' === $key ) { + return $this->get_currency(); + } elseif ( 'order_version' === $key ) { + return $this->get_version(); + } elseif ( is_callable( array( $this, "get_{$key}" ) ) ) { + return $this->{"get_{$key}"}(); + } else { + return get_post_meta( $this->get_id(), '_' . $key, true ); + } + } + + /** + * has_meta function for order items. + * + * @param string $order_item_id + * @return array of meta data. + */ + public function has_meta( $order_item_id ) { + global $wpdb; + + _deprecated_function( 'has_meta', '2.7', 'WC_Order_item::get_meta_data' ); + + return $wpdb->get_results( $wpdb->prepare( "SELECT meta_key, meta_value, meta_id, order_item_id + FROM {$wpdb->prefix}woocommerce_order_itemmeta WHERE order_item_id = %d + ORDER BY meta_id", absint( $order_item_id ) ), ARRAY_A ); + } + + /** + * Display meta data belonging to an item. + * @param array $item + */ + public function display_item_meta( $item ) { + _deprecated_function( 'get_item_meta', '2.7', 'wc_display_item_meta' ); + $product = $item->get_product(); + $item_meta = new WC_Order_Item_Meta( $item, $product ); + $item_meta->display(); + } + + /** + * Display download links for an order item. + * @param array $item + */ + public function display_item_downloads( $item ) { + $product = $item->get_product(); + + if ( $product && $product->exists() && $product->is_downloadable() && $this->is_download_permitted() ) { + $download_files = $this->get_item_downloads( $item ); + $i = 0; + $links = array(); + + foreach ( $download_files as $download_id => $file ) { + $i++; + $prefix = count( $download_files ) > 1 ? sprintf( __( 'Download %d', 'woocommerce' ), $i ) : __( 'Download', 'woocommerce' ); + $links[] = '' . $prefix . ': ' . esc_html( $file['name'] ) . '' . "\n"; + } + + echo '
' . implode( '
', $links ); + } + } + + /** + * Get the Download URL. + * + * @param int $product_id + * @param int $download_id + * @return string + */ + public function get_download_url( $product_id, $download_id ) { + return add_query_arg( array( + 'download_file' => $product_id, + 'order' => $this->get_order_key(), + 'email' => urlencode( $this->get_billing_email() ), + 'key' => $download_id, + ), trailingslashit( home_url() ) ); + } + + /** + * Get the downloadable files for an item in this order. + * + * @param array $item + * @return array + */ + public function get_item_downloads( $item ) { + global $wpdb; + + $product = $item->get_product(); + + if ( ! $product ) { + /** + * $product can be `false`. Example: checking an old order, when a product or variation has been deleted. + * @see \WC_Product_Factory::get_product + */ + return array(); + } + $download_ids = $wpdb->get_col( $wpdb->prepare(" + SELECT download_id + FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions + WHERE user_email = %s + AND order_key = %s + AND product_id = %d + ORDER BY permission_id + ", $this->get_billing_email(), $this->get_order_key(), $product_id ) ); + + $files = array(); + + foreach ( $download_ids as $download_id ) { + + if ( $product->has_file( $download_id ) ) { + $files[ $download_id ] = $product->get_file( $download_id ); + $files[ $download_id ]['download_url'] = $this->get_download_url( $product_id, $download_id ); + } + } + + return apply_filters( 'woocommerce_get_item_downloads', $files, $item, $this ); + } + + /** + * Gets shipping total. Alias of WC_Order::get_shipping_total(). + * @deprecated 2.7.0 since this is an alias only. + * @return float + */ + public function get_total_shipping() { + return $this->get_shipping_total(); + } + + /** + * Get order item meta. + * @deprecated 2.7.0 + * @param mixed $order_item_id + * @param string $key (default: '') + * @param bool $single (default: false) + * @return array|string + */ + public function get_item_meta( $order_item_id, $key = '', $single = false ) { + _deprecated_function( 'get_item_meta', '2.7', 'wc_get_order_item_meta' ); + return get_metadata( 'order_item', $order_item_id, $key, $single ); + } + + /** + * Get all item meta data in array format in the order it was saved. Does not group meta by key like get_item_meta(). + * + * @param mixed $order_item_id + * @return array of objects + */ + public function get_item_meta_array( $order_item_id ) { + _deprecated_function( 'get_item_meta_array', '2.7', 'WC_Order_Item::get_meta_data() (note the format has changed)' ); + $item = $this->get_item( $order_item_id ); + $meta_data = $item->get_meta_data(); + $item_meta_array = array(); + + foreach ( $meta_data as $meta ) { + $item_meta_array[ $meta->meta_id ] = $meta; + } + + return $item_meta_array; + } + + /** + * Expand item meta into the $item array. + * @deprecated 2.7.0 Item meta no longer expanded due to new order item + * classes. This function now does nothing to avoid data breakage. + * @since 2.4.0 + * @param array $item before expansion. + * @return array + */ + public function expand_item_meta( $item ) { + _deprecated_function( 'expand_item_meta', '2.7', '' ); + return $item; + } + + /** + * Load the order object. Called from the constructor. + * @deprecated 2.7.0 Logic moved to constructor + * @param int|object|WC_Order $order Order to init. + */ + protected function init( $order ) { + _deprecated_function( 'init', '2.7', 'Logic moved to constructor' ); + if ( is_numeric( $order ) ) { + $this->read( $order ); + } elseif ( $order instanceof WC_Order ) { + $this->read( absint( $order->get_id() ) ); + } elseif ( isset( $order->ID ) ) { + $this->read( absint( $order->ID ) ); + } + } + + /** + * Gets an order from the database. + * @deprecated 2.7 + * @param int $id (default: 0). + * @return bool + */ + public function get_order( $id = 0 ) { + _deprecated_function( 'get_order', '2.7', 'read' ); + if ( ! $id ) { + return false; + } + if ( $result = get_post( $id ) ) { + $this->populate( $result ); + return true; + } + return false; + } + + /** + * Populates an order from the loaded post data. + * @deprecated 2.7 + * @param mixed $result + */ + public function populate( $result ) { + _deprecated_function( 'populate', '2.7', 'read' ); + $this->read( $result->ID ); + } + + /** + * Cancel the order and restore the cart (before payment). + * @deprecated 2.7.0 Moved to event handler. + * @param string $note (default: '') Optional note to add. + */ + public function cancel_order( $note = '' ) { + _deprecated_function( 'cancel_order', '2.7', 'update_status' ); + WC()->session->set( 'order_awaiting_payment', false ); + $this->update_status( 'cancelled', $note ); + } + + /** + * Record sales. + * @deprecated 2.7.0 + */ + public function record_product_sales() { + _deprecated_function( 'record_product_sales', '2.7', 'wc_update_total_sales_counts' ); + wc_update_total_sales_counts( $this->get_id() ); + } + + /** + * Increase applied coupon counts. + * @deprecated 2.7.0 + */ + public function increase_coupon_usage_counts() { + _deprecated_function( 'increase_coupon_usage_counts', '2.7', 'wc_update_coupon_usage_counts' ); + wc_update_coupon_usage_counts( $this->get_id() ); + } + + /** + * Decrease applied coupon counts. + * @deprecated 2.7.0 + */ + public function decrease_coupon_usage_counts() { + _deprecated_function( 'decrease_coupon_usage_counts', '2.7', 'wc_update_coupon_usage_counts' ); + wc_update_coupon_usage_counts( $this->get_id() ); + } + + /** + * Reduce stock levels for all line items in the order. + * @deprecated 2.7.0 + */ + public function reduce_order_stock() { + _deprecated_function( 'reduce_order_stock', '2.7', 'wc_reduce_stock_levels' ); + wc_reduce_stock_levels( $this->get_id() ); + } + + /** + * Send the stock notifications. + * @deprecated 2.7.0 No longer needs to be called directly. + */ + public function send_stock_notifications( $product, $new_stock, $qty_ordered ) { + _deprecated_function( 'send_stock_notifications', '2.7' ); + } + + /** + * Output items for display in html emails. + * @deprecated 2.7.0 Moved to template functions. + * @param array $args Items args. + * @return string + */ + public function email_order_items_table( $args = array() ) { + return wc_get_email_order_items( $this, $args ); + } + + /** + * Get currency. + * @deprecated 2.7.0 + */ + public function get_order_currency() { + _deprecated_function( 'get_order_currency', '2.7', 'get_currency' ); + return $this->get_currency(); + } +} From ece2b5bf57d55998a804e3f426b659294a6cd8a1 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 21 Jun 2016 20:06:39 +0100 Subject: [PATCH 008/298] Order class --- includes/class-wc-order.php | 1275 +++++++++++++++++++++++++++++++++-- 1 file changed, 1231 insertions(+), 44 deletions(-) diff --git a/includes/class-wc-order.php b/includes/class-wc-order.php index d8ff76290ce..773c38ee56e 100644 --- a/includes/class-wc-order.php +++ b/includes/class-wc-order.php @@ -1,11 +1,13 @@ _data = array_merge( $this->_data, array( + 'billing' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => '', + 'postcode' => '', + 'country' => '', + 'email' => '', + 'phone' => '', + ), + 'shipping' => array( + 'first_name' => '', + 'last_name' => '', + 'company' => '', + 'address_1' => '', + 'address_2' => '', + 'city' => '', + 'state' => '', + 'postcode' => '', + 'country' => '', + ), + 'payment_method' => '', + 'payment_method_title' => '', + 'transaction_id' => '', + 'customer_ip_address' => '', + 'customer_user_agent' => '', + 'created_via' => '', + 'customer_note' => '', + 'date_completed' => '', + 'date_paid' => '', + 'cart_hash' => '', + ) ); + parent::__construct( $order ); + } + + /** + * When a payment is complete this function is called. + * + * Most of the time this should mark an order as 'processing' so that admin can process/post the items. + * If the cart contains only downloadable items then the order is 'completed' since the admin needs to take no action. + * Stock levels are reduced at this point. + * Sales are also recorded for products. + * Finally, record the date of payment. + * + * @param string $transaction_id Optional transaction id to store in post meta. + */ + public function payment_complete( $transaction_id = '' ) { + do_action( 'woocommerce_pre_payment_complete', $this->get_id() ); + + if ( ! empty( WC()->session ) ) { + WC()->session->set( 'order_awaiting_payment', false ); + } + + if ( $this->get_id() && $this->has_status( apply_filters( 'woocommerce_valid_order_statuses_for_payment_complete', array( 'on-hold', 'pending', 'failed', 'cancelled' ), $this ) ) ) { + $order_needs_processing = false; + + if ( sizeof( $this->get_items() ) > 0 ) { + foreach ( $this->get_items() as $item ) { + if ( $item->is_type( 'line_item' ) && ( $product = $item->get_product() ) ) { + $virtual_downloadable_item = $product->is_downloadable() && $product->is_virtual(); + + if ( apply_filters( 'woocommerce_order_item_needs_processing', ! $virtual_downloadable_item, $product, $this->get_id() ) ) { + $order_needs_processing = true; + break; + } + } + } + } + + if ( ! empty( $transaction_id ) ) { + $this->set_transaction_id( $transaction_id ); + } + + $this->set_status( apply_filters( 'woocommerce_payment_complete_order_status', $order_needs_processing ? 'processing' : 'completed', $this->get_id() ) ); + $this->set_date_paid( current_time( 'timestamp' ) ); + $this->save(); + + do_action( 'woocommerce_payment_complete', $this->get_id() ); + } else { + do_action( 'woocommerce_payment_complete_order_status_' . $this->get_status(), $this->get_id() ); + } + } /** * Gets order total - formatted for display. - * * @return string */ public function get_formatted_order_total( $tax_display = '', $display_refunded = true ) { - $formatted_total = wc_price( $this->get_total(), array( 'currency' => $this->get_order_currency() ) ); + $formatted_total = wc_price( $this->get_total(), array( 'currency' => $this->get_currency() ) ); $order_total = $this->get_total(); $total_refunded = $this->get_total_refunded(); $tax_string = ''; @@ -35,12 +151,12 @@ class WC_Order extends WC_Abstract_Order { if ( 'itemized' == get_option( 'woocommerce_tax_total_display' ) ) { foreach ( $this->get_tax_totals() as $code => $tax ) { - $tax_amount = ( $total_refunded && $display_refunded ) ? wc_price( WC_Tax::round( $tax->amount - $this->get_total_tax_refunded_by_rate_id( $tax->rate_id ) ), array( 'currency' => $this->get_order_currency() ) ) : $tax->formatted_amount; + $tax_amount = ( $total_refunded && $display_refunded ) ? wc_price( WC_Tax::round( $tax->amount - $this->get_total_tax_refunded_by_rate_id( $tax->rate_id ) ), array( 'currency' => $this->get_currency() ) ) : $tax->formatted_amount; $tax_string_array[] = sprintf( '%s %s', $tax_amount, $tax->label ); } } else { $tax_amount = ( $total_refunded && $display_refunded ) ? $this->get_total_tax() - $this->get_total_tax_refunded() : $this->get_total_tax(); - $tax_string_array[] = sprintf( '%s %s', wc_price( $tax_amount, array( 'currency' => $this->get_order_currency() ) ), WC()->countries->tax_or_vat() ); + $tax_string_array[] = sprintf( '%s %s', wc_price( $tax_amount, array( 'currency' => $this->get_currency() ) ), WC()->countries->tax_or_vat() ); } if ( ! empty( $tax_string_array ) ) { $tax_string = ' ' . sprintf( __( '(includes %s)', 'woocommerce' ), implode( ', ', $tax_string_array ) ); @@ -48,7 +164,7 @@ class WC_Order extends WC_Abstract_Order { } if ( $total_refunded && $display_refunded ) { - $formatted_total = '' . strip_tags( $formatted_total ) . ' ' . wc_price( $order_total - $total_refunded, array( 'currency' => $this->get_order_currency() ) ) . $tax_string . ''; + $formatted_total = '' . strip_tags( $formatted_total ) . ' ' . wc_price( $order_total - $total_refunded, array( 'currency' => $this->get_currency() ) ) . $tax_string . ''; } else { $formatted_total .= $tax_string; } @@ -56,16 +172,1107 @@ class WC_Order extends WC_Abstract_Order { return apply_filters( 'woocommerce_get_formatted_order_total', $formatted_total, $this ); } + /* + |-------------------------------------------------------------------------- + | CRUD methods + |-------------------------------------------------------------------------- + | + | Methods which create, read, update and delete orders from the database. + | Written in abstract fashion so that the way orders are stored can be + | changed more easily in the future. + | + | A save method is included for convenience (chooses update or create based + | on if the order exists yet). + | + */ + + /** + * Insert data into the database. + * @since 2.7.0 + */ + public function create() { + parent::create(); + + // Store additonal order data + if ( $this->get_id() ) { + $this->update_post_meta( '_billing_first_name', $this->get_billing_first_name() ); + $this->update_post_meta( '_billing_last_name', $this->get_billing_last_name() ); + $this->update_post_meta( '_billing_company', $this->get_billing_company() ); + $this->update_post_meta( '_billing_address_1', $this->get_billing_address_1() ); + $this->update_post_meta( '_billing_address_2', $this->get_billing_address_2() ); + $this->update_post_meta( '_billing_city', $this->get_billing_city() ); + $this->update_post_meta( '_billing_state', $this->get_billing_state() ); + $this->update_post_meta( '_billing_postcode', $this->get_billing_postcode() ); + $this->update_post_meta( '_billing_country', $this->get_billing_country() ); + $this->update_post_meta( '_billing_email', $this->get_billing_email() ); + $this->update_post_meta( '_billing_phone', $this->get_billing_phone() ); + $this->update_post_meta( '_shipping_first_name', $this->get_shipping_first_name() ); + $this->update_post_meta( '_shipping_last_name', $this->get_shipping_last_name() ); + $this->update_post_meta( '_shipping_company', $this->get_shipping_company() ); + $this->update_post_meta( '_shipping_address_1', $this->get_shipping_address_1() ); + $this->update_post_meta( '_shipping_address_2', $this->get_shipping_address_2() ); + $this->update_post_meta( '_shipping_city', $this->get_shipping_city() ); + $this->update_post_meta( '_shipping_state', $this->get_shipping_state() ); + $this->update_post_meta( '_shipping_postcode', $this->get_shipping_postcode() ); + $this->update_post_meta( '_shipping_country', $this->get_shipping_country() ); + $this->update_post_meta( '_payment_method', $this->get_payment_method() ); + $this->update_post_meta( '_payment_method_title', $this->get_payment_method_title() ); + $this->update_post_meta( '_transaction_id', $this->get_transaction_id() ); + $this->update_post_meta( '_customer_ip_address', $this->get_customer_ip_address() ); + $this->update_post_meta( '_customer_user_agent', $this->get_customer_user_agent() ); + $this->update_post_meta( '_created_via', $this->get_created_via() ); + $this->update_post_meta( '_customer_note', $this->get_customer_note() ); + $this->update_post_meta( '_date_completed', $this->get_date_completed() ); + $this->update_post_meta( '_date_paid', $this->get_date_paid() ); + $this->update_post_meta( '_cart_hash', $this->get_cart_hash() ); + do_action( 'woocommerce_new_order', $this->get_id() ); + } + } + + /** + * Read from the database. + * @since 2.7.0 + * @param int $id ID of object to read. + */ + public function read( $id ) { + parent::read( $id ); + + // Read additonal order data + if ( $order_id = $this->get_id() ) { + $post_object = get_post( $this->get_id() ); + $this->set_billing_first_name( get_post_meta( $order_id, '_billing_first_name', true ) ); + $this->set_billing_last_name( get_post_meta( $order_id, '_billing_last_name', true ) ); + $this->set_billing_company( get_post_meta( $order_id, '_billing_company', true ) ); + $this->set_billing_address_1( get_post_meta( $order_id, '_billing_address_1', true ) ); + $this->set_billing_address_2( get_post_meta( $order_id, '_billing_address_2', true ) ); + $this->set_billing_city( get_post_meta( $order_id, '_billing_city', true ) ); + $this->set_billing_state( get_post_meta( $order_id, '_billing_state', true ) ); + $this->set_billing_postcode( get_post_meta( $order_id, '_billing_postcode', true ) ); + $this->set_billing_country( get_post_meta( $order_id, '_billing_country', true ) ); + $this->set_billing_email( get_post_meta( $order_id, '_billing_email', true ) ); + $this->set_billing_phone( get_post_meta( $order_id, '_billing_phone', true ) ); + $this->set_shipping_first_name( get_post_meta( $order_id, '_shipping_first_name', true ) ); + $this->set_shipping_last_name( get_post_meta( $order_id, '_shipping_last_name', true ) ); + $this->set_shipping_company( get_post_meta( $order_id, '_shipping_company', true ) ); + $this->set_shipping_address_1( get_post_meta( $order_id, '_shipping_address_1', true ) ); + $this->set_shipping_address_2( get_post_meta( $order_id, '_shipping_address_2', true ) ); + $this->set_shipping_city( get_post_meta( $order_id, '_shipping_city', true ) ); + $this->set_shipping_state( get_post_meta( $order_id, '_shipping_state', true ) ); + $this->set_shipping_postcode( get_post_meta( $order_id, '_shipping_postcode', true ) ); + $this->set_shipping_country( get_post_meta( $order_id, '_shipping_country', true ) ); + $this->set_payment_method( get_post_meta( $order_id, '_payment_method', true ) ); + $this->set_payment_method_title( get_post_meta( $order_id, '_payment_method_title', true ) ); + $this->set_transaction_id( get_post_meta( $order_id, '_transaction_id', true ) ); + $this->set_customer_ip_address( get_post_meta( $order_id, '_customer_ip_address', true ) ); + $this->set_customer_user_agent( get_post_meta( $order_id, '_customer_user_agent', true ) ); + $this->set_created_via( get_post_meta( $order_id, '_created_via', true ) ); + $this->set_customer_note( get_post_meta( $order_id, '_customer_note', true ) ); + $this->set_date_completed( get_post_meta( $order_id, '_completed_date', true ) ); + $this->set_date_paid( get_post_meta( $order_id, '_paid_date', true ) ); + $this->set_cart_hash( get_post_meta( $order_id, '_cart_hash', true ) ); + $this->set_customer_note( $post_object->post_excerpt ); + + // Map user data + if ( ! $this->get_billing_email() && ( $user = $this->get_user() ) ) { + $this->set_billing_email( $user->user_email ); + } + } + } + + /** + * Update data in the database. + * @since 2.7.0 + */ + public function update() { + // Store additonal order data + $this->update_post_meta( '_billing_first_name', $this->get_billing_first_name() ); + $this->update_post_meta( '_billing_last_name', $this->get_billing_last_name() ); + $this->update_post_meta( '_billing_company', $this->get_billing_company() ); + $this->update_post_meta( '_billing_address_1', $this->get_billing_address_1() ); + $this->update_post_meta( '_billing_address_2', $this->get_billing_address_2() ); + $this->update_post_meta( '_billing_city', $this->get_billing_city() ); + $this->update_post_meta( '_billing_state', $this->get_billing_state() ); + $this->update_post_meta( '_billing_postcode', $this->get_billing_postcode() ); + $this->update_post_meta( '_billing_country', $this->get_billing_country() ); + $this->update_post_meta( '_billing_email', $this->get_billing_email() ); + $this->update_post_meta( '_billing_phone', $this->get_billing_phone() ); + $this->update_post_meta( '_shipping_first_name', $this->get_shipping_first_name() ); + $this->update_post_meta( '_shipping_last_name', $this->get_shipping_last_name() ); + $this->update_post_meta( '_shipping_company', $this->get_shipping_company() ); + $this->update_post_meta( '_shipping_address_1', $this->get_shipping_address_1() ); + $this->update_post_meta( '_shipping_address_2', $this->get_shipping_address_2() ); + $this->update_post_meta( '_shipping_city', $this->get_shipping_city() ); + $this->update_post_meta( '_shipping_state', $this->get_shipping_state() ); + $this->update_post_meta( '_shipping_postcode', $this->get_shipping_postcode() ); + $this->update_post_meta( '_shipping_country', $this->get_shipping_country() ); + $this->update_post_meta( '_payment_method', $this->get_payment_method() ); + $this->update_post_meta( '_payment_method_title', $this->get_payment_method_title() ); + $this->update_post_meta( '_transaction_id', $this->get_transaction_id() ); + $this->update_post_meta( '_customer_ip_address', $this->get_customer_ip_address() ); + $this->update_post_meta( '_customer_user_agent', $this->get_customer_user_agent() ); + $this->update_post_meta( '_created_via', $this->get_created_via() ); + $this->update_post_meta( '_customer_note', $this->get_customer_note() ); + $this->update_post_meta( '_date_completed', $this->get_date_completed() ); + $this->update_post_meta( '_date_paid', $this->get_date_paid() ); + $this->update_post_meta( '_cart_hash', $this->get_cart_hash() ); + + $customer_changed = $this->update_post_meta( '_customer_user', $this->get_customer_id() ); + + // Update parent + parent::update(); + + // If customer changed, update any downloadable permissions + if ( $customer_changed ) { + $wpdb->update( $wpdb->prefix . "woocommerce_downloadable_product_permissions", + array( + 'user_id' => $this->get_customer_id(), + 'user_email' => $this->get_billing_email(), + ), + array( + 'order_id' => $this->get_id(), + ), + array( + '%d', + '%s', + ), + array( + '%d', + ) + ); + } + + // Handle status change + $this->status_transition(); + } + + /** + * Set order status. + * @since 2.7.0 + * @param string $new_status Status to change the order to. No internal wc- prefix is required. + * @param string $note (default: '') Optional note to add. + * @param bool $manual_update is this a manual order status change? + * @param array details of change + */ + public function set_status( $new_status, $note = '', $manual_update = false ) { + $result = parent::set_status( $new_status ); + + if ( ! empty( $result['from'] ) && $result['from'] !== $result['to'] ) { + $this->_status_transition = array( + 'from' => ! empty( $this->_status_transition['from'] ) ? $this->_status_transition['from'] : $result['from'], + 'to' => $result['to'], + 'note' => $note, + 'manual' => (bool) $manual_update, + ); + + if ( 'pending' === $result['from'] && ! $manual_update ) { + $this->set_date_paid( current_time( 'timestamp' ) ); + } + + if ( 'completed' === $result['to'] ) { + $this->set_date_completed( current_time( 'timestamp' ) ); + } + } + + return $result; + } + + /** + * Updates status of order immediately. + * @uses WC_Order::set_status() + */ + public function update_status( $new_status, $note = '', $manual = false ) { + if ( ! $this->get_id() ) { + return false; + } + $this->set_status( $new_status, $note, $manual ); + $this->save(); + return true; + } + + /** + * Handle the status transition. + */ + protected function status_transition() { + if ( $this->_status_transition ) { + if ( ! empty( $this->_status_transition['from'] ) ) { + $transition_note = sprintf( __( 'Order status changed from %s to %s.', 'woocommerce' ), wc_get_order_status_name( $this->_status_transition['from'] ), wc_get_order_status_name( $this->_status_transition['to'] ) ); + + do_action( 'woocommerce_order_status_' . $this->_status_transition['from'] . '_to_' . $this->_status_transition['to'], $this->get_id() ); + do_action( 'woocommerce_order_status_changed', $this->get_id(), $this->_status_transition['from'], $this->_status_transition['to'] ); + } else { + $transition_note = sprintf( __( 'Order status set to %s.', 'woocommerce' ), wc_get_order_status_name( $this->_status_transition['to'] ) ); + } + + do_action( 'woocommerce_order_status_' . $this->_status_transition['to'], $this->get_id() ); + + // Note the transition occured + $this->add_order_note( trim( $this->_status_transition['note'] . ' ' . $transition_note ), 0, $this->_status_transition['manual'] ); + + // This has ran, so reset status transition variable + $this->_status_transition = false; + } + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + | + | Methods for getting data from the order object. + | + */ + + /** + * Get billing_first_name + * @return string + */ + public function get_billing_first_name() { + return $this->_data['billing']['first_name']; + } + + /** + * Get billing_last_name + * @return string + */ + public function get_billing_last_name() { + return $this->_data['billing']['last_name']; + } + + /** + * Get billing_company + * @return string + */ + public function get_billing_company() { + return $this->_data['billing']['company']; + } + + /** + * Get billing_address_1 + * @return string + */ + public function get_billing_address_1() { + return $this->_data['billing']['address_1']; + } + + /** + * Get billing_address_2 + * @return string $value + */ + public function get_billing_address_2() { + return $this->_data['billing']['address_2']; + } + + /** + * Get billing_city + * @return string $value + */ + public function get_billing_city() { + return $this->_data['billing']['city']; + } + + /** + * Get billing_state + * @return string + */ + public function get_billing_state() { + return $this->_data['billing']['state']; + } + + /** + * Get billing_postcode + * @return string + */ + public function get_billing_postcode() { + return $this->_data['billing']['postcode']; + } + + /** + * Get billing_country + * @return string + */ + public function get_billing_country() { + return $this->_data['billing']['country']; + } + + /** + * Get billing_email + * @return string + */ + public function get_billing_email() { + return sanitize_email( $this->_data['billing']['email'] ); + } + + /** + * Get billing_phone + * @return string + */ + public function get_billing_phone() { + return $this->_data['billing']['phone']; + } + + /** + * Get shipping_first_name + * @return string + */ + public function get_shipping_first_name() { + return $this->_data['shipping']['first_name']; + } + + /** + * Get shipping_last_name + * @return string + */ + public function get_shipping_last_name() { + return $this->_data['shipping']['last_name']; + } + + /** + * Get shipping_company + * @return string + */ + public function get_shipping_company() { + return $this->_data['shipping']['company']; + } + + /** + * Get shipping_address_1 + * @return string + */ + public function get_shipping_address_1() { + return $this->_data['shipping']['address_1']; + } + + /** + * Get shipping_address_2 + * @return string + */ + public function get_shipping_address_2() { + return $this->_data['shipping']['address_2']; + } + + /** + * Get shipping_city + * @return string + */ + public function get_shipping_city() { + return $this->_data['shipping']['city']; + } + + /** + * Get shipping_state + * @return string + */ + public function get_shipping_state() { + return $this->_data['shipping']['state']; + } + + /** + * Get shipping_postcode + * @return string + */ + public function get_shipping_postcode() { + return $this->_data['shipping']['postcode']; + } + + /** + * Get shipping_country + * @return string + */ + public function get_shipping_country() { + return $this->_data['shipping']['country']; + } + + /** + * Get the payment method. + * @return string + */ + public function get_payment_method() { + return $this->_data['payment_method']; + } + + /** + * Get payment_method_title + * @return string + */ + public function get_payment_method_title() { + return $this->_data['payment_method_title']; + } + + /** + * Get transaction_id + * @return string + */ + public function get_transaction_id() { + return $this->_data['transaction_id']; + } + + /** + * Get customer_ip_address + * @return string + */ + public function get_customer_ip_address() { + return $this->_data['customer_ip_address']; + } + + /** + * Get customer_user_agent + * @return string + */ + public function get_customer_user_agent() { + return $this->_data['customer_user_agent']; + } + + /** + * Get created_via + * @return string + */ + public function get_created_via() { + return $this->_data['created_via']; + } + + /** + * Get customer_note + * @return string + */ + public function get_customer_note() { + return $this->_data['customer_note']; + } + + /** + * Get date_completed + * @return int + */ + public function get_date_completed() { + return absint( $this->_data['date_completed'] ); + } + + /** + * Get date_paid + * @return int + */ + public function get_date_paid() { + return absint( $this->_data['date_paid'] ); + } + + /** + * Returns the requested address in raw, non-formatted way. + * @since 2.4.0 + * @param string $type Billing or shipping. Anything else besides 'billing' will return shipping address. + * @return array The stored address after filter. + */ + public function get_address( $type = 'billing' ) { + return apply_filters( 'woocommerce_get_order_address', isset( $this->_data[ $type ] ) ? $this->_data[ $type ] : array(), $type, $this ); + } + + /** + * Get a formatted shipping address for the order. + * + * @return string + */ + public function get_shipping_address_map_url() { + $address = apply_filters( 'woocommerce_shipping_address_map_url_parts', $this->get_address( 'shipping' ), $this ); + return apply_filters( 'woocommerce_shipping_address_map_url', 'http://maps.google.com/maps?&q=' . urlencode( implode( ', ', $address ) ) . '&z=16', $this ); + } + + /** + * Get a formatted billing full name. + * + * @since 2.4.0 + * + * @return string + */ + public function get_formatted_billing_full_name() { + return sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $this->get_billing_first_name(), $this->get_billing_last_name() ); + } + + /** + * Get a formatted shipping full name. + * + * @since 2.4.0 + * + * @return string + */ + public function get_formatted_shipping_full_name() { + return sprintf( _x( '%1$s %2$s', 'full name', 'woocommerce' ), $this->get_shipping_first_name(), $this->get_shipping_last_name() ); + } + + /** + * Get a formatted billing address for the order. + * @return string + */ + public function get_formatted_billing_address() { + return WC()->countries->get_formatted_address( apply_filters( 'woocommerce_order_formatted_billing_address', $this->get_address( 'billing' ), $this ) ); + } + + /** + * Get a formatted shipping address for the order. + * @return string + */ + public function get_formatted_shipping_address() { + if ( $this->get_shipping_address_1() || $this->get_shipping_address_2() ) { + return WC()->countries->get_formatted_address( apply_filters( 'woocommerce_order_formatted_shipping_address', $this->get_address( 'shipping' ), $this ) ); + } else { + return ''; + } + } + + /** + * Get cart hash + * @return string + */ + public function get_cart_hash() { + return $this->_data['cart_hash']; + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + | + | Functions for setting order data. These should not update anything in the + | database itself and should only change what is stored in the class + | object. However, for backwards compatibility pre 2.7.0 some of these + | setters may handle both. + | + */ + + /** + * Set billing_first_name + * @param string $value + */ + public function set_billing_first_name( $value ) { + $this->_data['billing']['first_name'] = $value; + } + + /** + * Set billing_last_name + * @param string $value + */ + public function set_billing_last_name( $value ) { + $this->_data['billing']['last_name'] = $value; + } + + /** + * Set billing_company + * @param string $value + */ + public function set_billing_company( $value ) { + $this->_data['billing']['company'] = $value; + } + + /** + * Set billing_address_1 + * @param string $value + */ + public function set_billing_address_1( $value ) { + $this->_data['billing']['address_1'] = $value; + } + + /** + * Set billing_address_2 + * @param string $value + */ + public function set_billing_address_2( $value ) { + $this->_data['billing']['address_2'] = $value; + } + + /** + * Set billing_city + * @param string $value + */ + public function set_billing_city( $value ) { + $this->_data['billing']['city'] = $value; + } + + /** + * Set billing_state + * @param string $value + */ + public function set_billing_state( $value ) { + $this->_data['billing']['state'] = $value; + } + + /** + * Set billing_postcode + * @param string $value + */ + public function set_billing_postcode( $value ) { + $this->_data['billing']['postcode'] = $value; + } + + /** + * Set billing_country + * @param string $value + */ + public function set_billing_country( $value ) { + $this->_data['billing']['country'] = $value; + } + + /** + * Set billing_email + * @param string $value + */ + public function set_billing_email( $value ) { + $value = sanitize_email( $value ); + $this->_data['billing']['email'] = is_email( $value ) ? $value : ''; + } + + /** + * Set billing_phone + * @param string $value + */ + public function set_billing_phone( $value ) { + $this->_data['billing']['phone'] = $value; + } + + /** + * Set shipping_first_name + * @param string $value + */ + public function set_shipping_first_name( $value ) { + $this->_data['shipping']['first_name'] = $value; + } + + /** + * Set shipping_last_name + * @param string $value + */ + public function set_shipping_last_name( $value ) { + $this->_data['shipping']['last_name'] = $value; + } + + /** + * Set shipping_company + * @param string $value + */ + public function set_shipping_company( $value ) { + $this->_data['shipping']['company'] = $value; + } + + /** + * Set shipping_address_1 + * @param string $value + */ + public function set_shipping_address_1( $value ) { + $this->_data['shipping']['address_1'] = $value; + } + + /** + * Set shipping_address_2 + * @param string $value + */ + public function set_shipping_address_2( $value ) { + $this->_data['shipping']['address_2'] = $value; + } + + /** + * Set shipping_city + * @param string $value + */ + public function set_shipping_city( $value ) { + $this->_data['shipping']['city'] = $value; + } + + /** + * Set shipping_state + * @param string $value + */ + public function set_shipping_state( $value ) { + $this->_data['shipping']['state'] = $value; + } + + /** + * Set shipping_postcode + * @param string $value + */ + public function set_shipping_postcode( $value ) { + $this->_data['shipping']['postcode'] = $value; + } + + /** + * Set shipping_country + * @param string $value + */ + public function set_shipping_country( $value ) { + $this->_data['shipping']['country'] = $value; + } + + /** + * Set the payment method. + * @since 2.2.0 + * @param string $payment_method Supports WC_Payment_Gateway for bw compatibility with < 2.7 + */ + public function set_payment_method( $payment_method = '' ) { + if ( is_object( $payment_method ) ) { + $this->set_payment_method( $payment_method->id ); + $this->set_payment_method_title( $payment_method->get_title() ); + } elseif ( '' === $payment_method ) { + $this->_data['payment_method'] = ''; + $this->_data['payment_method_title'] = ''; + } else { + $this->_data['payment_method'] = $payment_method; + } + } + + /** + * Set payment_method_title + * @param string $value + */ + public function set_payment_method_title( $value ) { + $this->_data['payment_method_title'] = $value; + } + + /** + * Set transaction_id + * @param string $value + */ + public function set_transaction_id( $value ) { + $this->_data['transaction_id'] = $value; + } + + /** + * Set customer_ip_address + * @param string $value + */ + public function set_customer_ip_address( $value ) { + $this->_data['customer_ip_address'] = $value; + } + + /** + * Set customer_user_agent + * @param string $value + */ + public function set_customer_user_agent( $value ) { + $this->_data['customer_user_agent'] = $value; + } + + /** + * Set created_via + * @param string $value + */ + public function set_created_via( $value ) { + $this->_data['created_via'] = $value; + } + + /** + * Set customer_note + * @param string $value + */ + public function set_customer_note( $value ) { + $this->_data['customer_note'] = $value; + } + + /** + * Set date_completed + * @param string $timestamp + */ + public function set_date_completed( $timestamp ) { + $this->_data['date_completed'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp ); + } + + /** + * Set date_paid + * @param string $timestamp + */ + public function set_date_paid( $timestamp ) { + $this->_data['date_paid'] = is_numeric( $timestamp ) ? $timestamp : strtotime( $timestamp ); + } + + /** + * Set cart hash + * @param string $value + */ + public function set_cart_hash( $value ) { + $this->_data['cart_hash'] = $value; + } + + /* + |-------------------------------------------------------------------------- + | Conditionals + |-------------------------------------------------------------------------- + | + | Checks if a condition is true or false. + | + */ + + /** + * See if order matches cart_hash. + * @return bool + */ + public function has_cart_hash( $cart_hash ) { + return hash_equals( $this->get_cart_hash(), $cart_hash ); + } + + /** + * Checks if an order can be edited, specifically for use on the Edit Order screen. + * @return bool + */ + public function is_editable() { + return apply_filters( 'wc_order_is_editable', in_array( $this->get_status(), array( 'pending', 'on-hold', 'auto-draft' ) ), $this ); + } + + /** + * Returns if an order has been paid for based on the order status. + * @since 2.5.0 + * @return bool + */ + public function is_paid() { + return apply_filters( 'woocommerce_order_is_paid', $this->has_status( apply_filters( 'woocommerce_order_is_paid_statuses', array( 'processing', 'completed' ) ) ), $this ); + } + + /** + * Checks if product download is permitted. + * + * @return bool + */ + public function is_download_permitted() { + return apply_filters( 'woocommerce_order_is_download_permitted', $this->has_status( 'completed' ) || ( 'yes' === get_option( 'woocommerce_downloads_grant_access_after_payment' ) && $this->has_status( 'processing' ) ), $this ); + } + + /** + * Checks if an order needs display the shipping address, based on shipping method. + * @return bool + */ + public function needs_shipping_address() { + if ( 'no' === get_option( 'woocommerce_calc_shipping' ) ) { + return false; + } + + $hide = apply_filters( 'woocommerce_order_hide_shipping_address', array( 'local_pickup' ), $this ); + $needs_address = false; + + foreach ( $this->get_shipping_methods() as $shipping_method ) { + if ( ! in_array( $shipping_method['method_id'], $hide ) ) { + $needs_address = true; + break; + } + } + + return apply_filters( 'woocommerce_order_needs_shipping_address', $needs_address, $hide, $this ); + } + + /** + * Returns true if the order contains a downloadable product. + * @return bool + */ + public function has_downloadable_item() { + foreach ( $this->get_items() as $item ) { + if ( $item->is_type( 'line_item' ) && ( $product = $item->get_product() ) && $product->is_downloadable() && $product->has_file() ) { + return true; + } + } + return false; + } + + /** + * Checks if an order needs payment, based on status and order total. + * + * @return bool + */ + public function needs_payment() { + $valid_order_statuses = apply_filters( 'woocommerce_valid_order_statuses_for_payment', array( 'pending', 'failed' ), $this ); + return apply_filters( 'woocommerce_order_needs_payment', ( $this->has_status( $valid_order_statuses ) && $this->get_total() > 0 ), $this, $valid_order_statuses ); + } + + /* + |-------------------------------------------------------------------------- + | URLs and Endpoints + |-------------------------------------------------------------------------- + */ + + /** + * Generates a URL so that a customer can pay for their (unpaid - pending) order. Pass 'true' for the checkout version which doesn't offer gateway choices. + * + * @param bool $on_checkout + * @return string + */ + public function get_checkout_payment_url( $on_checkout = false ) { + $pay_url = wc_get_endpoint_url( 'order-pay', $this->get_id(), wc_get_page_permalink( 'checkout' ) ); + + if ( 'yes' == get_option( 'woocommerce_force_ssl_checkout' ) || is_ssl() ) { + $pay_url = str_replace( 'http:', 'https:', $pay_url ); + } + + if ( $on_checkout ) { + $pay_url = add_query_arg( 'key', $this->get_order_key(), $pay_url ); + } else { + $pay_url = add_query_arg( array( 'pay_for_order' => 'true', 'key' => $this->get_order_key() ), $pay_url ); + } + + return apply_filters( 'woocommerce_get_checkout_payment_url', $pay_url, $this ); + } + + /** + * Generates a URL for the thanks page (order received). + * + * @return string + */ + public function get_checkout_order_received_url() { + $order_received_url = wc_get_endpoint_url( 'order-received', $this->get_id(), wc_get_page_permalink( 'checkout' ) ); + + if ( 'yes' === get_option( 'woocommerce_force_ssl_checkout' ) || is_ssl() ) { + $order_received_url = str_replace( 'http:', 'https:', $order_received_url ); + } + + $order_received_url = add_query_arg( 'key', $this->get_order_key(), $order_received_url ); + + return apply_filters( 'woocommerce_get_checkout_order_received_url', $order_received_url, $this ); + } + + /** + * Generates a URL so that a customer can cancel their (unpaid - pending) order. + * + * @param string $redirect + * + * @return string + */ + public function get_cancel_order_url( $redirect = '' ) { + return apply_filters( 'woocommerce_get_cancel_order_url', wp_nonce_url( add_query_arg( array( + 'cancel_order' => 'true', + 'order' => $this->get_order_key(), + 'order_id' => $this->get_id(), + 'redirect' => $redirect + ), $this->get_cancel_endpoint() ), 'woocommerce-cancel_order' ) ); + } + + /** + * Generates a raw (unescaped) cancel-order URL for use by payment gateways. + * + * @param string $redirect + * + * @return string The unescaped cancel-order URL. + */ + public function get_cancel_order_url_raw( $redirect = '' ) { + return apply_filters( 'woocommerce_get_cancel_order_url_raw', add_query_arg( array( + 'cancel_order' => 'true', + 'order' => $this->get_order_key(), + 'order_id' => $this->get_id(), + 'redirect' => $redirect, + '_wpnonce' => wp_create_nonce( 'woocommerce-cancel_order' ) + ), $this->get_cancel_endpoint() ) ); + } + + /** + * Helper method to return the cancel endpoint. + * + * @return string the cancel endpoint; either the cart page or the home page. + */ + public function get_cancel_endpoint() { + $cancel_endpoint = wc_get_page_permalink( 'cart' ); + if ( ! $cancel_endpoint ) { + $cancel_endpoint = home_url(); + } + + if ( false === strpos( $cancel_endpoint, '?' ) ) { + $cancel_endpoint = trailingslashit( $cancel_endpoint ); + } + + return $cancel_endpoint; + } + + /** + * Generates a URL to view an order from the my account page. + * + * @return string + */ + public function get_view_order_url() { + return apply_filters( 'woocommerce_get_view_order_url', wc_get_endpoint_url( 'view-order', $this->get_id(), wc_get_page_permalink( 'myaccount' ) ), $this ); + } + + /* + |-------------------------------------------------------------------------- + | Order notes. + |-------------------------------------------------------------------------- + */ + + /** + * Adds a note (comment) to the order. + * + * @param string $note Note to add. + * @param int $is_customer_note (default: 0) Is this a note for the customer? + * @param bool added_by_user Was the note added by a user? + * @return int Comment ID. + */ + public function add_order_note( $note, $is_customer_note = 0, $added_by_user = false ) { + if ( is_user_logged_in() && current_user_can( 'edit_shop_order', $this->get_id() ) && $added_by_user ) { + $user = get_user_by( 'id', get_current_user_id() ); + $comment_author = $user->display_name; + $comment_author_email = $user->user_email; + } else { + $comment_author = __( 'WooCommerce', 'woocommerce' ); + $comment_author_email = strtolower( __( 'WooCommerce', 'woocommerce' ) ) . '@'; + $comment_author_email .= isset( $_SERVER['HTTP_HOST'] ) ? str_replace( 'www.', '', $_SERVER['HTTP_HOST'] ) : 'noreply.com'; + $comment_author_email = sanitize_email( $comment_author_email ); + } + $commentdata = apply_filters( 'woocommerce_new_order_note_data', array( + 'comment_post_ID' => $this->get_id(), + 'comment_author' => $comment_author, + 'comment_author_email' => $comment_author_email, + 'comment_author_url' => '', + 'comment_content' => $note, + 'comment_agent' => 'WooCommerce', + 'comment_type' => 'order_note', + 'comment_parent' => 0, + 'comment_approved' => 1, + ), array( 'order_id' => $this->get_id(), 'is_customer_note' => $is_customer_note ) ); + + $comment_id = wp_insert_comment( $commentdata ); + + if ( $is_customer_note ) { + add_comment_meta( $comment_id, 'is_customer_note', 1 ); + + do_action( 'woocommerce_new_customer_note', array( 'order_id' => $this->get_id(), 'customer_note' => $commentdata['comment_content'] ) ); + } + + return $comment_id; + } + + /** + * List order notes (public) for the customer. + * + * @return array + */ + public function get_customer_order_notes() { + $notes = array(); + $args = array( + 'post_id' => $this->get_id(), + 'approve' => 'approve', + 'type' => '' + ); + + remove_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ) ); + + $comments = get_comments( $args ); + + foreach ( $comments as $comment ) { + if ( ! get_comment_meta( $comment->comment_ID, 'is_customer_note', true ) ) { + continue; + } + $comment->comment_content = make_clickable( $comment->comment_content ); + $notes[] = $comment; + } + + add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_order_comments' ) ); + + return $notes; + } + + /* + |-------------------------------------------------------------------------- + | Refunds + |-------------------------------------------------------------------------- + */ + /** * Get order refunds. * @since 2.2 * @return array of WC_Order_Refund objects */ public function get_refunds() { - if ( empty( $this->refunds ) && ! is_array( $this->refunds ) ) { + if ( empty( $this->refunds ) || ! is_array( $this->refunds ) ) { $this->refunds = wc_get_orders( array( 'type' => 'shop_order_refund', - 'parent' => $this->id, + 'parent' => $this->get_id(), 'limit' => -1, ) ); } @@ -87,7 +1294,7 @@ class WC_Order extends WC_Abstract_Order { INNER JOIN $wpdb->posts AS posts ON ( posts.post_type = 'shop_order_refund' AND posts.post_parent = %d ) WHERE postmeta.meta_key = '_refund_amount' AND postmeta.post_id = posts.ID - ", $this->id ) ); + ", $this->get_id() ) ); return $total; } @@ -108,7 +1315,7 @@ class WC_Order extends WC_Abstract_Order { INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON ( order_items.order_id = posts.ID AND order_items.order_item_type = 'tax' ) WHERE order_itemmeta.order_item_id = order_items.order_item_id AND order_itemmeta.meta_key IN ('tax_amount', 'shipping_tax_amount') - ", $this->id ) ); + ", $this->get_id() ) ); return abs( $total ); } @@ -129,7 +1336,7 @@ class WC_Order extends WC_Abstract_Order { INNER JOIN {$wpdb->prefix}woocommerce_order_items AS order_items ON ( order_items.order_id = posts.ID AND order_items.order_item_type = 'shipping' ) WHERE order_itemmeta.order_item_id = order_items.order_item_id AND order_itemmeta.meta_key IN ('cost') - ", $this->id ) ); + ", $this->get_id() ) ); return abs( $total ); } @@ -151,7 +1358,7 @@ class WC_Order extends WC_Abstract_Order { foreach ( $this->get_refunds() as $refund ) { foreach ( $refund->get_items( $item_type ) as $refunded_item ) { - $count += empty( $refunded_item['qty'] ) ? 0 : $refunded_item['qty']; + $count += $refunded_item->get_qty(); } } @@ -169,7 +1376,7 @@ class WC_Order extends WC_Abstract_Order { $qty = 0; foreach ( $this->get_refunds() as $refund ) { foreach ( $refund->get_items( $item_type ) as $refunded_item ) { - $qty += $refunded_item['qty']; + $qty += $refunded_item->get_qty(); } } return $qty; @@ -186,8 +1393,8 @@ class WC_Order extends WC_Abstract_Order { $qty = 0; foreach ( $this->get_refunds() as $refund ) { foreach ( $refund->get_items( $item_type ) as $refunded_item ) { - if ( isset( $refunded_item['refunded_item_id'] ) && $refunded_item['refunded_item_id'] == $item_id ) { - $qty += $refunded_item['qty']; + if ( absint( $refunded_item->get_meta( '_refunded_item_id' ) ) === $item_id ) { + $qty += $refunded_item->get_qty(); } } } @@ -205,15 +1412,8 @@ class WC_Order extends WC_Abstract_Order { $total = 0; foreach ( $this->get_refunds() as $refund ) { foreach ( $refund->get_items( $item_type ) as $refunded_item ) { - if ( isset( $refunded_item['refunded_item_id'] ) && $refunded_item['refunded_item_id'] == $item_id ) { - switch ( $item_type ) { - case 'shipping' : - $total += $refunded_item['cost']; - break; - default : - $total += $refunded_item['line_total']; - break; - } + if ( absint( $refunded_item->get_meta( '_refunded_item_id' ) ) === $item_id ) { + $total += $refunded_item->get_total(); } } } @@ -232,21 +1432,8 @@ class WC_Order extends WC_Abstract_Order { $total = 0; foreach ( $this->get_refunds() as $refund ) { foreach ( $refund->get_items( $item_type ) as $refunded_item ) { - if ( isset( $refunded_item['refunded_item_id'] ) && $refunded_item['refunded_item_id'] == $item_id ) { - switch ( $item_type ) { - case 'shipping' : - $tax_data = maybe_unserialize( $refunded_item['taxes'] ); - if ( isset( $tax_data[ $tax_id ] ) ) { - $total += $tax_data[ $tax_id ]; - } - break; - default : - $tax_data = maybe_unserialize( $refunded_item['line_tax_data'] ); - if ( isset( $tax_data['total'][ $tax_id ] ) ) { - $total += $tax_data['total'][ $tax_id ]; - } - break; - } + if ( absint( $refunded_item->get_meta( '_refunded_item_id' ) ) === $item_id ) { + $total += $refunded_item->get_total_tax(); } } } @@ -264,8 +1451,8 @@ class WC_Order extends WC_Abstract_Order { $total = 0; foreach ( $this->get_refunds() as $refund ) { foreach ( $refund->get_items( 'tax' ) as $refunded_item ) { - if ( isset( $refunded_item['rate_id'] ) && $refunded_item['rate_id'] == $rate_id ) { - $total += abs( $refunded_item['tax_amount'] ) + abs( $refunded_item['shipping_tax_amount'] ); + if ( absint( $refunded_item->get_rate_id() ) === $rate_id ) { + $total += abs( $refunded_item->tax_total() ) + abs( $refunded_item->shipping_tax_total() ); } } } From f70e05441b5a53fa6341b1523769da176e694868 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 21 Jun 2016 20:06:56 +0100 Subject: [PATCH 009/298] refund class --- includes/class-wc-order-refund.php | 204 ++++++++++++++++++++--------- 1 file changed, 141 insertions(+), 63 deletions(-) diff --git a/includes/class-wc-order-refund.php b/includes/class-wc-order-refund.php index b3ab4ce106e..bb03580bdee 100644 --- a/includes/class-wc-order-refund.php +++ b/includes/class-wc-order-refund.php @@ -1,113 +1,191 @@ _data = array_merge( $this->_data, array( + 'refund_amount' => '', + 'refund_reason' => '', + 'refunded_by' => 0, + ) ); + parent::__construct( $order ); + } /** - * Init/load the refund object. Called from the constructor. - * - * @param string|int|object|WC_Order_Refund $refund Refund to init - * @uses WP_POST + * Insert data into the database. + * @since 2.7.0 */ - protected function init( $refund ) { - if ( is_numeric( $refund ) ) { - $this->id = absint( $refund ); - $this->post = get_post( $refund ); - $this->get_refund( $this->id ); - } elseif ( $refund instanceof WC_Order_Refund ) { - $this->id = absint( $refund->id ); - $this->post = $refund->post; - $this->get_refund( $this->id ); - } elseif ( isset( $refund->ID ) ) { - $this->id = absint( $refund->ID ); - $this->post = $refund; - $this->get_refund( $this->id ); + public function create() { + parent::create(); + + // Store additonal order data + if ( $this->get_id() ) { + $this->update_post_meta( '_refund_amount', $this->get_refund_amount() ); + $this->update_post_meta( '_refunded_by', $this->get_refunded_by() ); + $this->update_post_meta( '_refund_reason', $this->get_refund_reason() ); } } /** - * Gets an refund from the database. - * - * @since 2.2 - * @param int $id - * @return bool - */ - public function get_refund( $id = 0 ) { - if ( ! $id ) { - return false; + * Read from the database. + * @since 2.7.0 + * @param int $id ID of object to read. + */ + public function read( $id ) { + parent::read( $id ); + + // Read additonal order data + if ( $this->get_id() ) { + $post_object = get_post( $id ); + $this->set_refund_amount( get_post_meta( $this->get_id(), '_refund_amount', true ) ); + + // post_author was used before refunded_by meta. + $this->set_refunded_by( metadata_exists( 'post', $this->get_id(), '_refunded_by' ) ? get_post_meta( $this->get_id(), '_refunded_by', true ) : absint( $post_object->post_author ) ); + + // post_excerpt was used before refund_reason meta. + $this->set_refund_reason( metadata_exists( 'post', $this->get_id(), '_refund_reason' ) ? get_post_meta( $this->get_id(), '_refund_reason', true ) : absint( $post_object->post_excerpt ) ); } - - if ( $result = get_post( $id ) ) { - $this->populate( $result ); - - return true; - } - - return false; } /** - * Populates an refund from the loaded post data. - * - * @param mixed $result + * Update data in the database. + * @since 2.7.0 */ - public function populate( $result ) { - // Standard post data - $this->id = $result->ID; - $this->date = $result->post_date; - $this->modified_date = $result->post_modified; - $this->reason = $result->post_excerpt; + public function update() { + parent::update(); + + // Store additonal order data + $this->update_post_meta( '_refund_amount', $this->get_refund_amount() ); + $this->update_post_meta( '_refunded_by', $this->get_refunded_by() ); + $this->update_post_meta( '_refund_reason', $this->get_refund_reason() ); + } + + /** + * Get internal type (post type.) + * @return string + */ + public function get_type() { + return 'shop_order_refund'; + } + + /** + * Get a title for the new post type. + */ + protected function get_post_title() { + return sprintf( __( 'Refund – %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ) ) ); + } + + /** + * Set refunded amount. + * @param string $value + */ + public function set_refund_amount( $value ) { + $this->_data['refund_amount'] = wc_format_decimal( $value ); } /** * Get refunded amount. - * * @since 2.2 * @return int|float */ public function get_refund_amount() { - return apply_filters( 'woocommerce_refund_amount', (double) $this->refund_amount, $this ); + return apply_filters( 'woocommerce_refund_amount', (double) $this->_data['refund_amount'], $this ); } /** * Get formatted refunded amount. - * * @since 2.4 * @return string */ public function get_formatted_refund_amount() { - return apply_filters( 'woocommerce_formatted_refund_amount', wc_price( $this->refund_amount, array('currency' => $this->get_order_currency()) ), $this ); + return apply_filters( 'woocommerce_formatted_refund_amount', wc_price( $this->get_refund_amount(), array( 'currency' => $this->get_currency() ) ), $this ); } + /** + * Set refund reason. + * @param string $value + */ + public function set_refund_reason( $value ) { + $this->_data['refund_reason'] = $value; + } /** - * Get refunded amount. - * + * Get refund reason. * @since 2.2 * @return int|float */ public function get_refund_reason() { - return apply_filters( 'woocommerce_refund_reason', $this->reason, $this ); + return apply_filters( 'woocommerce_refund_reason', $this->_data['refund_reason'], $this ); } + + /** + * Set refunded by. + * @param int $value + */ + public function set_refunded_by( $value ) { + $this->_data['refunded_by'] = absint( $value ); + } + + /** + * Get ID of user who did the refund. + * @since 2.7 + * @return int + */ + public function get_refunded_by() { + return absint( $this->_data['refunded_by'] ); + } + + /** + * Magic __get method for backwards compatibility. + * @param string $key + * @return mixed + */ + public function __get( $key ) { + _doing_it_wrong( $key, 'Refund properties should not be accessed directly.', '2.7' ); + + /** + * Maps legacy vars to new getters. + */ + if ( 'reason' === $key ) { + return $this->get_refund_reason(); + } elseif ( 'refund_amount' === $key ) { + return $this->get_refund_amount(); + } + return parent::__get( $key ); + } + + /** + * Gets an refund from the database. + * @deprecated 2.7 + * @param int $id (default: 0). + * @return bool + */ + public function get_refund( $id = 0 ) { + _deprecated_function( 'get_refund', '2.7', 'read' ); + if ( ! $id ) { + return false; + } + if ( $result = get_post( $id ) ) { + $this->populate( $result ); + return true; + } + return false; + } } From aa7f6a6cf7ed3185aa249176f84f1f455a39958f Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 21 Jun 2016 20:07:31 +0100 Subject: [PATCH 010/298] Factory --- includes/class-wc-order-factory.php | 51 +++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/includes/class-wc-order-factory.php b/includes/class-wc-order-factory.php index 530104be857..c5da64f000b 100644 --- a/includes/class-wc-order-factory.php +++ b/includes/class-wc-order-factory.php @@ -10,7 +10,7 @@ if ( ! defined( 'ABSPATH' ) ) { * The WooCommerce order factory creating the right order objects. * * @class WC_Order_Factory - * @version 2.2.0 + * @version 2.7.0 * @package WooCommerce/Classes * @category Class * @author WooThemes @@ -23,7 +23,7 @@ class WC_Order_Factory { * @param bool $the_order (default: false) * @return WC_Order|bool */ - public function get_order( $the_order = false ) { + public static function get_order( $the_order = false ) { global $post; if ( false === $the_order ) { @@ -31,7 +31,7 @@ class WC_Order_Factory { } elseif ( is_numeric( $the_order ) ) { $the_order = get_post( $the_order ); } elseif ( $the_order instanceof WC_Order ) { - $the_order = get_post( $the_order->id ); + $the_order = get_post( $the_order->get_id() ); } if ( ! $the_order || ! is_object( $the_order ) ) { @@ -56,4 +56,49 @@ class WC_Order_Factory { return new $classname( $the_order ); } + + /** + * Get order item. + * @param int + * @return WC_Order_Item + */ + public static function get_order_item( $item_id = 0 ) { + global $wpdb; + + if ( is_numeric( $item_id ) ) { + $item_data = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d LIMIT 1;", $item_id ) ); + $item_type = $item_data->order_item_type; + } elseif ( $item_id instanceof WC_Order_Item ) { + $item_data = $item_id->get_data(); + $item_type = $item_data->get_type(); + } elseif( is_object( $item_id ) && ! empty( $item_id->order_item_type ) ) { + $item_data = $item_id; + $item_type = $item_id->order_item_type; + } else { + $item_data = false; + $item_type = false; + } + + if ( $item_data && $item_type ) { + switch ( $item_type ) { + case 'line_item' : + case 'product' : + return new WC_Order_Item_Product( $item_data ); + break; + case 'coupon' : + return new WC_Order_Item_Coupon( $item_data ); + break; + case 'fee' : + return new WC_Order_Item_Fee( $item_data ); + break; + case 'shipping' : + return new WC_Order_Item_Shipping( $item_data ); + break; + case 'tax' : + return new WC_Order_Item_Tax( $item_data ); + break; + } + } + return new WC_Order_Item(); + } } From a1adf0cf7855bd32eb6d83d25c8e959f4f9e2b68 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 21 Jun 2016 20:10:09 +0100 Subject: [PATCH 011/298] Order item classes --- includes/class-wc-order-item-coupon.php | 187 ++++++++++ includes/class-wc-order-item-fee.php | 231 ++++++++++++ includes/class-wc-order-item-meta.php | 5 +- includes/class-wc-order-item-product.php | 402 +++++++++++++++++++++ includes/class-wc-order-item-shipping.php | 233 ++++++++++++ includes/class-wc-order-item-tax.php | 210 +++++++++++ includes/class-wc-order-item.php | 412 ++++++++++++++++++++++ 7 files changed, 1677 insertions(+), 3 deletions(-) create mode 100644 includes/class-wc-order-item-coupon.php create mode 100644 includes/class-wc-order-item-fee.php create mode 100644 includes/class-wc-order-item-product.php create mode 100644 includes/class-wc-order-item-shipping.php create mode 100644 includes/class-wc-order-item-tax.php create mode 100644 includes/class-wc-order-item.php diff --git a/includes/class-wc-order-item-coupon.php b/includes/class-wc-order-item-coupon.php new file mode 100644 index 00000000000..8229ed18dde --- /dev/null +++ b/includes/class-wc-order-item-coupon.php @@ -0,0 +1,187 @@ + 0, + 'order_item_id' => 0, + 'code' => '', + 'discount' => 0, + 'discount_tax' => 0, + ); + + /** + * offsetGet for ArrayAccess/Backwards compatibility. + * @deprecated Add deprecation notices in future release. + * @param string $offset + * @return mixed + */ + public function offsetGet( $offset ) { + if ( 'discount_amount' === $offset ) { + $offset = 'discount'; + } elseif ( 'discount_amount_tax' === $offset ) { + $offset = 'discount_tax'; + } + return parent::offsetGet( $offset ); + } + + /** + * offsetSet for ArrayAccess/Backwards compatibility. + * @deprecated Add deprecation notices in future release. + * @param string $offset + * @param mixed $value + */ + public function offsetSet( $offset, $value ) { + if ( 'discount_amount' === $offset ) { + $offset = 'discount'; + } elseif ( 'discount_amount_tax' === $offset ) { + $offset = 'discount_tax'; + } + parent::offsetSet( $offset, $value ); + } + + /** + * offsetExists for ArrayAccess + * @param string $offset + * @return bool + */ + public function offsetExists( $offset ) { + if ( in_array( $offset, array( 'discount_amount', 'discount_amount_tax' ) ) ) { + return true; + } + return parent::offsetExists( $offset ); + } + + /** + * Read/populate data properties specific to this order item. + */ + public function read( $id ) { + parent::read( $id ); + if ( $this->get_id() ) { + $this->set_discount( get_metadata( 'order_item', $this->get_id(), 'discount_amount', true ) ); + $this->set_discount_tax( get_metadata( 'order_item', $this->get_id(), 'discount_amount_tax', true ) ); + } + } + + /** + * Save properties specific to this order item. + * @return int Item ID + */ + public function save() { + parent::save(); + if ( $this->get_id() ) { + wc_update_order_item_meta( $this->get_id(), 'discount_amount', $this->get_discount() ); + wc_update_order_item_meta( $this->get_id(), 'discount_amount_tax', $this->get_discount_tax() ); + } + + return $this->get_id(); + } + + /** + * Internal meta keys we don't want exposed as part of meta_data. + * @return array() + */ + protected function get_internal_meta_keys() { + return array( 'discount_amount', 'discount_amount_tax' ); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set order item name. + * @param string $value + */ + public function set_name( $value ) { + $this->set_code( $value ); + } + + /** + * Set code. + * @param string $value + */ + public function set_code( $value ) { + $this->_data['code'] = wc_clean( $value ); + } + + /** + * Set discount amount. + * @param string $value + */ + public function set_discount( $value ) { + $this->_data['discount'] = wc_format_decimal( $value ); + } + + /** + * Set discounted tax amount. + * @param string $value + */ + public function set_discount_tax( $value ) { + $this->_data['discount_tax'] = wc_format_decimal( $value ); + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get order item type. + * @return string + */ + public function get_type() { + return 'coupon'; + } + + /** + * Get order item name. + * @return string + */ + public function get_name() { + return $this->get_code(); + } + + /** + * Get coupon code. + * @return string + */ + public function get_code() { + return $this->_data['code']; + } + + /** + * Get discount amount. + * @return string + */ + public function get_discount() { + return wc_format_decimal( $this->_data['discount'] ); + } + + /** + * Get discounted tax amount. + * @return string + */ + public function get_discount_tax() { + return wc_format_decimal( $this->_data['discount_tax'] ); + } +} diff --git a/includes/class-wc-order-item-fee.php b/includes/class-wc-order-item-fee.php new file mode 100644 index 00000000000..47332d6b64f --- /dev/null +++ b/includes/class-wc-order-item-fee.php @@ -0,0 +1,231 @@ + 0, + 'order_item_id' => 0, + 'name' => '', + 'tax_class' => '', + 'tax_status' => 'taxable', + 'total' => '', + 'total_tax' => '', + 'taxes' => array( + 'total' => array() + ) + ); + + /** + * offsetGet for ArrayAccess/Backwards compatibility. + * @deprecated Add deprecation notices in future release. + * @param string $offset + * @return mixed + */ + public function offsetGet( $offset ) { + if ( 'line_total' === $offset ) { + $offset = 'total'; + } elseif ( 'line_tax' === $offset ) { + $offset = 'total_tax'; + } elseif ( 'line_tax_data' === $offset ) { + $offset = 'taxes'; + } + return parent::offsetGet( $offset ); + } + + /** + * offsetSet for ArrayAccess/Backwards compatibility. + * @deprecated Add deprecation notices in future release. + * @param string $offset + * @param mixed $value + */ + public function offsetSet( $offset, $value ) { + if ( 'line_total' === $offset ) { + $offset = 'total'; + } elseif ( 'line_tax' === $offset ) { + $offset = 'total_tax'; + } elseif ( 'line_tax_data' === $offset ) { + $offset = 'taxes'; + } + parent::offsetSet( $offset, $value ); + } + + /** + * offsetExists for ArrayAccess + * @param string $offset + * @return bool + */ + public function offsetExists( $offset ) { + if ( in_array( $offset, array( 'line_total', 'line_tax', 'line_tax_data' ) ) ) { + return true; + } + return parent::offsetExists( $offset ); + } + + /** + * Read/populate data properties specific to this order item. + */ + public function read( $id ) { + parent::read( $id ); + if ( $this->get_id() ) { + $this->set_tax_class( get_metadata( 'order_item', $this->get_id(), '_tax_class', true ) ); + $this->set_tax_status( get_metadata( 'order_item', $this->get_id(), '_tax_status', true ) ); + $this->set_total( get_metadata( 'order_item', $this->get_id(), '_line_total', true ) ); + $this->set_total_tax( get_metadata( 'order_item', $this->get_id(), '_line_tax', true ) ); + $this->set_taxes( get_metadata( 'order_item', $this->get_id(), '_line_tax_data', true ) ); + } + } + + /** + * Save properties specific to this order item. + * @return int Item ID + */ + public function save() { + parent::save(); + if ( $this->get_id() ) { + wc_update_order_item_meta( $this->get_id(), '_tax_class', $this->get_tax_class() ); + wc_update_order_item_meta( $this->get_id(), '_tax_status', $this->get_tax_status() ); + wc_update_order_item_meta( $this->get_id(), '_line_total', $this->get_total() ); + wc_update_order_item_meta( $this->get_id(), '_line_tax', $this->get_total_tax() ); + wc_update_order_item_meta( $this->get_id(), '_line_tax_data', $this->get_taxes() ); + } + + return $this->get_id(); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set tax class. + * @param string $value + */ + public function set_tax_class( $value ) { + $this->_data['tax_class'] = $value; + } + + /** + * Set tax_status. + * @param string $value + */ + public function set_tax_status( $value ) { + if ( in_array( $value, array( 'taxable', 'none' ) ) ) { + $this->_data['tax_status'] = $value; + } else { + $this->_data['tax_status'] = 'taxable'; + } + } + + /** + * Set total. + * @param string $value + */ + public function set_total( $value ) { + $this->_data['total'] = wc_format_decimal( $value ); + } + + /** + * Set total tax. + * @param string $value + */ + public function set_total_tax( $value ) { + $this->_data['total_tax'] = wc_format_decimal( $value ); + } + + /** + * Set taxes. + * + * This is an array of tax ID keys with total amount values. + * @param array $raw_tax_data + */ + public function set_taxes( $raw_tax_data ) { + $raw_tax_data = maybe_unserialize( $raw_tax_data ); + $tax_data = array( + 'total' => array(), + ); + if ( ! empty( $raw_tax_data['total'] ) ) { + $tax_data['total'] = array_map( 'wc_format_decimal', $raw_tax_data['total'] ); + } + $this->_data['taxes'] = $tax_data; + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get order item name. + * @return string + */ + public function get_name() { + return $this->_data['name'] ? $this->_data['name'] : __( 'Fee', 'woocommerce' ); + } + + /** + * Get order item type. + * @return string + */ + public function get_type() { + return 'fee'; + } + + /** + * Get tax class. + * @return string + */ + public function get_tax_class() { + return $this->_data['tax_class']; + } + + /** + * Get tax status. + * @return string + */ + public function get_tax_status() { + return $this->_data['tax_status']; + } + + /** + * Get total fee. + * @return string + */ + public function get_total() { + return wc_format_decimal( $this->_data['total'] ); + } + + /** + * Get total tax. + * @return string + */ + public function get_total_tax() { + return wc_format_decimal( $this->_data['total_tax'] ); + } + + /** + * Get fee taxes. + * @return array + */ + public function get_taxes() { + return $this->_data['taxes']; + } +} diff --git a/includes/class-wc-order-item-meta.php b/includes/class-wc-order-item-meta.php index aef65beaddf..c20cc28f30b 100644 --- a/includes/class-wc-order-item-meta.php +++ b/includes/class-wc-order-item-meta.php @@ -1,7 +1,6 @@ meta = array_filter( (array) $item ); return; } - $this->item = $item; $this->meta = array_filter( (array) $item['item_meta'] ); $this->product = $product; diff --git a/includes/class-wc-order-item-product.php b/includes/class-wc-order-item-product.php new file mode 100644 index 00000000000..a9dbd58f973 --- /dev/null +++ b/includes/class-wc-order-item-product.php @@ -0,0 +1,402 @@ + 0, + 'order_item_id' => 0, + 'name' => '', + 'product_id' => 0, + 'variation_id' => 0, + 'qty' => 0, + 'tax_class' => '', + 'subtotal' => 0, + 'subtotal_tax' => 0, + 'total' => 0, + 'total_tax' => 0, + 'taxes' => array( + 'subtotal' => array(), + 'total' => array() + ), + ); + + /** + * offsetGet for ArrayAccess/Backwards compatibility. + * @deprecated Add deprecation notices in future release. + * @param string $offset + * @return mixed + */ + public function offsetGet( $offset ) { + if ( 'line_subtotal' === $offset ) { + $offset = 'subtotal'; + } elseif ( 'line_subtotal_tax' === $offset ) { + $offset = 'subtotal_tax'; + } elseif ( 'line_total' === $offset ) { + $offset = 'total'; + } elseif ( 'line_tax' === $offset ) { + $offset = 'total_tax'; + } elseif ( 'line_tax_data' === $offset ) { + $offset = 'taxes'; + } + return parent::offsetGet( $offset ); + } + + /** + * offsetSet for ArrayAccess/Backwards compatibility. + * @deprecated Add deprecation notices in future release. + * @param string $offset + * @param mixed $value + */ + public function offsetSet( $offset, $value ) { + if ( 'line_subtotal' === $offset ) { + $offset = 'subtotal'; + } elseif ( 'line_subtotal_tax' === $offset ) { + $offset = 'subtotal_tax'; + } elseif ( 'line_total' === $offset ) { + $offset = 'total'; + } elseif ( 'line_tax' === $offset ) { + $offset = 'total_tax'; + } elseif ( 'line_tax_data' === $offset ) { + $offset = 'taxes'; + } + parent::offsetSet( $offset, $value ); + } + + /** + * offsetExists for ArrayAccess + * @param string $offset + * @return bool + */ + public function offsetExists( $offset ) { + if ( in_array( $offset, array( 'line_subtotal', 'line_subtotal_tax', 'line_total', 'line_tax', 'line_tax_data', 'item_meta_array', 'item_meta' ) ) ) { + return true; + } + return parent::offsetExists( $offset ); + } + + /** + * Read/populate data properties specific to this order item. + */ + public function read( $id ) { + parent::read( $id ); + if ( $this->get_id() ) { + $this->set_product_id( get_metadata( 'order_item', $this->get_id(), '_product_id', true ) ); + $this->set_variation_id( get_metadata( 'order_item', $this->get_id(), '_variation_id', true ) ); + $this->set_qty( get_metadata( 'order_item', $this->get_id(), '_qty', true ) ); + $this->set_tax_class( get_metadata( 'order_item', $this->get_id(), '_tax_class', true ) ); + $this->set_subtotal( get_metadata( 'order_item', $this->get_id(), '_line_subtotal', true ) ); + $this->set_subtotal_tax( get_metadata( 'order_item', $this->get_id(), '_line_subtotal_tax', true ) ); + $this->set_total( get_metadata( 'order_item', $this->get_id(), '_line_total', true ) ); + $this->set_total_tax( get_metadata( 'order_item', $this->get_id(), '_line_tax', true ) ); + $this->set_taxes( get_metadata( 'order_item', $this->get_id(), '_line_tax_data', true ) ); + } + } + + /** + * Save properties specific to this order item. + * @return int Item ID + */ + public function save() { + parent::save(); + if ( $this->get_id() ) { + wc_update_order_item_meta( $this->get_id(), '_product_id', $this->get_product_id() ); + wc_update_order_item_meta( $this->get_id(), '_variation_id', $this->get_variation_id() ); + wc_update_order_item_meta( $this->get_id(), '_qty', $this->get_qty() ); + wc_update_order_item_meta( $this->get_id(), '_tax_class', $this->get_tax_class() ); + wc_update_order_item_meta( $this->get_id(), '_line_subtotal', $this->get_subtotal() ); + wc_update_order_item_meta( $this->get_id(), '_line_subtotal_tax', $this->get_subtotal_tax() ); + wc_update_order_item_meta( $this->get_id(), '_line_total', $this->get_total() ); + wc_update_order_item_meta( $this->get_id(), '_line_tax', $this->get_total_tax() ); + wc_update_order_item_meta( $this->get_id(), '_line_tax_data', $this->get_taxes() ); + } + + return $this->get_id(); + } + + /** + * Internal meta keys we don't want exposed as part of meta_data. + * @return array() + */ + protected function get_internal_meta_keys() { + return array( '_product_id', '_variation_id', '_qty', '_tax_class', '_line_subtotal', '_line_subtotal_tax', '_line_total', '_line_tax', '_line_tax_data' ); + } + + /** + * Get the associated product. + * @return WC_Product|bool + */ + public function get_product() { + if ( $this->get_variation_id() ) { + $product = wc_get_product( $this->get_variation_id() ); + } else { + $product = wc_get_product( $this->get_product_id() ); + } + + // Backwards compatible filter from WC_Order::get_product_from_item() + if ( has_filter( 'woocommerce_get_product_from_item' ) ) { + $product = apply_filters( 'woocommerce_get_product_from_item', $product, $this, wc_get_order( $this->get_order_id() ) ); + } + + return apply_filters( 'woocommerce_order_item_product', $product, $this ); + } + + /** + * Get any associated downloadable files. + * @return array + */ + public function get_item_downloads() { + global $wpdb; + + $files = array(); + $product = $this->get_product(); + $order = wc_get_order( $this->get_order_id() ); + + if ( $product && $order && $product->is_downloadable() && $order->is_download_permitted() ) { + $download_file_id = $this->get_variation_id() ? $this->get_variation_id() : $this->get_product_id(); + $download_ids = $wpdb->get_col( + $wpdb->prepare( + "SELECT download_id FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE user_email = %s AND order_key = %s AND product_id = %d ORDER BY permission_id", + $order->get_billing_email(), + $order->get_order_key(), + $download_file_id + ) + ); + + foreach ( $download_ids as $download_id ) { + if ( $product->has_file( $download_id ) ) { + $files[ $download_id ] = $product->get_file( $download_id ); + $files[ $download_id ]['download_url'] = add_query_arg( array( + 'download_file' => $download_file_id, + 'order' => $order->get_order_key(), + 'email' => urlencode( $order->get_billing_email() ), + 'key' => $download_id + ), trailingslashit( home_url() ) ); + } + } + } + + return apply_filters( 'woocommerce_get_item_downloads', $files, $this, $order ); + } + + /** + * Get tax status. + * @return string + */ + public function get_tax_status() { + $product = $this->get_product(); + return $product ? $product->get_tax_status() : 'taxable'; + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set qty. + * @param int $value + */ + public function set_qty( $value ) { + $this->_data['qty'] = wc_stock_amount( $value ); + } + + /** + * Set tax class. + * @param string $value + */ + public function set_tax_class( $value ) { + $this->_data['tax_class'] = $value; + } + + /** + * Set Product ID + * @param int $value + */ + public function set_product_id( $value ) { + $this->_data['product_id'] = absint( $value ); + } + + /** + * Set variation ID. + * @param int $value + */ + public function set_variation_id( $value ) { + $this->_data['variation_id'] = absint( $value ); + } + + /** + * Line subtotal (before discounts). + * @param string $value + */ + public function set_subtotal( $value ) { + $this->_data['subtotal'] = wc_format_decimal( $value ); + } + + /** + * Line total (after discounts). + * @param string $value + */ + public function set_total( $value ) { + $this->_data['total'] = wc_format_decimal( $value ); + } + + /** + * Line subtotal tax (before discounts). + * @param string $value + */ + public function set_subtotal_tax( $value ) { + $this->_data['subtotal_tax'] = wc_format_decimal( $value ); + } + + /** + * Line total tax (after discounts). + * @param string $value + */ + public function set_total_tax( $value ) { + $this->_data['total_tax'] = wc_format_decimal( $value ); + } + + /** + * Set line taxes. + * @param array $raw_tax_data + */ + public function set_taxes( $raw_tax_data ) { + $raw_tax_data = maybe_unserialize( $raw_tax_data ); + $tax_data = array( + 'total' => array(), + 'subtotal' => array() + ); + if ( ! empty( $raw_tax_data['total'] ) && ! empty( $raw_tax_data['subtotal'] ) ) { + $tax_data['total'] = array_map( 'wc_format_decimal', $raw_tax_data['total'] ); + $tax_data['subtotal'] = array_map( 'wc_format_decimal', $raw_tax_data['subtotal'] ); + } + $this->_data['taxes'] = $tax_data; + } + + /** + * Set variation data (stored as meta data - write only). + * @param array $data Key/Value pairs + */ + public function set_variation( $data ) { + foreach ( $data as $key => $value ) { + $this->_meta_data[ str_replace( 'attribute_', '', $key ) ] = $value; + } + } + + /** + * Set properties based on passed in product object. + * @param WC_Product $product + */ + public function set_product( $product ) { + if ( $product ) { + $this->set_product_id( $product->get_id() ); + $this->set_name( $product->get_title() ); + $this->set_tax_class( $product->get_tax_class() ); + $this->set_variation_id( is_callable( array( $product, 'get_variation_id' ) ) ? $product->get_variation_id() : 0 ); + $this->set_variation( is_callable( array( $product, 'get_variation_attributes' ) ) ? $product->get_variation_attributes() : array() ); + } + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get order item type. + * @return string + */ + public function get_type() { + return 'line_item'; + } + + /** + * Get product ID. + * @return int + */ + public function get_product_id() { + return absint( $this->_data['product_id'] ); + } + + /** + * Get variation ID. + * @return int + */ + public function get_variation_id() { + return absint( $this->_data['variation_id'] ); + } + + /** + * Get qty. + * @return int + */ + public function get_qty() { + return wc_stock_amount( $this->_data['qty'] ); + } + + /** + * Get tax class. + * @return string + */ + public function get_tax_class() { + return $this->_data['tax_class']; + } + + /** + * Get subtotal. + * @return string + */ + public function get_subtotal() { + return wc_format_decimal( $this->_data['subtotal'] ); + } + + /** + * Get subtotal tax. + * @return string + */ + public function get_subtotal_tax() { + return wc_format_decimal( $this->_data['subtotal_tax'] ); + } + + /** + * Get total. + * @return string + */ + public function get_total() { + return wc_format_decimal( $this->_data['total'] ); + } + + /** + * Get total tax. + * @return string + */ + public function get_total_tax() { + return wc_format_decimal( $this->_data['total_tax'] ); + } + + /** + * Get fee taxes. + * @return array + */ + public function get_taxes() { + return $this->_data['taxes']; + } +} diff --git a/includes/class-wc-order-item-shipping.php b/includes/class-wc-order-item-shipping.php new file mode 100644 index 00000000000..ba51826e5cf --- /dev/null +++ b/includes/class-wc-order-item-shipping.php @@ -0,0 +1,233 @@ + 0, + 'order_item_id' => 0, + 'method_title' => '', + 'method_id' => '', + 'total' => 0, + 'total_tax' => 0, + 'taxes' => array( + 'total' => array() + ), + ); + + /** + * offsetGet for ArrayAccess/Backwards compatibility. + * @deprecated Add deprecation notices in future release. + * @param string $offset + * @return mixed + */ + public function offsetGet( $offset ) { + if ( 'cost' === $offset ) { + $offset = 'total'; + } + return parent::offsetGet( $offset ); + } + + /** + * offsetSet for ArrayAccess/Backwards compatibility. + * @deprecated Add deprecation notices in future release. + * @param string $offset + * @param mixed $value + */ + public function offsetSet( $offset, $value ) { + if ( 'cost' === $offset ) { + $offset = 'total'; + } + parent::offsetSet( $offset, $value ); + } + + /** + * offsetExists for ArrayAccess + * @param string $offset + * @return bool + */ + public function offsetExists( $offset ) { + if ( in_array( $offset, array( 'cost' ) ) ) { + return true; + } + return parent::offsetExists( $offset ); + } + + /** + * Read/populate data properties specific to this order item. + */ + public function read( $id ) { + parent::read( $id ); + if ( $this->get_id() ) { + $this->set_method_id( get_metadata( 'order_item', $this->get_id(), 'method_id', true ) ); + $this->set_total( get_metadata( 'order_item', $this->get_id(), 'cost', true ) ); + $this->set_total_tax( get_metadata( 'order_item', $this->get_id(), 'total_tax', true ) ); + $this->set_taxes( get_metadata( 'order_item', $this->get_id(), 'taxes', true ) ); + } + } + + /** + * Save properties specific to this order item. + * @return int Item ID + */ + public function save() { + parent::save(); + if ( $this->get_id() ) { + wc_update_order_item_meta( $this->get_id(), 'method_id', $this->get_method_id() ); + wc_update_order_item_meta( $this->get_id(), 'cost', $this->get_total() ); + wc_update_order_item_meta( $this->get_id(), 'total_tax', $this->get_total_tax() ); + wc_update_order_item_meta( $this->get_id(), 'taxes', $this->get_taxes() ); + } + + return $this->get_id(); + } + + /** + * Internal meta keys we don't want exposed as part of meta_data. + * @return array() + */ + protected function get_internal_meta_keys() { + return array( 'method_id', 'cost', 'total_tax', 'taxes' ); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set order item name. + * @param string $value + */ + public function set_name( $value ) { + $this->set_method_title( $value ); + } + + /** + * Set code. + * @param string $value + */ + public function set_method_title( $value ) { + $this->_data['method_title'] = wc_clean( $value ); + } + + /** + * Set shipping method id. + * @param string $value + */ + public function set_method_id( $value ) { + $this->_data['method_id'] = wc_clean( $value ); + } + + /** + * Set total. + * @param string $value + */ + public function set_total( $value ) { + $this->_data['total'] = wc_format_decimal( $value ); + } + + /** + * Set total tax. + * @param string $value + */ + public function set_total_tax( $value ) { + $this->_data['total_tax'] = wc_format_decimal( $value ); + } + + /** + * Set taxes. + * + * This is an array of tax ID keys with total amount values. + * @param array $raw_tax_data + */ + public function set_taxes( $raw_tax_data ) { + $raw_tax_data = maybe_unserialize( $raw_tax_data ); + $tax_data = array( + 'total' => array() + ); + if ( ! empty( $raw_tax_data['total'] ) ) { + $tax_data['total'] = array_map( 'wc_format_decimal', $raw_tax_data['total'] ); + } + $this->_data['taxes'] = $tax_data; + $this->set_total_tax( array_sum( $tax_data['total'] ) ); + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get order item type. + * @return string + */ + public function get_type() { + return 'shipping'; + } + + /** + * Get order item name. + * @return string + */ + public function get_name() { + return $this->get_method_title(); + } + + /** + * Get title. + * @return string + */ + public function get_method_title() { + return $this->_data['method_title'] ? $this->_data['method_title'] : __( 'Shipping', 'woocommerce' ); + } + + /** + * Get method ID. + * @return string + */ + public function get_method_id() { + return $this->_data['method_id']; + } + + /** + * Get total cost. + * @return string + */ + public function get_total() { + return wc_format_decimal( $this->_data['total'] ); + } + + /** + * Get total tax. + * @return string + */ + public function get_total_tax() { + return wc_format_decimal( $this->_data['total_tax'] ); + } + + /** + * Get taxes. + * @return array + */ + public function get_taxes() { + return $this->_data['taxes']; + } +} diff --git a/includes/class-wc-order-item-tax.php b/includes/class-wc-order-item-tax.php new file mode 100644 index 00000000000..5a3cc70a442 --- /dev/null +++ b/includes/class-wc-order-item-tax.php @@ -0,0 +1,210 @@ + 0, + 'order_item_id' => 0, + 'rate_code' => '', + 'rate_id' => 0, + 'label' => '', + 'compound' => false, + 'tax_total' => 0, + 'shipping_tax_total' => 0 + ); + + /** + * Read/populate data properties specific to this order item. + */ + public function read( $id ) { + parent::read( $id ); + if ( $this->get_id() ) { + $this->set_rate_id( get_metadata( 'order_item', $this->get_id(), 'rate_id', true ) ); + $this->set_label( get_metadata( 'order_item', $this->get_id(), 'label', true ) ); + $this->set_compound( get_metadata( 'order_item', $this->get_id(), 'compound', true ) ); + $this->set_tax_total( get_metadata( 'order_item', $this->get_id(), 'tax_amount', true ) ); + $this->set_shipping_tax_total( get_metadata( 'order_item', $this->get_id(), 'shipping_tax_amount', true ) ); + } + } + + /** + * Save properties specific to this order item. + * @return int Item ID + */ + public function save() { + parent::save(); + if ( $this->get_id() ) { + wc_update_order_item_meta( $this->get_id(), 'rate_id', $this->get_rate_id() ); + wc_update_order_item_meta( $this->get_id(), 'label', $this->get_label() ); + wc_update_order_item_meta( $this->get_id(), 'compound', $this->get_compound() ); + wc_update_order_item_meta( $this->get_id(), 'tax_amount', $this->get_tax_total() ); + wc_update_order_item_meta( $this->get_id(), 'shipping_tax_amount', $this->get_shipping_tax_total() ); + } + + return $this->get_id(); + } + + /** + * Internal meta keys we don't want exposed as part of meta_data. + * @return array() + */ + protected function get_internal_meta_keys() { + return array( 'rate_id', 'label', 'compound', 'tax_amount', 'shipping_tax_amount' ); + } + + /** + * Is this a compound tax rate? + * @return boolean + */ + public function is_compound() { + return $this->get_compound(); + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set order item name. + * @param string $value + */ + public function set_name( $value ) { + $this->set_rate_code( $value ); + } + + /** + * Set item name. + * @param string $value + */ + public function set_rate_code( $value ) { + $this->_data['rate_code'] = wc_clean( $value ); + } + + /** + * Set item name. + * @param string $value + */ + public function set_label( $value ) { + $this->_data['label'] = wc_clean( $value ); + } + + /** + * Set tax rate id. + * @param int $value + */ + public function set_rate_id( $value ) { + $this->_data['rate_id'] = absint( $value ); + } + + /** + * Set tax total. + * @param string $value + */ + public function set_tax_total( $value ) { + $this->_data['tax_total'] = wc_format_decimal( $value ); + } + + /** + * Set shipping_tax_total + * @param string $value + */ + public function set_shipping_tax_total( $value ) { + $this->_data['shipping_tax_total'] = wc_format_decimal( $value ); + } + + /** + * Set compound + * @param bool $value + */ + public function set_compound( $value ) { + $this->_data['compound'] = (bool) $value; + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get order item type. + * @return string + */ + public function get_type() { + return 'tax'; + } + + /** + * Get rate code/name. + * @return string + */ + public function get_name() { + return $this->get_rate_code(); + } + + /** + * Get rate code/name. + * @return string + */ + public function get_rate_code() { + return $this->_data['rate_code']; + } + + /** + * Get label. + * @return string + */ + public function get_label() { + return $this->_data['label'] ? $this->_data['label'] : __( 'Tax', 'woocommerce' ); + } + + /** + * Get tax rate ID. + * @return int + */ + public function get_rate_id() { + return absint( $this->_data['rate_id'] ); + } + + /** + * Get tax_total + * @return string + */ + public function get_tax_total() { + return wc_format_decimal( $this->_data['tax_total'] ); + } + + /** + * Get shipping_tax_total + * @return string + */ + public function get_shipping_tax_total() { + return wc_format_decimal( $this->_data['shipping_tax_total'] ); + } + + /** + * Get compound. + * @return bool + */ + public function get_compound() { + return (bool) $this->_data['compound']; + } +} diff --git a/includes/class-wc-order-item.php b/includes/class-wc-order-item.php new file mode 100644 index 00000000000..ac87dbd666d --- /dev/null +++ b/includes/class-wc-order-item.php @@ -0,0 +1,412 @@ + 0, + 'order_item_id' => 0, + 'name' => '', + 'type' => '', + ); + + /** + * Stores meta in cache for future reads. + * A group must be set to to enable caching. + * @var string + */ + protected $_cache_group = 'order_itemmeta'; + + /** + * Meta type. This should match up with + * the types avaiable at https://codex.wordpress.org/Function_Reference/add_metadata. + * WP defines 'post', 'user', 'comment', and 'term'. + */ + protected $_meta_type = 'order_item'; + + /** + * Constructor. + * @param int|object|array $order_item ID to load from the DB (optional) or already queried data. + */ + public function __construct( $item = 0 ) { + if ( $item instanceof WC_Order_Item ) { + if ( $this->is_type( $item->get_type() ) ) { + $this->set_all( $item->get_data() ); + } + } elseif ( is_array( $item ) ) { + $this->set_all( $item ); + } else { + $this->read( $item ); + } + } + + /** + * Set all data based on input array. + * @param array $data + * @access private + */ + public function set_all( $data ) { + foreach ( $data as $key => $value ) { + if ( is_callable( array( $this, "set_$key" ) ) ) { + $this->{"set_$key"}( $value ); + } else { + $this->_data[ $key ] = $value; + } + } + } + + /** + * Type checking + * @param string|array $Type + * @return boolean + */ + public function is_type( $type ) { + return is_array( $type ) ? in_array( $this->get_type(), $type ) : $type === $this->get_type(); + } + + /** + * Get qty. + * @return int + */ + public function get_qty() { + return 1; + } + + /* + |-------------------------------------------------------------------------- + | Getters + |-------------------------------------------------------------------------- + */ + + /** + * Get order item ID. + * @return int + */ + public function get_id() { + return $this->get_order_item_id(); + } + + /** + * Get order ID this meta belongs to. + * @return int + */ + public function get_order_id() { + return absint( $this->_data['order_id'] ); + } + + /** + * Get order item ID this meta belongs to. + * @return int + */ + public function get_order_item_id() { + return absint( $this->_data['order_item_id'] ); + } + + /** + * Get order item name. + * @return string + */ + public function get_name() { + return $this->_data['name']; + } + + /** + * Get order item type. + * @return string + */ + public function get_type() { + return $this->_data['type']; + } + + /* + |-------------------------------------------------------------------------- + | Setters + |-------------------------------------------------------------------------- + */ + + /** + * Set ID + * @param int $value + */ + public function set_id( $value ) { + $this->set_order_item_id( $value ); + } + + /** + * Set order ID. + * @param int $value + */ + public function set_order_id( $value ) { + $this->_data['order_id'] = absint( $value ); + } + + /** + * Set order item ID. + * @param int $value + */ + public function set_order_item_id( $value ) { + $this->_data['order_item_id'] = absint( $value ); + } + + /** + * Set order item name. + * @param string $value + */ + public function set_name( $value ) { + $this->_data['name'] = wc_clean( $value ); + } + + /** + * Set order item type. + * @param string $value + */ + public function set_type( $value ) { + $this->_data['type'] = wc_clean( $value ); + + } + + /* + |-------------------------------------------------------------------------- + | CRUD methods + |-------------------------------------------------------------------------- + | + | Methods which create, read, update and delete data from the database. + | + */ + + /** + * Insert data into the database. + * @since 2.7.0 + */ + public function create() { + global $wpdb; + + $wpdb->insert( $wpdb->prefix . 'woocommerce_order_items', array( + 'order_item_name' => $this->get_name(), + 'order_item_type' => $this->get_type(), + 'order_id' => $this->get_order_id() + ) ); + $this->set_id( $wpdb->insert_id ); + + do_action( 'woocommerce_new_order_item', $this->get_id(), $this, $this->get_order_id() ); + } + + /** + * Update data in the database. + * @since 2.7.0 + */ + public function update() { + global $wpdb; + + $wpdb->update( $wpdb->prefix . 'woocommerce_order_items', array( + 'order_item_name' => $this->get_name(), + 'order_item_type' => $this->get_type(), + 'order_id' => $this->get_order_id() + ), array( 'order_item_id' => $this->get_id() ) ); + + do_action( 'woocommerce_update_order_item', $this->get_id(), $this, $this->get_order_id() ); + } + + /** + * Read from the database. + * @since 2.7.0 + * @param int|object $item ID of object to read, or already queried object. + */ + public function read( $item ) { + global $wpdb; + + if ( is_numeric( $item ) && ! empty( $item ) ) { + $data = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d LIMIT 1;", $item ) ); + } elseif ( ! empty( $item->order_item_id ) ) { + $data = $item; + } else { + $data = false; + } + + if ( $data ) { + $this->set_order_id( $data->order_id ); + $this->set_id( $data->order_item_id ); + $this->set_name( $data->order_item_name ); + $this->set_type( $data->order_item_type ); + $this->read_meta_data(); + } + } + + /** + * Save data to the database. + * @since 2.7.0 + * @return int Item ID + */ + public function save() { + if ( ! $this->get_id() ) { + $this->create(); + } else { + $this->update(); + } + $this->save_meta_data(); + + return $this->get_id(); + } + + /** + * Delete data from the database. + * @since 2.7.0 + */ + public function delete() { + if ( $this->get_id() ) { + global $wpdb; + do_action( 'woocommerce_before_delete_order_item', $this->get_id() ); + $wpdb->delete( $wpdb->prefix . 'woocommerce_order_items', array( 'order_item_id' => $this->get_id() ) ); + $wpdb->delete( $wpdb->prefix . 'woocommerce_order_itemmeta', array( 'order_item_id' => $this->get_id() ) ); + do_action( 'woocommerce_delete_order_item', $this->get_id() ); + } + } + + /* + |-------------------------------------------------------------------------- + | Meta Data Handling + |-------------------------------------------------------------------------- + */ + + /** + * Expands things like term slugs before return. + * @param string $hideprefix (default: _) + * @return array + */ + public function get_formatted_meta_data( $hideprefix = '_' ) { + $formatted_meta = array(); + $meta_data = $this->get_meta_data(); + + foreach ( $meta_data as $meta ) { + if ( "" === $meta->value || is_serialized( $meta->value ) || ( ! empty( $hideprefix ) && substr( $meta->key, 0, 1 ) === $hideprefix ) ) { + continue; + } + + $attribute_key = urldecode( str_replace( 'attribute_', '', $meta->key ) ); + $display_key = wc_attribute_label( $attribute_key, is_callable( array( $this, 'get_product' ) ) ? $this->get_product() : false ); + $display_value = $meta->value; + + if ( taxonomy_exists( $attribute_key ) ) { + $term = get_term_by( 'slug', $meta->value, $attribute_key ); + if ( ! is_wp_error( $term ) && is_object( $term ) && $term->name ) { + $display_value = $term->name; + } + } + + $formatted_meta[ $meta->meta_id ] = (object) array( + 'key' => $meta->key, + 'value' => $meta->key, + 'display_key' => apply_filters( 'woocommerce_order_item_display_meta_key', $display_key ), + 'display_value' => apply_filters( 'woocommerce_order_item_display_meta_value', $display_value ), + ); + } + + return $formatted_meta; + } + + /* + |-------------------------------------------------------------------------- + | Array Access Methods + |-------------------------------------------------------------------------- + | + | For backwards compat with legacy arrays. + | + */ + + /** + * offsetSet for ArrayAccess + * @param string $offset + * @param mixed $value + */ + public function offsetSet( $offset, $value ) { + if ( 'item_meta_array' === $offset ) { + foreach ( $value as $meta_id => $meta ) { + $this->update_meta_data( $meta->key, $meta->value, $meta_id ); + } + return; + } + + if ( array_key_exists( $offset, $this->_data ) ) { + $this->_data[ $offset ] = $value; + } + + $this->update_meta_data( '_' . $offset, $value ); + } + + /** + * offsetUnset for ArrayAccess + * @param string $offset + */ + public function offsetUnset( $offset ) { + if ( 'item_meta_array' === $offset || 'item_meta' === $offset ) { + $this->_meta_data = array(); + return; + } + + if ( array_key_exists( $offset, $this->_data ) ) { + unset( $this->_data[ $offset ] ); + } + + $this->delete_meta_data( '_' . $offset ); + } + + /** + * offsetExists for ArrayAccess + * @param string $offset + * @return bool + */ + public function offsetExists( $offset ) { + if ( 'item_meta_array' === $offset || 'item_meta' === $offset || array_key_exists( $offset, $this->_data ) ) { + return true; + } + return array_key_exists( '_' . $offset, wp_list_pluck( $this->_meta_data, 'value', 'key' ) ); + } + + /** + * offsetGet for ArrayAccess + * @param string $offset + * @return mixed + */ + public function offsetGet( $offset ) { + if ( 'item_meta_array' === $offset ) { + $return = array(); + + foreach ( $this->_meta_data as $meta ) { + $return[ $meta->meta_id ] = $meta; + } + + return $return; + } + + $meta_values = wp_list_pluck( $this->_meta_data, 'value', 'key' ); + + if ( 'item_meta' === $offset ) { + return $meta_values; + } elseif ( array_key_exists( $offset, $this->_data ) ) { + return $this->_data[ $offset ]; + } elseif ( array_key_exists( '_' . $offset, $meta_values ) ) { + // Item meta was expanded in previous versions, with prefixes removed. This maintains support. + return $meta_values[ '_' . $offset ]; + } + + return null; + } +} From 7b3a9b27ed816e029e56afd5326033506f2cb7f4 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 21 Jun 2016 20:26:35 +0100 Subject: [PATCH 012/298] Function replacements for class methods --- includes/wc-order-functions.php | 131 +++++++++++++++++++++++++++++ includes/wc-template-functions.php | 121 ++++++++++++++++++++++++++ 2 files changed, 252 insertions(+) diff --git a/includes/wc-order-functions.php b/includes/wc-order-functions.php index cf5137b1f84..d0e0c90ed59 100644 --- a/includes/wc-order-functions.php +++ b/includes/wc-order-functions.php @@ -1054,3 +1054,134 @@ function wc_order_search( $term ) { return $post_ids; } + + +/** + * Update total sales amount for each product within a paid order. + * + * @since 2.6.0 + * @param int $order_id + */ +function wc_update_total_sales_counts( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( ! $order || 'yes' === get_post_meta( $order_id, '_recorded_sales', true ) ) { + return; + } + + if ( sizeof( $order->get_items() ) > 0 ) { + foreach ( $order->get_items() as $item ) { + if ( $item['product_id'] > 0 ) { + update_post_meta( $item['product_id'], 'total_sales', absint( get_post_meta( $item['product_id'], 'total_sales', true ) ) + absint( $item['qty'] ) ); + } + } + } + + update_post_meta( $order_id, '_recorded_sales', 'yes' ); + + /** + * Called when sales for an order are recorded + * + * @param int $order_id order id + */ + do_action( 'woocommerce_recorded_sales', $order_id ); +} +add_action( 'woocommerce_order_status_completed', 'wc_update_total_sales_counts' ); +add_action( 'woocommerce_order_status_processing', 'wc_update_total_sales_counts' ); +add_action( 'woocommerce_order_status_on-hold', 'wc_update_total_sales_counts' ); + +/** + * Update used coupon amount for each coupon within an order. + * + * @since 2.6.0 + * @param int $order_id + */ +function wc_update_coupon_usage_counts( $order_id ) { + $order = wc_get_order( $order_id ); + $has_recorded = get_post_meta( $order_id, '_recorded_coupon_usage_counts', true ); + + if ( ! $order ) { + return; + } + + if ( $order->has_status( 'cancelled' ) && 'yes' === $has_recorded ) { + $action = 'reduce'; + delete_post_meta( $order_id, '_recorded_coupon_usage_counts' ); + } elseif ( ! $order->has_status( 'cancelled' ) && 'yes' !== $has_recorded ) { + $action = 'increase'; + update_post_meta( $order_id, '_recorded_coupon_usage_counts', 'yes' ); + } else { + return; + } + + if ( sizeof( $order->get_used_coupons() ) > 0 ) { + foreach ( $order->get_used_coupons() as $code ) { + if ( ! $code ) { + continue; + } + + $coupon = new WC_Coupon( $code ); + + if ( ! $used_by = $order->get_user_id() ) { + $used_by = $order->get_billing_email(); + } + + switch ( $action ) { + case 'reduce' : + $coupon->dcr_usage_count( $used_by ); + break; + case 'increase' : + $coupon->inc_usage_count( $used_by ); + break; + } + } + } +} +add_action( 'woocommerce_order_status_completed', 'wc_update_total_sales_counts' ); +add_action( 'woocommerce_order_status_processing', 'wc_update_total_sales_counts' ); +add_action( 'woocommerce_order_status_on-hold', 'wc_update_total_sales_counts' ); +add_action( 'woocommerce_order_status_cancelled', 'wc_update_total_sales_counts' ); + +/** + * When a payment is complete, we can reduce stock levels for items within an order. + * @since 2.6.0 + * @param int $order_id + */ +function wc_maybe_reduce_stock_levels( $order_id ) { + if ( apply_filters( 'woocommerce_payment_complete_reduce_order_stock', ! get_post_meta( $order_id, '_order_stock_reduced', true ), $order_id ) ) { + wc_reduce_stock_levels( $order_id ); + add_post_meta( $order_id, '_order_stock_reduced', '1', true ); + } +} +add_action( 'woocommerce_payment_complete', 'wc_maybe_reduce_stock_levels' ); + +/** + * Reduce stock levels for items within an order. + * @since 2.6.0 + * @param int $order_id + */ +function wc_reduce_stock_levels( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( 'yes' === get_option( 'woocommerce_manage_stock' ) && $order && apply_filters( 'woocommerce_can_reduce_order_stock', true, $order ) && sizeof( $order->get_items() ) > 0 ) { + foreach ( $order->get_items() as $item ) { + if ( $item->is_type( 'line_item' ) && ( $product = $item->get_product() ) && $product->managing_stock() ) { + $qty = apply_filters( 'woocommerce_order_item_quantity', $item['qty'], $order, $item ); + $new_stock = $product->reduce_stock( $qty ); + $item_name = $product->get_sku() ? $product->get_sku(): $item['product_id']; + + if ( ! empty( $item['variation_id'] ) ) { + $order->add_order_note( sprintf( __( 'Item %s variation #%s stock reduced from %s to %s.', 'woocommerce' ), $item_name, $item['variation_id'], $new_stock + $qty, $new_stock ) ); + } else { + $order->add_order_note( sprintf( __( 'Item %s stock reduced from %s to %s.', 'woocommerce' ), $item_name, $new_stock + $qty, $new_stock ) ); + } + + if ( $new_stock < 0 ) { + do_action( 'woocommerce_product_on_backorder', array( 'product' => $product, 'order_id' => $order_id, 'quantity' => $qty_ordered ) ); + } + } + } + + do_action( 'woocommerce_reduce_order_stock', $order ); + } +} diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index c8ef0e257b9..80202307ce3 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -2216,3 +2216,124 @@ if ( ! function_exists( 'woocommerce_account_edit_account' ) ) { WC_Shortcode_My_Account::edit_account(); } } + + +if ( ! function_exists( 'wc_get_email_order_items' ) ) { + /** + * Get HTML for the order items to be shown in emails. + * @param WC_Order $order + * @param array $args + * @since 2.7.0 + */ + function wc_get_email_order_items( $order, $args = array() ) { + ob_start(); + + $defaults = array( + 'show_sku' => false, + 'show_image' => false, + 'image_size' => array( 32, 32 ), + 'plain_text' => false + ); + + $args = wp_parse_args( $args, $defaults ); + $template = $args['plain_text'] ? 'emails/plain/email-order-items.php' : 'emails/email-order-items.php'; + + wc_get_template( $template, array( + 'order' => $order, + 'items' => $order->get_items(), + 'show_download_links' => $order->is_download_permitted(), + 'show_sku' => $args['show_sku'], + 'show_purchase_note' => $order->is_paid(), + 'show_image' => $args['show_image'], + 'image_size' => $args['image_size'], + ) ); + + return apply_filters( 'woocommerce_email_order_items_table', ob_get_clean(), $order ); + } +} + +if ( ! function_exists( 'wc_display_item_meta' ) ) { + /** + * Display item meta data. + * @param WC_Item $item + * @param array $args + * @return string|void + */ + function wc_display_item_meta( $item, $args = array() ) { + $strings = array(); + $html = ''; + $args = wp_parse_args( $args, array( + 'before' => '
  • ', + 'after' => '
', + 'separator' => '
  • ', + 'echo' => true, + 'autop' => false, + ) ); + + foreach ( $item->get_formatted_meta_data() as $meta_id => $meta ) { + if ( '_' === substr( $meta->key, 0, 1 ) ) { + continue; + } + $value = $args['autop'] ? wp_kses_post( wpautop( make_clickable( $meta->display_value ) ) ) : wp_kses_post( make_clickable( $meta->display_value ) ); + $strings[] = '' . wp_kses_post( $meta->display_key ) . ': ' . $value; + } + + if ( $strings ) { + $html = $args['before'] . implode( $args['separator'], $strings ) . $args['after']; + } + + $html = apply_filters( 'woocommerce_display_item_meta', $html, $item, $args ); + + if ( $args['echo'] ) { + echo $html; + } else { + return $html; + } + } +} + +if ( ! function_exists( 'wc_display_item_downloads' ) ) { + /** + * Display item download links. + * @param WC_Item $item + * @param array $args + * @return string|void + */ + function wc_display_item_downloads( $item, $args = array() ) { + $strings = array(); + $html = ''; + $args = wp_parse_args( $args, array( + 'before' => '
    • ', + 'after' => '
    ', + 'separator' => '
  • ', + 'echo' => true, + 'show_url' => false, + ) ); + + if ( is_object( $item ) && $item->is_type( 'line_item' ) && ( $downloads = $item->get_item_downloads() ) ) { + $i = 0; + foreach ( $downloads as $file ) { + $i ++; + + if ( $args['show_url'] ) { + $strings[] = '' . esc_html( $file['name'] ) . ': ' . esc_html( $file['download_url'] ); + } else { + $prefix = sizeof( $downloads ) > 1 ? sprintf( __( 'Download %d', 'woocommerce' ), $i ) : __( 'Download', 'woocommerce' ); + $strings[] = '' . $prefix . ': ' . esc_html( $file['name'] ) . ''; + } + } + } + + if ( $strings ) { + $html = $args['before'] . implode( $args['separator'], $strings ) . $args['after']; + } + + $html = apply_filters( 'woocommerce_display_item_downloads', $html, $item, $args ); + + if ( $args['echo'] ) { + echo $html; + } else { + return $html; + } + } +} From 9c7abaedcbe2baf969100f38bd42ef8e5916ae8e Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 Jun 2016 12:29:23 +0100 Subject: [PATCH 013/298] Fixed unit tests --- .../helpers/class-wc-helper-order.php | 16 ++++---- tests/unit-tests/crud/orders.php | 39 +++++++++++++++++++ tests/unit-tests/order/functions.php | 4 +- .../payment-tokens/payment-tokens.php | 6 +-- 4 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 tests/unit-tests/crud/orders.php diff --git a/tests/framework/helpers/class-wc-helper-order.php b/tests/framework/helpers/class-wc-helper-order.php index 480f03e03a3..5b4ea31cd82 100644 --- a/tests/framework/helpers/class-wc-helper-order.php +++ b/tests/framework/helpers/class-wc-helper-order.php @@ -51,7 +51,7 @@ class WC_Helper_Order { $order = wc_create_order( $order_data ); // Add order products - $item_id = $order->add_product( $product, 4 ); + $item_id = $order->add_product( $product, array( 'qty' => 4 ) ); // Set billing address $billing_address = array( @@ -78,13 +78,13 @@ class WC_Helper_Order { $order->set_payment_method( $payment_gateways['bacs'] ); // Set totals - $order->set_total( 10, 'shipping' ); - $order->set_total( 0, 'cart_discount' ); - $order->set_total( 0, 'cart_discount_tax' ); - $order->set_total( 0, 'tax' ); - $order->set_total( 0, 'shipping_tax' ); - $order->set_total( 40, 'total' ); // 4 x $10 simple helper product + $order->set_shipping_total( 10 ); + $order->set_discount_total( 0 ); + $order->set_discount_tax( 0 ); + $order->set_cart_tax( 0 ); + $order->set_shipping_tax( 0 ); + $order->set_total( 40 ); // 4 x $10 simple helper product - return wc_get_order( $order->id ); + return wc_get_order( $order->get_id() ); } } diff --git a/tests/unit-tests/crud/orders.php b/tests/unit-tests/crud/orders.php new file mode 100644 index 00000000000..c8b26d6b57f --- /dev/null +++ b/tests/unit-tests/crud/orders.php @@ -0,0 +1,39 @@ +assertEquals( 'shop_order', $object->get_type() ); + } + + /** + * Test: CRUD + */ + function test_CRUD() { + $object = new WC_Order(); + + // Save + create + $save_id = $object->save(); + $post = get_post( $save_id ); + $this->assertEquals( 'shop_order', $post->post_type ); + $this->assertEquals( 'shop_order', $post->post_type ); + + // Update + $update_id = $object->save(); + $this->assertEquals( $update_id, $save_id ); + + // Delete + $object->delete(); + $post = get_post( $save_id ); + $this->assertNull( $post ); + } + +} diff --git a/tests/unit-tests/order/functions.php b/tests/unit-tests/order/functions.php index b17717aa31c..ad516a63739 100644 --- a/tests/unit-tests/order/functions.php +++ b/tests/unit-tests/order/functions.php @@ -109,7 +109,7 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case { $this->assertInstanceOf( 'WC_Order', wc_get_order( $order ) ); // Assert that wc_get_order() accepts a order post id. - $this->assertInstanceOf( 'WC_Order', wc_get_order( $order->id ) ); + $this->assertInstanceOf( 'WC_Order', wc_get_order( $order->get_id() ) ); // Assert that a non-shop_order post returns false $post = $this->factory->post->create_and_get( array( 'post_type' => 'post' ) ); @@ -132,7 +132,7 @@ class WC_Tests_Order_Functions extends WC_Unit_Test_Case { $this->assertEmpty( $order->get_payment_tokens() ); $token = WC_Helper_Payment_Token::create_cc_token(); - update_post_meta( $order->id, '_payment_tokens', array( $token->get_id() ) ); + update_post_meta( $order->get_id(), '_payment_tokens', array( $token->get_id() ) ); $this->assertCount( 1, $order->get_payment_tokens() ); } diff --git a/tests/unit-tests/payment-tokens/payment-tokens.php b/tests/unit-tests/payment-tokens/payment-tokens.php index 27843506792..558bb37ae5d 100644 --- a/tests/unit-tests/payment-tokens/payment-tokens.php +++ b/tests/unit-tests/payment-tokens/payment-tokens.php @@ -18,12 +18,12 @@ class WC_Tests_Payment_Tokens extends WC_Unit_Test_Case { */ function test_wc_payment_tokens_get_order_tokens() { $order = WC_Helper_Order::create_order(); - $this->assertEmpty( WC_Payment_Tokens::get_order_tokens( $order->id ) ); + $this->assertEmpty( WC_Payment_Tokens::get_order_tokens( $order->get_id() ) ); $token = WC_Helper_Payment_Token::create_cc_token(); - update_post_meta( $order->id, '_payment_tokens', array( $token->get_id() ) ); + update_post_meta( $order->get_id(), '_payment_tokens', array( $token->get_id() ) ); - $this->assertCount( 1, WC_Payment_Tokens::get_order_tokens( $order->id ) ); + $this->assertCount( 1, WC_Payment_Tokens::get_order_tokens( $order->get_id() ) ); } From 67de655f71c209eef243f70f3c51076e7de5afb7 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 Jun 2016 13:06:02 +0100 Subject: [PATCH 014/298] wc_paying_customer unit test compat --- includes/wc-user-functions.php | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/includes/wc-user-functions.php b/includes/wc-user-functions.php index 8b668a12127..96982ba8722 100644 --- a/includes/wc-user-functions.php +++ b/includes/wc-user-functions.php @@ -176,17 +176,18 @@ function wc_update_new_customer_past_orders( $customer_id ) { * @param int $order_id */ function wc_paying_customer( $order_id ) { - $order = wc_get_order( $order_id ); + $order = wc_get_order( $order_id ); + $customer_id = $order->get_customer_id(); - if ( $order->user_id > 0 && 'refund' !== $order->order_type ) { - update_user_meta( $order->user_id, 'paying_customer', 1 ); + if ( $customer_id > 0 && 'refund' !== $order->get_type() ) { + update_user_meta( $customer_id, 'paying_customer', 1 ); - $old_spent = absint( get_user_meta( $order->user_id, '_money_spent', true ) ); - update_user_meta( $order->user_id, '_money_spent', $old_spent + $order->order_total ); + $old_spent = absint( get_user_meta( $customer_id, '_money_spent', true ) ); + update_user_meta( $customer_id, '_money_spent', $old_spent + $order->order_total ); } - if ( $order->user_id > 0 && 'simple' === $order->order_type ) { - $old_count = absint( get_user_meta( $order->user_id, '_order_count', true ) ); - update_user_meta( $order->user_id, '_order_count', $old_count + 1 ); + if ( $customer_id > 0 && 'shop_order' === $order->get_type() ) { + $old_count = absint( get_user_meta( $customer_id, '_order_count', true ) ); + update_user_meta( $customer_id, '_order_count', $old_count + 1 ); } } add_action( 'woocommerce_order_status_completed', 'wc_paying_customer' ); From 8287b13cf1e4ff1cc5f3a62629d7d238d4d6b040 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 Jun 2016 14:07:42 +0100 Subject: [PATCH 015/298] Address and CRUD unit tests --- includes/abstracts/abstract-wc-order.php | 2 +- includes/class-wc-order.php | 13 +- tests/unit-tests/crud/orders.php | 246 +++++++++++++++++++++++ 3 files changed, 258 insertions(+), 3 deletions(-) diff --git a/includes/abstracts/abstract-wc-order.php b/includes/abstracts/abstract-wc-order.php index 45734c971cc..600c894f47c 100644 --- a/includes/abstracts/abstract-wc-order.php +++ b/includes/abstracts/abstract-wc-order.php @@ -33,7 +33,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { protected $_data = array( 'id' => 0, 'parent_id' => 0, - 'status' => '', + 'status' => 'pending', 'type' => 'shop_order', 'order_key' => '', 'currency' => '', diff --git a/includes/class-wc-order.php b/includes/class-wc-order.php index 773c38ee56e..b318793b310 100644 --- a/includes/class-wc-order.php +++ b/includes/class-wc-order.php @@ -96,16 +96,23 @@ class WC_Order extends WC_Abstract_Order { * Sales are also recorded for products. * Finally, record the date of payment. * + * Order must exist. + * * @param string $transaction_id Optional transaction id to store in post meta. + * @return bool success */ public function payment_complete( $transaction_id = '' ) { + if ( ! $this->get_id() ) { + return false; + } + do_action( 'woocommerce_pre_payment_complete', $this->get_id() ); if ( ! empty( WC()->session ) ) { WC()->session->set( 'order_awaiting_payment', false ); } - if ( $this->get_id() && $this->has_status( apply_filters( 'woocommerce_valid_order_statuses_for_payment_complete', array( 'on-hold', 'pending', 'failed', 'cancelled' ), $this ) ) ) { + if ( $this->has_status( apply_filters( 'woocommerce_valid_order_statuses_for_payment_complete', array( 'on-hold', 'pending', 'failed', 'cancelled' ), $this ) ) ) { $order_needs_processing = false; if ( sizeof( $this->get_items() ) > 0 ) { @@ -133,6 +140,8 @@ class WC_Order extends WC_Abstract_Order { } else { do_action( 'woocommerce_payment_complete_order_status_' . $this->get_status(), $this->get_id() ); } + + return true; } /** @@ -377,7 +386,7 @@ class WC_Order extends WC_Abstract_Order { } /** - * Updates status of order immediately. + * Updates status of order immediately. Order must exist. * @uses WC_Order::set_status() */ public function update_status( $new_status, $note = '', $manual = false ) { diff --git a/tests/unit-tests/crud/orders.php b/tests/unit-tests/crud/orders.php index c8b26d6b57f..a2490d9d4f8 100644 --- a/tests/unit-tests/crud/orders.php +++ b/tests/unit-tests/crud/orders.php @@ -36,4 +36,250 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case { $this->assertNull( $post ); } + /** + * Test: payment_complete + */ + function test_payment_complete() { + $object = new WC_Order(); + + $this->assertFalse( $object->payment_complete() ); + $object->save(); + $this->assertTrue( $object->payment_complete( '12345' ) ); + $this->assertEquals( 'completed', $object->get_status() ); + $this->assertEquals( '12345', $object->get_transaction_id() ); + } + + /** + * Test: get_formatted_order_total + */ + function test_get_formatted_order_total() { + $object = new WC_Order(); + $object->set_total( 100 ); + $object->set_currency( 'USD' ); + $this->assertEquals( '$100.00', $object->get_formatted_order_total() ); + } + + /** + * Test: set_status + */ + function test_set_status() { + $object = new WC_Order(); + $object->set_status( 'on-hold' ); + $this->assertEquals( 'on-hold', $object->get_status() ); + } + + /** + * Test: update_status + */ + function test_update_status() { + $object = new WC_Order(); + $this->assertFalse( $object->update_status( 'on-hold' ) ); + $object->save(); + $this->assertTrue( $object->update_status( 'on-hold' ) ); + $this->assertEquals( 'on-hold', $object->get_status() ); + } + + /** + * Test: get_billing_first_name + */ + function test_get_billing_first_name() { + $object = new WC_Order(); + $set_to = 'Fred'; + $object->set_billing_first_name( $set_to ); + $this->assertEquals( $set_to, $object->get_billing_first_name() ); + } + + /** + * Test: get_billing_last_name + */ + function test_get_billing_last_name() { + $object = new WC_Order(); + $set_to = 'Flintstone'; + $object->set_billing_last_name( $set_to ); + $this->assertEquals( $set_to, $object->get_billing_last_name() ); + } + + /** + * Test: get_billing_company + */ + function test_get_billing_company() { + $object = new WC_Order(); + $set_to = 'Bedrock Ltd.'; + $object->set_billing_company( $set_to ); + $this->assertEquals( $set_to, $object->get_billing_company() ); + } + + /** + * Test: get_billing_address_1 + */ + function test_get_billing_address_1() { + $object = new WC_Order(); + $set_to = '34 Stonepants avenue'; + $object->set_billing_address_1( $set_to ); + $this->assertEquals( $set_to, $object->get_billing_address_1() ); + } + + /** + * Test: get_billing_address_2 + */ + function test_get_billing_address_2() { + $object = new WC_Order(); + $set_to = 'Rockville'; + $object->set_billing_address_2( $set_to ); + $this->assertEquals( $set_to, $object->get_billing_address_2() ); + } + + /** + * Test: get_billing_city + */ + function test_get_billing_city() { + $object = new WC_Order(); + $set_to = 'Bedrock'; + $object->set_billing_city( $set_to ); + $this->assertEquals( $set_to, $object->get_billing_city() ); + } + + /** + * Test: get_billing_state + */ + function test_get_billing_state() { + $object = new WC_Order(); + $set_to = 'Jurassic America'; + $object->set_billing_state( $set_to ); + $this->assertEquals( $set_to, $object->get_billing_state() ); + } + + /** + * Test: get_billing_postcode + */ + function test_get_billing_postcode() { + $object = new WC_Order(); + $set_to = '00001'; + $object->set_billing_postcode( $set_to ); + $this->assertEquals( $set_to, $object->get_billing_postcode() ); + } + + /** + * Test: get_billing_country + */ + function test_get_billing_country() { + $object = new WC_Order(); + $set_to = 'US'; + $object->set_billing_country( $set_to ); + $this->assertEquals( $set_to, $object->get_billing_country() ); + } + + /** + * Test: get_billing_email + */ + function test_get_billing_email() { + $object = new WC_Order(); + $set_to = 'test@test.com'; + $object->set_billing_email( $set_to ); + $this->assertEquals( $set_to, $object->get_billing_email() ); + + $set_to = 'not an email'; + $object->set_billing_email( $set_to ); + $this->assertEquals( '', $object->get_billing_email() ); + } + + /** + * Test: get_billing_phone + */ + function test_get_billing_phone() { + $object = new WC_Order(); + $set_to = '123456678'; + $object->set_billing_phone( $set_to ); + $this->assertEquals( $set_to, $object->get_billing_phone() ); + } + + /** + * Test: get_shipping_first_name + */ + function test_get_shipping_first_name() { + $object = new WC_Order(); + $set_to = 'Fred'; + $object->set_shipping_first_name( $set_to ); + $this->assertEquals( $set_to, $object->get_shipping_first_name() ); + } + + /** + * Test: get_shipping_last_name + */ + function test_get_shipping_last_name() { + $object = new WC_Order(); + $set_to = 'Flintstone'; + $object->set_shipping_last_name( $set_to ); + $this->assertEquals( $set_to, $object->get_shipping_last_name() ); + } + + /** + * Test: get_shipping_company + */ + function test_get_shipping_company() { + $object = new WC_Order(); + $set_to = 'Bedrock Ltd.'; + $object->set_shipping_company( $set_to ); + $this->assertEquals( $set_to, $object->get_shipping_company() ); + } + + /** + * Test: get_shipping_address_1 + */ + function test_get_shipping_address_1() { + $object = new WC_Order(); + $set_to = '34 Stonepants avenue'; + $object->set_shipping_address_1( $set_to ); + $this->assertEquals( $set_to, $object->get_shipping_address_1() ); + } + + /** + * Test: get_shipping_address_2 + */ + function test_get_shipping_address_2() { + $object = new WC_Order(); + $set_to = 'Rockville'; + $object->set_shipping_address_2( $set_to ); + $this->assertEquals( $set_to, $object->get_shipping_address_2() ); + } + + /** + * Test: get_shipping_city + */ + function test_get_shipping_city() { + $object = new WC_Order(); + $set_to = 'Bedrock'; + $object->set_shipping_city( $set_to ); + $this->assertEquals( $set_to, $object->get_shipping_city() ); + } + + /** + * Test: get_shipping_state + */ + function test_get_shipping_state() { + $object = new WC_Order(); + $set_to = 'Jurassic America'; + $object->set_shipping_state( $set_to ); + $this->assertEquals( $set_to, $object->get_shipping_state() ); + } + + /** + * Test: get_shipping_postcode + */ + function test_get_shipping_postcode() { + $object = new WC_Order(); + $set_to = '00001'; + $object->set_shipping_postcode( $set_to ); + $this->assertEquals( $set_to, $object->get_shipping_postcode() ); + } + + /** + * Test: get_shipping_country + */ + function test_get_shipping_country() { + $object = new WC_Order(); + $set_to = 'US'; + $object->set_shipping_country( $set_to ); + $this->assertEquals( $set_to, $object->get_shipping_country() ); + } } From 9fc3e24647d80a2cf802ea6781bb5cd45ea7e27d Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 Jun 2016 14:28:00 +0100 Subject: [PATCH 016/298] getter unit tests --- tests/unit-tests/crud/orders.php | 236 ++++++++++++++++++++++++++++++- 1 file changed, 234 insertions(+), 2 deletions(-) diff --git a/tests/unit-tests/crud/orders.php b/tests/unit-tests/crud/orders.php index a2490d9d4f8..50f3faa6220 100644 --- a/tests/unit-tests/crud/orders.php +++ b/tests/unit-tests/crud/orders.php @@ -144,7 +144,7 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case { */ function test_get_billing_state() { $object = new WC_Order(); - $set_to = 'Jurassic America'; + $set_to = 'Boulder'; $object->set_billing_state( $set_to ); $this->assertEquals( $set_to, $object->get_billing_state() ); } @@ -258,7 +258,7 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case { */ function test_get_shipping_state() { $object = new WC_Order(); - $set_to = 'Jurassic America'; + $set_to = 'Boulder'; $object->set_shipping_state( $set_to ); $this->assertEquals( $set_to, $object->get_shipping_state() ); } @@ -282,4 +282,236 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case { $object->set_shipping_country( $set_to ); $this->assertEquals( $set_to, $object->get_shipping_country() ); } + + /** + * Test: get_payment_method + */ + function test_get_payment_method() { + $object = new WC_Order(); + $set_to = 'paypal'; + $object->set_payment_method( $set_to ); + $this->assertEquals( $set_to, $object->get_payment_method() ); + } + + /** + * Test: get_payment_method_title + */ + function test_get_payment_method_title() { + $object = new WC_Order(); + $set_to = 'PayPal'; + $object->set_payment_method_title( $set_to ); + $this->assertEquals( $set_to, $object->get_payment_method_title() ); + } + + /** + * Test: get_transaction_id + */ + function test_get_transaction_id() { + $object = new WC_Order(); + $set_to = '12345'; + $object->set_transaction_id( $set_to ); + $this->assertEquals( $set_to, $object->get_transaction_id() ); + } + + /** + * Test: get_customer_ip_address + */ + function test_get_customer_ip_address() { + $object = new WC_Order(); + $set_to = '192.168.1.1'; + $object->set_customer_ip_address( $set_to ); + $this->assertEquals( $set_to, $object->get_customer_ip_address() ); + } + + /** + * Test: get_customer_user_agent + */ + function test_get_customer_user_agent() { + $object = new WC_Order(); + $set_to = 'UAstring'; + $object->set_customer_user_agent( $set_to ); + $this->assertEquals( $set_to, $object->get_customer_user_agent() ); + } + + /** + * Test: get_created_via + */ + function test_get_created_via() { + $object = new WC_Order(); + $set_to = 'WooCommerce'; + $object->set_created_via( $set_to ); + $this->assertEquals( $set_to, $object->get_created_via() ); + } + + /** + * Test: get_customer_note + */ + function test_get_customer_note() { + $object = new WC_Order(); + $set_to = 'Leave on porch.'; + $object->set_customer_note( $set_to ); + $this->assertEquals( $set_to, $object->get_customer_note() ); + } + + /** + * Test: get_date_completed + */ + function test_get_date_completed() { + $object = new WC_Order(); + $object->set_date_completed( '2016-12-12' ); + $this->assertEquals( '1481500800', $object->get_date_completed() ); + + $object->set_date_completed( '1481500800' ); + $this->assertEquals( 1481500800, $object->get_date_completed() ); + } + + /** + * Test: get_date_paid + */ + function test_get_date_paid() { + $object = new WC_Order(); + $set_to = 'PayPal'; + $object->set_date_paid( '2016-12-12' ); + $this->assertEquals( 1481500800, $object->get_date_paid() ); + + $object->set_date_paid( '1481500800' ); + $this->assertEquals( 1481500800, $object->get_date_paid() ); + } + + /** + * Test: get_cart_hash + */ + function test_get_cart_hash() { + $object = new WC_Order(); + $set_to = '12345'; + $object->set_cart_hash( $set_to ); + $this->assertEquals( $set_to, $object->get_cart_hash() ); + } + + /** + * Test: get_address + */ + function test_get_address() { + $object = new WC_Order(); + + $billing = array( + 'first_name' => 'Fred', + 'last_name' => 'Flintstone', + 'company' => 'Bedrock Ltd.', + 'address_1' => '34 Stonepants avenue', + 'address_2' => 'Rockville', + 'city' => 'Bedrock', + 'state' => 'Boulder', + 'postcode' => '00001', + 'country' => 'US', + 'email' => '', + 'phone' => '', + ); + + $shipping = array( + 'first_name' => 'Barney', + 'last_name' => 'Rubble', + 'company' => 'Bedrock Ltd.', + 'address_1' => '34 Stonepants avenue', + 'address_2' => 'Rockville', + 'city' => 'Bedrock', + 'state' => 'Boulder', + 'postcode' => '00001', + 'country' => 'US', + ); + + $object->set_billing_first_name( 'Fred' ); + $object->set_billing_last_name( 'Flintstone' ); + $object->set_billing_company( 'Bedrock Ltd.' ); + $object->set_billing_address_1( '34 Stonepants avenue' ); + $object->set_billing_address_2( 'Rockville' ); + $object->set_billing_city( 'Bedrock' ); + $object->set_billing_state( 'Boulder' ); + $object->set_billing_postcode( '00001' ); + $object->set_billing_country( 'US' ); + + $object->set_shipping_first_name( 'Barney' ); + $object->set_shipping_last_name( 'Rubble' ); + $object->set_shipping_company( 'Bedrock Ltd.' ); + $object->set_shipping_address_1( '34 Stonepants avenue' ); + $object->set_shipping_address_2( 'Rockville' ); + $object->set_shipping_city( 'Bedrock' ); + $object->set_shipping_state( 'Boulder' ); + $object->set_shipping_postcode( '00001' ); + $object->set_shipping_country( 'US' ); + + $this->assertEquals( $billing, $object->get_address() ); + $this->assertEquals( $shipping, $object->get_address( 'shipping' ) ); + } + + /** + * Test: get_shipping_address_map_url + */ + function test_get_shipping_address_map_url() { + $object = new WC_Order(); + $object->set_shipping_first_name( 'Barney' ); + $object->set_shipping_last_name( 'Rubble' ); + $object->set_shipping_company( 'Bedrock Ltd.' ); + $object->set_shipping_address_1( '34 Stonepants avenue' ); + $object->set_shipping_address_2( 'Rockville' ); + $object->set_shipping_city( 'Bedrock' ); + $object->set_shipping_state( 'Boulder' ); + $object->set_shipping_postcode( '00001' ); + $object->set_shipping_country( 'US' ); + $this->assertEquals( 'http://maps.google.com/maps?&q=Barney%2C+Rubble%2C+Bedrock+Ltd.%2C+34+Stonepants+avenue%2C+Rockville%2C+Bedrock%2C+Boulder%2C+00001%2C+US&z=16', $object->get_shipping_address_map_url() ); + } + + /** + * Test: get_formatted_billing_full_name + */ + function test_get_formatted_billing_full_name() { + $object = new WC_Order(); + $object->set_billing_first_name( 'Fred' ); + $object->set_billing_last_name( 'Flintstone' ); + $this->assertEquals( 'Fred Flintstone', $object->get_formatted_billing_full_name() ); + } + + /** + * Test: get_formatted_shipping_full_name + */ + function test_get_formatted_shipping_full_name() { + $object = new WC_Order(); + $object->set_shipping_first_name( 'Barney' ); + $object->set_shipping_last_name( 'Rubble' ); + $this->assertEquals( 'Barney Rubble', $object->get_formatted_shipping_full_name() ); + } + + /** + * Test: get_formatted_billing_address + */ + function test_get_formatted_billing_address() { + $object = new WC_Order(); + $object->set_billing_first_name( 'Fred' ); + $object->set_billing_last_name( 'Flintstone' ); + $object->set_billing_company( 'Bedrock Ltd.' ); + $object->set_billing_address_1( '34 Stonepants avenue' ); + $object->set_billing_address_2( 'Rockville' ); + $object->set_billing_city( 'Bedrock' ); + $object->set_billing_state( 'Boulder' ); + $object->set_billing_postcode( '00001' ); + $object->set_billing_country( 'US' ); + $this->assertEquals( 'Fred Flintstone
    Bedrock Ltd.
    34 Stonepants avenue
    Rockville
    Bedrock, BOULDER 00001
    United States (US)', $object->get_formatted_billing_address() ); + } + + /** + * Test: get_formatted_shipping_address + */ + function test_get_formatted_shipping_address() { + $object = new WC_Order(); + $object->set_shipping_first_name( 'Barney' ); + $object->set_shipping_last_name( 'Rubble' ); + $object->set_shipping_company( 'Bedrock Ltd.' ); + $object->set_shipping_address_1( '34 Stonepants avenue' ); + $object->set_shipping_address_2( 'Rockville' ); + $object->set_shipping_city( 'Bedrock' ); + $object->set_shipping_state( 'Boulder' ); + $object->set_shipping_postcode( '00001' ); + $object->set_shipping_country( 'US' ); + $this->assertEquals( 'Barney Rubble
    Bedrock Ltd.
    34 Stonepants avenue
    Rockville
    Bedrock, BOULDER 00001
    United States (US)', $object->get_formatted_shipping_address() ); + } } From 9da9d3bf69a31618fc6149c89385d99756d4eddc Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 Jun 2016 15:38:28 +0100 Subject: [PATCH 017/298] Unit test conditional functions --- includes/class-wc-order.php | 2 +- tests/unit-tests/crud/orders.php | 132 +++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 1 deletion(-) diff --git a/includes/class-wc-order.php b/includes/class-wc-order.php index b318793b310..fc01ab35de0 100644 --- a/includes/class-wc-order.php +++ b/includes/class-wc-order.php @@ -1008,7 +1008,7 @@ class WC_Order extends WC_Abstract_Order { * See if order matches cart_hash. * @return bool */ - public function has_cart_hash( $cart_hash ) { + public function has_cart_hash( $cart_hash = '' ) { return hash_equals( $this->get_cart_hash(), $cart_hash ); } diff --git a/tests/unit-tests/crud/orders.php b/tests/unit-tests/crud/orders.php index 50f3faa6220..cf1742c3db3 100644 --- a/tests/unit-tests/crud/orders.php +++ b/tests/unit-tests/crud/orders.php @@ -514,4 +514,136 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case { $object->set_shipping_country( 'US' ); $this->assertEquals( 'Barney Rubble
    Bedrock Ltd.
    34 Stonepants avenue
    Rockville
    Bedrock, BOULDER 00001
    United States (US)', $object->get_formatted_shipping_address() ); } + + /** + * Test: has_cart_hash + */ + function test_has_cart_hash() { + $object = new WC_Order(); + $this->assertFalse( $object->has_cart_hash( '12345' ) ); + $set_to = '12345'; + $object->set_cart_hash( $set_to ); + $this->assertTrue( $object->has_cart_hash( '12345' ) ); + } + + /** + * Test: is_editable + */ + function test_is_editable() { + $object = new WC_Order(); + $object->set_status( 'pending' ); + $this->assertTrue( $object->is_editable() ); + $object->set_status( 'processing' ); + $this->assertFalse( $object->is_editable() ); + } + + /** + * Test: is_paid + */ + function test_is_paid() { + $object = new WC_Order(); + $object->set_status( 'pending' ); + $this->assertFalse( $object->is_paid() ); + $object->set_status( 'processing' ); + $this->assertTrue( $object->is_paid() ); + } + + /** + * Test: is_download_permitted + */ + function test_is_download_permitted() { + $object = new WC_Order(); + $object->set_status( 'pending' ); + $this->assertFalse( $object->is_download_permitted() ); + $object->set_status( 'completed' ); + $this->assertTrue( $object->is_download_permitted() ); + } + + /** + * Test: needs_shipping_address + */ + function test_needs_shipping_address() { + $object = new WC_Order(); + $this->assertFalse( $object->needs_shipping_address() ); + + // @todo + } + + /** + * Test: has_downloadable_item + */ + function test_has_downloadable_item() { + $object = new WC_Order(); + $this->assertFalse( $object->has_downloadable_item() ); + + // @todo + } + + /** + * Test: needs_payment + */ + function test_needs_payment() { + $object = new WC_Order(); + + $object->set_status( 'pending' ); + $this->assertFalse( $object->needs_payment() ); + + $object->set_total( 100 ); + $this->assertTrue( $object->needs_payment() ); + + $object->set_status( 'processing' ); + $this->assertFalse( $object->needs_payment() ); + } + + /** + * Test: get_checkout_payment_url + */ + function test_get_checkout_payment_url() { + $object = new WC_Order(); + $id = $object->save(); + $this->assertEquals( '?order-pay=' . $id . '&pay_for_order=true&key=' . $object->get_order_key(), $object->get_checkout_payment_url() ); + } + + /** + * Test: get_checkout_order_received_url + */ + function test_get_checkout_order_received_url() { + $object = new WC_Order(); + $object->set_order_key( 'xxx' ); + $id = $object->save(); + $this->assertEquals( '?order-received=' . $id . '&key=' . $object->get_order_key(), $object->get_checkout_order_received_url() ); + } + + /** + * Test: get_cancel_order_url + */ + function test_get_cancel_order_url() { + $object = new WC_Order(); + $this->assertInternalType( 'string', $object->get_cancel_order_url() ); + } + + /** + * Test: get_cancel_order_url_raw + */ + function test_get_cancel_order_url_raw() { + $object = new WC_Order(); + $this->assertInternalType( 'string', $object->get_cancel_order_url_raw() ); + } + + /** + * Test: get_cancel_endpoint + */ + function test_get_cancel_endpoint() { + $object = new WC_Order(); + $this->assertEquals( 'http://example.org/', $object->get_cancel_endpoint() ); + } + + /** + * Test: get_view_order_url + */ + function test_get_view_order_url() { + $object = new WC_Order(); + $id = $object->save(); + $this->assertEquals( '?view-order=' . $id, $object->get_view_order_url() ); + } } From 46439ddba56829f5cb786a84ae3aaf7973c76763 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 Jun 2016 16:31:05 +0100 Subject: [PATCH 018/298] Refund unit tests --- includes/abstracts/abstract-wc-order.php | 1 + includes/class-wc-order-refund.php | 64 +++++----- includes/class-wc-order.php | 18 +-- includes/wc-order-functions.php | 4 +- tests/unit-tests/crud/orders.php | 152 ++++++++++++++++++++++- tests/unit-tests/crud/refunds.php | 43 +++++++ 6 files changed, 238 insertions(+), 44 deletions(-) create mode 100644 tests/unit-tests/crud/refunds.php diff --git a/includes/abstracts/abstract-wc-order.php b/includes/abstracts/abstract-wc-order.php index 600c894f47c..d399cea5406 100644 --- a/includes/abstracts/abstract-wc-order.php +++ b/includes/abstracts/abstract-wc-order.php @@ -175,6 +175,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { // Map standard post data $this->set_id( $order_id ); + $this->set_parent_id( $post_object->post_parent ); $this->set_date_created( $post_object->post_date ); $this->set_date_modified( $post_object->post_modified ); $this->set_status( $post_object->post_status ); diff --git a/includes/class-wc-order-refund.php b/includes/class-wc-order-refund.php index bb03580bdee..46f0f5efc62 100644 --- a/includes/class-wc-order-refund.php +++ b/includes/class-wc-order-refund.php @@ -44,11 +44,11 @@ class WC_Order_Refund extends WC_Abstract_Order { } /** - * Read from the database. - * @since 2.7.0 - * @param int $id ID of object to read. - */ - public function read( $id ) { + * Read from the database. + * @since 2.7.0 + * @param int $id ID of object to read. + */ + public function read( $id ) { parent::read( $id ); // Read additonal order data @@ -153,39 +153,39 @@ class WC_Order_Refund extends WC_Abstract_Order { } /** - * Magic __get method for backwards compatibility. - * @param string $key - * @return mixed - */ - public function __get( $key ) { + * Magic __get method for backwards compatibility. + * @param string $key + * @return mixed + */ + public function __get( $key ) { _doing_it_wrong( $key, 'Refund properties should not be accessed directly.', '2.7' ); - /** - * Maps legacy vars to new getters. - */ - if ( 'reason' === $key ) { - return $this->get_refund_reason(); + /** + * Maps legacy vars to new getters. + */ + if ( 'reason' === $key ) { + return $this->get_refund_reason(); } elseif ( 'refund_amount' === $key ) { - return $this->get_refund_amount(); + return $this->get_refund_amount(); } return parent::__get( $key ); } /** - * Gets an refund from the database. - * @deprecated 2.7 - * @param int $id (default: 0). - * @return bool - */ - public function get_refund( $id = 0 ) { - _deprecated_function( 'get_refund', '2.7', 'read' ); - if ( ! $id ) { - return false; - } - if ( $result = get_post( $id ) ) { - $this->populate( $result ); - return true; - } - return false; - } + * Gets an refund from the database. + * @deprecated 2.7 + * @param int $id (default: 0). + * @return bool + */ + public function get_refund( $id = 0 ) { + _deprecated_function( 'get_refund', '2.7', 'read' ); + if ( ! $id ) { + return false; + } + if ( $result = get_post( $id ) ) { + $this->populate( $result ); + return true; + } + return false; + } } diff --git a/includes/class-wc-order.php b/includes/class-wc-order.php index fc01ab35de0..5ba261a7bf4 100644 --- a/includes/class-wc-order.php +++ b/includes/class-wc-order.php @@ -1195,7 +1195,7 @@ class WC_Order extends WC_Abstract_Order { */ /** - * Adds a note (comment) to the order. + * Adds a note (comment) to the order. Order must exist. * * @param string $note Note to add. * @param int $is_customer_note (default: 0) Is this a note for the customer? @@ -1203,6 +1203,10 @@ class WC_Order extends WC_Abstract_Order { * @return int Comment ID. */ public function add_order_note( $note, $is_customer_note = 0, $added_by_user = false ) { + if ( ! $this->get_id() ) { + return 0; + } + if ( is_user_logged_in() && current_user_can( 'edit_shop_order', $this->get_id() ) && $added_by_user ) { $user = get_user_by( 'id', get_current_user_id() ); $comment_author = $user->display_name; @@ -1278,13 +1282,11 @@ class WC_Order extends WC_Abstract_Order { * @return array of WC_Order_Refund objects */ public function get_refunds() { - if ( empty( $this->refunds ) || ! is_array( $this->refunds ) ) { - $this->refunds = wc_get_orders( array( - 'type' => 'shop_order_refund', - 'parent' => $this->get_id(), - 'limit' => -1, - ) ); - } + $this->refunds = wc_get_orders( array( + 'type' => 'shop_order_refund', + 'parent' => $this->get_id(), + 'limit' => -1, + ) ); return $this->refunds; } diff --git a/includes/wc-order-functions.php b/includes/wc-order-functions.php index d0e0c90ed59..c8e004dc471 100644 --- a/includes/wc-order-functions.php +++ b/includes/wc-order-functions.php @@ -849,7 +849,7 @@ function wc_create_refund( $args = array() ) { $order = wc_get_order( $args['order_id'] ); // Refund currency is the same used for the parent order - update_post_meta( $refund_id, '_order_currency', $order->get_order_currency() ); + update_post_meta( $refund_id, '_order_currency', $order->get_currency() ); // Negative line items if ( sizeof( $args['line_items'] ) > 0 ) { @@ -906,7 +906,7 @@ function wc_create_refund( $args = array() ) { $refund->calculate_totals( false ); // Set total to total refunded which may vary from order items - $refund->set_total( wc_format_decimal( $args['amount'] ) * -1, 'total' ); + $refund->set_total( wc_format_decimal( $args['amount'] ) * -1 ); do_action( 'woocommerce_refund_created', $refund_id, $args ); } diff --git a/tests/unit-tests/crud/orders.php b/tests/unit-tests/crud/orders.php index cf1742c3db3..60731dc2217 100644 --- a/tests/unit-tests/crud/orders.php +++ b/tests/unit-tests/crud/orders.php @@ -566,7 +566,8 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case { $object = new WC_Order(); $this->assertFalse( $object->needs_shipping_address() ); - // @todo + $object = WC_Helper_Order::create_order(); + $this->assertTrue( $object->needs_shipping_address() ); } /** @@ -576,7 +577,8 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case { $object = new WC_Order(); $this->assertFalse( $object->has_downloadable_item() ); - // @todo + $object = WC_Helper_Order::create_order(); + $this->assertFalse( $object->has_downloadable_item() ); } /** @@ -646,4 +648,150 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case { $id = $object->save(); $this->assertEquals( '?view-order=' . $id, $object->get_view_order_url() ); } + + /** + * Test: add_order_note + */ + function test_add_order_note() { + $object = new WC_Order(); + $id = $object->save(); + $comment_id = $object->add_order_note( "Hello, I am a fish" ); + $this->assertTrue( $comment_id > 0 ); + + $comment = get_comment( $comment_id ); + $this->assertEquals( "Hello, I am a fish", $comment->comment_content ); + } + + /** + * Test: get_customer_order_notes + */ + function test_get_customer_order_notes() { + $object = new WC_Order(); + $id = $object->save(); + + $this->assertCount( 0, $object->get_customer_order_notes() ); + + $object->add_order_note( "Hello, I am a fish", true ); + $object->add_order_note( "Hello, I am a fish", false ); + $object->add_order_note( "Hello, I am a fish", true ); + + $this->assertCount( 2, $object->get_customer_order_notes() ); + } + + /** + * Test: get_refunds + */ + function test_get_refunds() { + $object = new WC_Order(); + $id = $object->save(); + + $this->assertCount( 0, $object->get_refunds() ); + + wc_create_refund( array( + 'order_id' => $id, + 'amount' => '100', + 'line_items' => array(), + ) ); + + $this->assertCount( 1, $object->get_refunds() ); + } + + /** + * Test: get_total_refunded + */ + function test_get_total_refunded() { + $object = new WC_Order(); + $object->set_total( 400 ); + $id = $object->save(); + wc_create_refund( array( + 'order_id' => $id, + 'amount' => '100', + 'line_items' => array(), + ) ); + wc_create_refund( array( + 'order_id' => $id, + 'amount' => '100', + 'line_items' => array(), + ) ); + $this->assertEquals( 200, $object->get_total_refunded() ); + } + + /** + * Test: get_total_tax_refunded + */ + function test_get_total_tax_refunded() { + $object = new WC_Order(); + $this->assertEquals( 0, $object->get_total_tax_refunded() ); + } + + /** + * Test: get_total_shipping_refunded + */ + function test_get_total_shipping_refunded() { + $object = new WC_Order(); + $this->assertEquals( 0, $object->get_total_shipping_refunded() ); + } + + /** + * Test: get_total_shipping_refunded + */ + function test_get_total_qty_refunded() { + $object = new WC_Order(); + $this->assertEquals( 0, $object->get_total_shipping_refunded() ); + } + + /** + * Test: get_qty_refunded_for_item + */ + function test_get_qty_refunded_for_item() { + $object = new WC_Order(); + $this->assertEquals( 0, $object->get_qty_refunded_for_item( 2 ) ); + } + + /** + * Test: test_get_total_refunded_for_item + */ + function test_get_total_refunded_for_item() { + $object = new WC_Order(); + $this->assertEquals( 0, $object->get_total_refunded_for_item( 2 ) ); + } + + /** + * Test: get_tax_refunded_for_item + */ + function test_get_tax_refunded_for_item() { + $object = new WC_Order(); + $this->assertEquals( 0, $object->get_tax_refunded_for_item( 1, 1 ) ); + } + + /** + * Test: get_total_tax_refunded_by_rate_id + */ + function test_get_total_tax_refunded_by_rate_id() { + $object = new WC_Order(); + $this->assertEquals( 0, $object->get_total_tax_refunded_by_rate_id( 2 ) ); + } + + /** + * Test: get_remaining_refund_amount + */ + function test_get_remaining_refund_amount() { + $object = new WC_Order(); + $object->set_total( 400 ); + $id = $object->save(); + wc_create_refund( array( + 'order_id' => $id, + 'amount' => '100', + 'line_items' => array(), + ) ); + $this->assertEquals( 300, $object->get_remaining_refund_amount() ); + } + + /** + * Test: get_total_tax_refunded_by_rate_id + */ + function test_get_remaining_refund_items() { + $object = WC_Helper_Order::create_order(); + $this->assertEquals( 4, $object->get_remaining_refund_items() ); + } } diff --git a/tests/unit-tests/crud/refunds.php b/tests/unit-tests/crud/refunds.php new file mode 100644 index 00000000000..38f077ef62d --- /dev/null +++ b/tests/unit-tests/crud/refunds.php @@ -0,0 +1,43 @@ +assertEquals( 'shop_order_refund', $object->get_type() ); + } + + /** + * Test: get_refund_amount + */ + function test_get_refund_amount() { + $object = new WC_Order_Refund(); + $object->set_refund_amount( 20 ); + $this->assertEquals( '20.00', $object->get_refund_amount() ); + } + + /** + * Test: get_refund_reason + */ + function test_get_refund_reason() { + $object = new WC_Order_Refund(); + $object->set_refund_reason( 'Customer is an idiot' ); + $this->assertEquals( 'Customer is an idiot', $object->get_refund_reason() ); + } + + /** + * Test: get_refunded_by + */ + function test_get_refunded_by() { + $object = new WC_Order_Refund(); + $object->set_refunded_by( 1 ); + $this->assertEquals( 1, $object->get_refunded_by() ); + } +} From 13d293dd255f09653d47bf8c58fa30632f265da6 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 22 Jun 2016 17:02:22 +0100 Subject: [PATCH 019/298] abstract total unit tests --- tests/unit-tests/crud/orders.php | 221 +++++++++++++++++++++++++++++++ 1 file changed, 221 insertions(+) diff --git a/tests/unit-tests/crud/orders.php b/tests/unit-tests/crud/orders.php index 60731dc2217..0ddb3d9eaed 100644 --- a/tests/unit-tests/crud/orders.php +++ b/tests/unit-tests/crud/orders.php @@ -14,6 +14,227 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case { $this->assertEquals( 'shop_order', $object->get_type() ); } + /** + * Test: get_type + */ + function test_get_order_type() { + $object = new WC_Order(); + $id = $object->save(); + $this->assertEquals( 'shop_order', $object->get_order_type() ); + } + + /** + * Test: get_data + */ + function test_get_data() { + $object = new WC_Order(); + $this->assertInternalType( 'array', $object->get_data() ); + } + + /** + * Test: get_id + */ + function test_get_id() { + $object = new WC_Order(); + $id = $object->save(); + $this->assertEquals( $id, $object->get_id() ); + } + + /** + * Test: get_parent_id + */ + function test_get_parent_id() { + $object = new WC_Order(); + $set_to = 100; + $object->set_parent_id( $set_to ); + $this->assertEquals( $set_to, $object->get_parent_id() ); + } + + /** + * Test: get_order_number + */ + function test_get_order_number() { + $object = new WC_Order(); + $id = $object->save(); + $this->assertEquals( $id, $object->get_order_number() ); + } + + /** + * Test: get_order_key + */ + function test_get_order_key() { + $object = new WC_Order(); + $set_to = 'some_key'; + $object->set_order_key( $set_to ); + $this->assertEquals( $set_to, $object->get_order_key() ); + } + + /** + * Test: get_currency + */ + function test_get_currency() { + $object = new WC_Order(); + $set_to = 'USD'; + $object->set_currency( $set_to ); + $this->assertEquals( $set_to, $object->get_currency() ); + } + + /** + * Test: get_version + */ + function test_get_version() { + $object = new WC_Order(); + $set_to = '2.7.0'; + $object->set_version( $set_to ); + $this->assertEquals( $set_to, $object->get_version() ); + } + + /** + * Test: get_prices_include_tax + */ + function test_get_prices_include_tax() { + $object = new WC_Order(); + $set_to = 'USD'; + $object->set_prices_include_tax( 1 ); + $this->assertEquals( true, $object->get_prices_include_tax() ); + } + + /** + * Test: get_date_created + */ + function test_get_date_created() { + $object = new WC_Order(); + $object->set_date_created( '2016-12-12' ); + $this->assertEquals( '1481500800', $object->get_date_created() ); + + $object->set_date_created( '1481500800' ); + $this->assertEquals( 1481500800, $object->get_date_created() ); + } + + /** + * Test: get_date_modified + */ + function test_get_date_modified() { + $object = new WC_Order(); + $object->set_date_modified( '2016-12-12' ); + $this->assertEquals( '1481500800', $object->get_date_modified() ); + + $object->set_date_modified( '1481500800' ); + $this->assertEquals( 1481500800, $object->get_date_modified() ); + } + + /** + * Test: get_customer_id + */ + function test_get_customer_id() { + $object = new WC_Order(); + $set_to = 10; + $object->set_customer_id( $set_to ); + $this->assertEquals( $set_to, $object->get_customer_id() ); + } + + /** + * Test: get_user + */ + function test_get_user() { + $object = new WC_Order(); + $this->assertEquals( false, $object->get_user() ); + $set_to = '1'; + $object->set_customer_id( $set_to ); + $this->assertInstanceOf( 'WP_User', $object->get_user() ); + } + + /** + * Test: get_discount_total + */ + function test_get_discount_total() { + $object = new WC_Order(); + $object->set_discount_total( 50 ); + $this->assertEquals( 50, $object->get_discount_total() ); + } + + /** + * Test: get_discount_tax + */ + function test_get_discount_tax() { + $object = new WC_Order(); + $object->set_discount_tax( 5 ); + $this->assertEquals( 5, $object->get_discount_tax() ); + } + + /** + * Test: get_shipping_total + */ + function test_get_shipping_total() { + $object = new WC_Order(); + $object->set_shipping_total( 5 ); + $this->assertEquals( 5, $object->get_shipping_total() ); + } + + /** + * Test: get_shipping_tax + */ + function test_get_shipping_tax() { + $object = new WC_Order(); + $object->set_shipping_tax( 5 ); + $this->assertEquals( 5, $object->get_shipping_tax() ); + } + + /** + * Test: get_cart_tax + */ + function test_get_cart_tax() { + $object = new WC_Order(); + $object->set_cart_tax( 5 ); + $this->assertEquals( 5, $object->get_cart_tax() ); + } + + /** + * Test: get_total + */ + function test_get_total() { + $object = new WC_Order(); + $object->set_total( 5 ); + $this->assertEquals( 5, $object->get_total() ); + } + + /** + * Test: get_total_tax + */ + function test_get_total_tax() { + $object = new WC_Order(); + $object->set_cart_tax( 5 ); + $object->set_shipping_tax( 5 ); + $this->assertEquals( 10, $object->get_total_tax() ); + } + + /** + * Test: get_total_discount + */ + function test_get_total_discount() { + $object = new WC_Order(); + $object->set_discount_total( 50 ); + $object->set_discount_tax( 5 ); + $this->assertEquals( 50, $object->get_total_discount() ); + $this->assertEquals( 55, $object->get_total_discount( false ) ); + } + + /** + * Test: get_subtotal + */ + function test_get_subtotal() { + $object = WC_Helper_Order::create_order(); + $this->assertEquals( 40, $object->get_subtotal() ); + } + + /** + * Test: get_tax_totals + */ + function test_get_tax_totals() { + $object = WC_Helper_Order::create_order(); + $this->assertEquals( array(), $object->get_tax_totals() ); + } + /** * Test: CRUD */ From a22859ae32acff9e4a9fd37b2e16678170ebe634 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 23 Jun 2016 15:52:12 +0100 Subject: [PATCH 020/298] Abstract unit tests --- includes/abstracts/abstract-wc-order.php | 8 +- tests/unit-tests/crud/orders.php | 305 +++++++++++++++++++++++ 2 files changed, 312 insertions(+), 1 deletion(-) diff --git a/includes/abstracts/abstract-wc-order.php b/includes/abstracts/abstract-wc-order.php index d399cea5406..7243a565f10 100644 --- a/includes/abstracts/abstract-wc-order.php +++ b/includes/abstracts/abstract-wc-order.php @@ -822,7 +822,13 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { * @return array */ public function get_used_coupons() { - return array_map( 'trim', wp_list_pluck( $this->get_items( 'coupon' ), 'name' ) ); + $coupon_codes = array(); + if ( $coupons = $this->get_items( 'coupon' ) ) { + foreach ( $coupons as $coupon ) { + $coupon_codes[] = $coupon->get_code(); + } + } + return $coupon_codes; } /** diff --git a/tests/unit-tests/crud/orders.php b/tests/unit-tests/crud/orders.php index 0ddb3d9eaed..06ec2e91cb5 100644 --- a/tests/unit-tests/crud/orders.php +++ b/tests/unit-tests/crud/orders.php @@ -235,6 +235,311 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case { $this->assertEquals( array(), $object->get_tax_totals() ); } + /** + * Test: remove_order_items + */ + function test_remove_order_items() { + $product = WC_Helper_Product::create_simple_product(); + $object = new WC_Order(); + $object->save(); + $item_id = $object->add_product( $product, array( 'qty' => 4 ) ); + $item_id = $object->add_product( $product, array( 'qty' => 2 ) ); + $this->assertCount( 2, $object->get_items() ); + $object->remove_order_items(); + $this->assertCount( 0, $object->get_items() ); + } + + /** + * Test: get_items + */ + function test_get_items() { + $object = new WC_Order(); + $object->save(); + $object->add_product( WC_Helper_Product::create_simple_product(), array( 'qty' => 4 ) ); + $object->add_product( WC_Helper_Product::create_simple_product(), array( 'qty' => 2 ) ); + $this->assertCount( 2, $object->get_items() ); + } + + /** + * Test: get_fees + */ + function test_get_fees() { + $object = new WC_Order(); + $object->save(); + $object->add_fee( (object) array( + 'name' => 'Some Fee', + 'taxable' => true, + 'amount' => '100', + 'tax_class' => '', + 'tax' => '', + 'tax_data' => '', + ) ); + $this->assertCount( 1, $object->get_fees() ); + } + + /** + * Test: get_taxes + */ + function test_get_taxes() { + global $wpdb; + + update_option( 'woocommerce_calc_taxes', 'yes' ); + $tax_rate = array( + 'tax_rate_country' => '', + 'tax_rate_state' => '', + 'tax_rate' => '10.0000', + 'tax_rate_name' => 'TAX', + 'tax_rate_priority' => '1', + 'tax_rate_compound' => '0', + 'tax_rate_shipping' => '1', + 'tax_rate_order' => '1', + 'tax_rate_class' => '' + ); + WC_Tax::_insert_tax_rate( $tax_rate ); + + $object = new WC_Order(); + $object->save(); + $object->add_product( WC_Helper_Product::create_simple_product(), array( 'qty' => 4 ) ); + $object->calculate_totals(); + $this->assertCount( 1, $object->get_taxes() ); + + $object->add_tax( + array( + 'rate_id' => '100', + 'tax_total' => '100', + 'shipping_tax_total' => '0', + ) + ); + + $this->assertCount( 2, $object->get_taxes() ); + + // Cleanup + $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rates" ); + $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations" ); + update_option( 'woocommerce_calc_taxes', 'no' ); + } + + /** + * Test: get_shipping_methods + */ + function test_get_shipping_methods() { + $object = new WC_Order(); + $object->save(); + $object->add_shipping( new WC_Shipping_Rate( 'flat_rate_shipping', 'Flat rate shipping', '10', array(), 'flat_rate' ) ); + $this->assertCount( 1, $object->get_shipping_methods() ); + } + + /** + * Test: get_shipping_method + */ + function test_get_shipping_method() { + $object = new WC_Order(); + $object->save(); + $object->add_shipping( new WC_Shipping_Rate( 'flat_rate_shipping', 'Flat rate shipping', '10', array(), 'flat_rate' ) ); + $this->assertEquals( 'Flat rate shipping', $object->get_shipping_method() ); + $object->add_shipping( new WC_Shipping_Rate( 'flat_rate_shipping', 'Flat rate shipping 2', '10', array(), 'flat_rate' ) ); + $this->assertEquals( 'Flat rate shipping, Flat rate shipping 2', $object->get_shipping_method() ); + } + + /** + * Test: get_used_coupons + */ + function test_get_used_coupons() { + $object = new WC_Order(); + $object->save(); + $object->add_coupon( + array( + 'code' => '12345', + 'discount' => '10', + 'discount_tax' => '5', + ) + ); + $this->assertCount( 1, $object->get_used_coupons() ); + } + + /** + * Test: get_item_count + */ + function test_get_item_count() { + $object = new WC_Order(); + $object->save(); + $object->add_product( WC_Helper_Product::create_simple_product(), array( 'qty' => 4 ) ); + $object->add_product( WC_Helper_Product::create_simple_product(), array( 'qty' => 2 ) ); + $this->assertEquals( 6, $object->get_item_count() ); + } + + /** + * Test: get_item + */ + function test_get_item() { + $object = new WC_Order(); + $object->save(); + + $item_id = $object->add_product( WC_Helper_Product::create_simple_product(), array( 'qty' => 4 ) ); + $this->assertTrue( $object->get_item( $item_id ) instanceOf WC_Order_Item_Product ); + + $item_id = $object->add_coupon( + array( + 'code' => '12345', + 'discount' => '10', + 'discount_tax' => '5', + ) + ); + $this->assertTrue( $object->get_item( $item_id ) instanceOf WC_Order_Item_Coupon ); + } + + /** + * Test: add_payment_token + */ + function test_add_payment_token() { + $object = new WC_Order(); + $object->save(); + $this->assertFalse( $object->add_payment_token( 'fish' ) ); + $token = new WC_Payment_Token_Stub(); + $token->set_extra( __FUNCTION__ ); + $token->set_token( time() ); + $token->create(); + $this->assertTrue( 0 < $object->add_payment_token( $token ) ); + } + + /** + * Test: get_payment_tokens + */ + function test_get_payment_tokens() { + $object = new WC_Order(); + $object->save(); + $token = new WC_Payment_Token_Stub(); + $token->set_extra( __FUNCTION__ ); + $token->set_token( time() ); + $token->create(); + $object->add_payment_token( $token ); + $this->assertCount( 1, $object->get_payment_tokens() ); + } + + /** + * Test: calculate_shipping + */ + function test_calculate_shipping() { + $object = new WC_Order(); + $object->save(); + $object->add_shipping( new WC_Shipping_Rate( 'flat_rate_shipping', 'Flat rate shipping', '10', array(), 'flat_rate' ) ); + $object->add_shipping( new WC_Shipping_Rate( 'flat_rate_shipping', 'Flat rate shipping', '10', array(), 'flat_rate' ) ); + $object->calculate_shipping(); + $this->assertEquals( 20, $object->get_shipping_total() ); + } + + /** + * Test: calculate_taxes + */ + function test_calculate_taxes() { + global $wpdb; + update_option( 'woocommerce_calc_taxes', 'yes' ); + $tax_rate = array( + 'tax_rate_country' => '', + 'tax_rate_state' => '', + 'tax_rate' => '10.0000', + 'tax_rate_name' => 'TAX', + 'tax_rate_priority' => '1', + 'tax_rate_compound' => '0', + 'tax_rate_shipping' => '1', + 'tax_rate_order' => '1', + 'tax_rate_class' => '' + ); + WC_Tax::_insert_tax_rate( $tax_rate ); + + $object = new WC_Order(); + $object->save(); + $object->add_product( WC_Helper_Product::create_simple_product(), array( 'qty' => 4 ) ); + $object->add_shipping( new WC_Shipping_Rate( 'flat_rate_shipping', 'Flat rate shipping', '10', array(), 'flat_rate' ) ); + $object->calculate_taxes(); + $this->assertEquals( 5, $object->get_total_tax() ); + + // Cleanup + $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rates" ); + $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations" ); + update_option( 'woocommerce_calc_taxes', 'no' ); + } + + /** + * Test: calculate_totals + */ + function test_calculate_totals() { + global $wpdb; + update_option( 'woocommerce_calc_taxes', 'yes' ); + $tax_rate = array( + 'tax_rate_country' => '', + 'tax_rate_state' => '', + 'tax_rate' => '10.0000', + 'tax_rate_name' => 'TAX', + 'tax_rate_priority' => '1', + 'tax_rate_compound' => '0', + 'tax_rate_shipping' => '1', + 'tax_rate_order' => '1', + 'tax_rate_class' => '' + ); + WC_Tax::_insert_tax_rate( $tax_rate ); + + $object = new WC_Order(); + $object->save(); + $object->add_product( WC_Helper_Product::create_simple_product(), array( 'qty' => 4 ) ); + $object->add_shipping( new WC_Shipping_Rate( 'flat_rate_shipping', 'Flat rate shipping', '10', array(), 'flat_rate' ) ); + $object->calculate_totals(); + $this->assertEquals( 55, $object->get_total() ); + + // Cleanup + $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rates" ); + $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations" ); + update_option( 'woocommerce_calc_taxes', 'no' ); + } + + /** + * Test: has_status + */ + function test_has_status() { + $object = new WC_Order(); + $this->assertFalse( $object->has_status( 'completed' ) ); + $this->assertFalse( $object->has_status( array( 'processing', 'completed' ) ) ); + $this->assertTrue( $object->has_status( 'pending' ) ); + $this->assertTrue( $object->has_status( array( 'processing', 'pending' ) ) ); + } + + /** + * Test: has_shipping_method + */ + function test_has_shipping_method() { + $object = new WC_Order(); + $object->save(); + $this->assertFalse( $object->has_shipping_method( 'flat_rate_shipping' ) ); + $object->add_shipping( new WC_Shipping_Rate( 'flat_rate_shipping', 'Flat rate shipping', '10', array(), 'flat_rate' ) ); + $this->assertTrue( $object->has_shipping_method( 'flat_rate_shipping' ) ); + } + + /** + * Test: key_is_valid + */ + function test_key_is_valid() { + $object = new WC_Order(); + $object->save(); + $this->assertFalse( $object->key_is_valid( '1234' ) ); + $object->set_order_key( '1234' ); + $this->assertTrue( $object->key_is_valid( '1234' ) ); + } + + /** + * Test: has_free_item + */ + function test_has_free_item() { + $object = new WC_Order(); + $object->save(); + $object->add_product( WC_Helper_Product::create_simple_product(), array( 'qty' => 4 ) ); + $this->assertFalse( $object->has_free_item() ); + + $free_product = WC_Helper_Product::create_simple_product(); + $free_product->set_price( 0 ); + $object->add_product( $free_product, array( 'qty' => 4 ) ); + $this->assertTrue( $object->has_free_item() ); + } + /** * Test: CRUD */ From 5275a2663a5cbcdd1323fee1f6bc5d6ee7f53a58 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 23 Jun 2016 16:07:35 +0100 Subject: [PATCH 021/298] check if empty --- includes/abstracts/abstract-wc-order.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/includes/abstracts/abstract-wc-order.php b/includes/abstracts/abstract-wc-order.php index 7243a565f10..a594f94602c 100644 --- a/includes/abstracts/abstract-wc-order.php +++ b/includes/abstracts/abstract-wc-order.php @@ -776,7 +776,12 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { global $wpdb; $get_items_sql = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = %d ", $this->get_id() ) . "AND order_item_type IN ( '" . implode( "','", array_map( 'esc_sql', (array) $type ) ) . "' ) ORDER BY order_item_id;"; $items = $wpdb->get_results( $get_items_sql ); - $items = array_map( array( $this, 'get_item' ), array_combine( wp_list_pluck( $items, 'order_item_id' ), $items ) ); + + if ( ! empty( $items ) ) { + $items = array_map( array( $this, 'get_item' ), array_combine( wp_list_pluck( $items, 'order_item_id' ), $items ) ); + } else { + $items = array(); + } return apply_filters( 'woocommerce_order_get_items', $items, $this ); } From b11794ceacc1f1a30f5c2cf64feba4892eb33b07 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 29 Jun 2016 12:58:38 +0100 Subject: [PATCH 022/298] @Since changes --- includes/abstracts/abstract-wc-legacy-order.php | 7 ------- includes/class-wc-order.php | 9 +-------- includes/wc-order-functions.php | 8 ++++---- includes/wc-template-functions.php | 2 ++ 4 files changed, 7 insertions(+), 19 deletions(-) diff --git a/includes/abstracts/abstract-wc-legacy-order.php b/includes/abstracts/abstract-wc-legacy-order.php index 8f4076373e3..d9baa87f5b6 100644 --- a/includes/abstracts/abstract-wc-legacy-order.php +++ b/includes/abstracts/abstract-wc-legacy-order.php @@ -21,7 +21,6 @@ abstract class WC_Abstract_Legacy_Order extends WC_Data { * * Note this does not update order totals. * - * @since 2.2 * @param object|int $item order item ID or item object. * @param WC_Product $product * @param array $args data to update. @@ -71,7 +70,6 @@ abstract class WC_Abstract_Legacy_Order extends WC_Data { /** * Update coupon for order. Note this does not update order totals. - * @since 2.2 * @param object|int $item * @param array $args * @return int updated order item ID @@ -110,7 +108,6 @@ abstract class WC_Abstract_Legacy_Order extends WC_Data { * * Note this does not update the order total. * - * @since 2.2 * @param object|int $item * @param array $args * @return int updated order item ID @@ -147,7 +144,6 @@ abstract class WC_Abstract_Legacy_Order extends WC_Data { * * Note this does not update order totals. * - * @since 2.2 * @param object|int $item * @param array $args * @return int updated order item ID @@ -220,7 +216,6 @@ abstract class WC_Abstract_Legacy_Order extends WC_Data { /** * Set the customer address. - * @since 2.2.0 * @param array $address Address data. * @param string $type billing or shipping. */ @@ -235,7 +230,6 @@ abstract class WC_Abstract_Legacy_Order extends WC_Data { /** * Set an order total. - * @since 2.2.0 * @param float $amount * @param string $total_type * @return bool @@ -499,7 +493,6 @@ abstract class WC_Abstract_Legacy_Order extends WC_Data { * Expand item meta into the $item array. * @deprecated 2.7.0 Item meta no longer expanded due to new order item * classes. This function now does nothing to avoid data breakage. - * @since 2.4.0 * @param array $item before expansion. * @return array */ diff --git a/includes/class-wc-order.php b/includes/class-wc-order.php index 5ba261a7bf4..e6a7fbd51c2 100644 --- a/includes/class-wc-order.php +++ b/includes/class-wc-order.php @@ -508,7 +508,7 @@ class WC_Order extends WC_Abstract_Order { * @return string */ public function get_billing_email() { - return sanitize_email( $this->_data['billing']['email'] ); + return $this->_data['billing']['email']; } /** @@ -685,9 +685,6 @@ class WC_Order extends WC_Abstract_Order { /** * Get a formatted billing full name. - * - * @since 2.4.0 - * * @return string */ public function get_formatted_billing_full_name() { @@ -696,9 +693,6 @@ class WC_Order extends WC_Abstract_Order { /** * Get a formatted shipping full name. - * - * @since 2.4.0 - * * @return string */ public function get_formatted_shipping_full_name() { @@ -908,7 +902,6 @@ class WC_Order extends WC_Abstract_Order { /** * Set the payment method. - * @since 2.2.0 * @param string $payment_method Supports WC_Payment_Gateway for bw compatibility with < 2.7 */ public function set_payment_method( $payment_method = '' ) { diff --git a/includes/wc-order-functions.php b/includes/wc-order-functions.php index c8e004dc471..f98f722f130 100644 --- a/includes/wc-order-functions.php +++ b/includes/wc-order-functions.php @@ -1059,7 +1059,7 @@ function wc_order_search( $term ) { /** * Update total sales amount for each product within a paid order. * - * @since 2.6.0 + * @since 2.7.0 * @param int $order_id */ function wc_update_total_sales_counts( $order_id ) { @@ -1093,7 +1093,7 @@ add_action( 'woocommerce_order_status_on-hold', 'wc_update_total_sales_counts' ) /** * Update used coupon amount for each coupon within an order. * - * @since 2.6.0 + * @since 2.7.0 * @param int $order_id */ function wc_update_coupon_usage_counts( $order_id ) { @@ -1144,7 +1144,7 @@ add_action( 'woocommerce_order_status_cancelled', 'wc_update_total_sales_counts' /** * When a payment is complete, we can reduce stock levels for items within an order. - * @since 2.6.0 + * @since 2.7.0 * @param int $order_id */ function wc_maybe_reduce_stock_levels( $order_id ) { @@ -1157,7 +1157,7 @@ add_action( 'woocommerce_payment_complete', 'wc_maybe_reduce_stock_levels' ); /** * Reduce stock levels for items within an order. - * @since 2.6.0 + * @since 2.7.0 * @param int $order_id */ function wc_reduce_stock_levels( $order_id ) { diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 80202307ce3..30b0efed763 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -2255,6 +2255,7 @@ if ( ! function_exists( 'wc_get_email_order_items' ) ) { if ( ! function_exists( 'wc_display_item_meta' ) ) { /** * Display item meta data. + * @since 2.7.0 * @param WC_Item $item * @param array $args * @return string|void @@ -2295,6 +2296,7 @@ if ( ! function_exists( 'wc_display_item_meta' ) ) { if ( ! function_exists( 'wc_display_item_downloads' ) ) { /** * Display item download links. + * @since 2.7.0 * @param WC_Item $item * @param array $args * @return string|void From 26353d7099d270064bee97ef11acdcd4f6390d13 Mon Sep 17 00:00:00 2001 From: toddlahman Date: Sat, 2 Jul 2016 23:16:11 -0700 Subject: [PATCH 023/298] added remove method to logger class, and delete GeoIP Log button to tools --- includes/admin/class-wc-admin-status.php | 15 ++++++++++++++ includes/class-wc-logger.php | 25 +++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/includes/admin/class-wc-admin-status.php b/includes/admin/class-wc-admin-status.php index c65b590347f..e8eec80646b 100644 --- a/includes/admin/class-wc-admin-status.php +++ b/includes/admin/class-wc-admin-status.php @@ -119,6 +119,16 @@ class WC_Admin_Status { echo '

    ' . __( 'Usage tracking settings successfully reset.', 'woocommerce' ) . '

    '; break; + case 'delete_geoip_log' : + $logger = new WC_Logger(); + $deleted = $logger->remove( 'geoip' ); + + if ( $deleted ) { + echo '

    ' . __( 'GeoIP Log successfully deleted.', 'woocommerce' ) . '

    '; + } else { + echo '

    ' . __( 'There was an error deleting the GeoIP Log.', 'woocommerce' ) . '

    '; + } + break; default : $action = esc_attr( $_GET['action'] ); if ( isset( $tools[ $action ]['callback'] ) ) { @@ -186,6 +196,11 @@ class WC_Admin_Status { 'name' => __( 'Reset Usage Tracking Settings', 'woocommerce' ), 'button' => __( 'Reset usage tracking settings', 'woocommerce' ), 'desc' => __( 'This will reset your usage tracking settings, causing it to show the opt-in banner again and not sending any data.', 'woocommerce' ), + ), + 'delete_geoip_log' => array( + 'name' => __( 'Delete GeoIP Log', 'woocommerce' ), + 'button' => __( 'Delete GeoIP Log', 'woocommerce' ), + 'desc' => __( 'This will delete the GeoIP log created by WooCommerce.', 'woocommerce' ), ) ); diff --git a/includes/class-wc-logger.php b/includes/class-wc-logger.php index 7a6c19c05b5..ebb69cc2b91 100644 --- a/includes/class-wc-logger.php +++ b/includes/class-wc-logger.php @@ -124,4 +124,27 @@ class WC_Logger { return $result; } -} + /** + * Remove/delete the chosen file. + * + * @param string $handle + * + * @return bool + */ + public function remove( $handle ) { + $removed = false; + $file = wc_get_log_file_path( $handle ); + + if ( is_file( $file ) && is_writable( $file ) ) { + // Close first to be certain no processes keep it alive after it is unlinked. + $this->close( $handle ); + + $removed = unlink( $file ); + } + + do_action( 'woocommerce_log_remove', $handle, $removed ); + + return $removed; + } + +} \ No newline at end of file From 4b5af405362cb9093aceacb620437fd278941519 Mon Sep 17 00:00:00 2001 From: toddlahman Date: Mon, 4 Jul 2016 17:10:17 -0700 Subject: [PATCH 024/298] add button to delete any log file --- includes/admin/class-wc-admin-status.php | 43 ++++++++++++++----- .../views/html-admin-page-status-logs.php | 3 ++ 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/includes/admin/class-wc-admin-status.php b/includes/admin/class-wc-admin-status.php index e8eec80646b..2e7e162dd7b 100644 --- a/includes/admin/class-wc-admin-status.php +++ b/includes/admin/class-wc-admin-status.php @@ -119,16 +119,6 @@ class WC_Admin_Status { echo '

    ' . __( 'Usage tracking settings successfully reset.', 'woocommerce' ) . '

    '; break; - case 'delete_geoip_log' : - $logger = new WC_Logger(); - $deleted = $logger->remove( 'geoip' ); - - if ( $deleted ) { - echo '

    ' . __( 'GeoIP Log successfully deleted.', 'woocommerce' ) . '

    '; - } else { - echo '

    ' . __( 'There was an error deleting the GeoIP Log.', 'woocommerce' ) . '

    '; - } - break; default : $action = esc_attr( $_GET['action'] ); if ( isset( $tools[ $action ]['callback'] ) ) { @@ -220,6 +210,12 @@ class WC_Admin_Status { $viewed_log = current( $logs ); } + $handle = ! empty( $viewed_log ) ? self::get_log_file_handle( $viewed_log ) : ''; + + if ( ! empty( $_REQUEST[ 'handle' ] ) ) { + self::remove_log(); + } + include_once( 'views/html-admin-page-status-logs.php' ); } @@ -255,6 +251,16 @@ class WC_Admin_Status { return $version ; } + /** + * Return the log file handle. + * + * @param string $filename + * @return string + */ + public static function get_log_file_handle( $filename ) { + return substr( $filename, 0, strlen( $filename ) > 37 ? strlen( $filename ) - 37 : strlen( $filename ) - 4 ); + } + /** * Scan the template files. * @param string $template_path @@ -357,4 +363,21 @@ class WC_Admin_Status { return $update_theme_version; } + + /** + * Remove/delete the chosen file. + */ + public function remove_log() { + if ( empty( $_REQUEST[ '_wpnonce' ] ) || ! wp_verify_nonce( $_REQUEST[ '_wpnonce' ], 'remove_log' ) ) { + wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) ); + } + + if ( ! empty( $_REQUEST[ 'handle' ] ) ) { + $logger = new WC_Logger(); + $logger->remove( $_REQUEST[ 'handle' ] ); + } + + wp_safe_redirect( esc_url_raw( admin_url( 'admin.php?page=wc-status&tab=logs' ) ) ); + exit(); + } } diff --git a/includes/admin/views/html-admin-page-status-logs.php b/includes/admin/views/html-admin-page-status-logs.php index 4f2ef9461e9..b53b80a8166 100644 --- a/includes/admin/views/html-admin-page-status-logs.php +++ b/includes/admin/views/html-admin-page-status-logs.php @@ -21,6 +21,9 @@ if ( ! defined( 'ABSPATH' ) ) { + + +
    From 043eecedc505773ac6d57ce20177098199cef3e0 Mon Sep 17 00:00:00 2001 From: andyexeter Date: Wed, 6 Jul 2016 00:15:39 +0100 Subject: [PATCH 025/298] Add NOT IN operator to WC_Admin_Report::get_order_report_data() --- includes/admin/reports/class-wc-admin-report.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/includes/admin/reports/class-wc-admin-report.php b/includes/admin/reports/class-wc-admin-report.php index 6b0d76cb628..fdd705a30c6 100644 --- a/includes/admin/reports/class-wc-admin-report.php +++ b/includes/admin/reports/class-wc-admin-report.php @@ -242,14 +242,14 @@ class WC_Admin_Report { $key = is_array( $value['meta_key'] ) ? $value['meta_key'][0] . '_array' : $value['meta_key']; - if ( strtolower( $value['operator'] ) == 'in' ) { + if ( strtolower( $value['operator'] ) == 'in' || strtolower( $value['operator'] ) == 'not in' ) { if ( is_array( $value['meta_value'] ) ) { $value['meta_value'] = implode( "','", $value['meta_value'] ); } if ( ! empty( $value['meta_value'] ) ) { - $where_value = "IN ('{$value['meta_value']}')"; + $where_value = "{$value['operator']} ('{$value['meta_value']}')"; } } else { $where_value = "{$value['operator']} '{$value['meta_value']}'"; @@ -289,14 +289,14 @@ class WC_Admin_Report { foreach ( $where as $value ) { - if ( strtolower( $value['operator'] ) == 'in' ) { + if ( strtolower( $value['operator'] ) == 'in' || strtolower( $value['operator'] ) == 'not in' ) { if ( is_array( $value['value'] ) ) { $value['value'] = implode( "','", $value['value'] ); } if ( ! empty( $value['value'] ) ) { - $where_value = "IN ('{$value['value']}')"; + $where_value = "{$value['operator']} ('{$value['value']}')"; } } else { $where_value = "{$value['operator']} '{$value['value']}'"; From 4a8e3a5f623d02c2dc2fa11352c00e641500252d Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Thu, 3 Mar 2016 12:07:20 -0800 Subject: [PATCH 026/298] Settings API Doc - To be removed later. --- settings-api.MD | 192 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 settings-api.MD diff --git a/settings-api.MD b/settings-api.MD new file mode 100644 index 00000000000..1fb4237cccc --- /dev/null +++ b/settings-api.MD @@ -0,0 +1,192 @@ +# Settings API Proposal + +The idea of this proposal is to handle custom settings for both WooCommerce > Settings pages and settings panels for "metaboxes" (product data, coupon data). + +All settings are registered with PHP filters. Not through the API. The API is only for retrieving settings and updating them. + +## GET /settings/sections + +Dedicated settings sections/pages (for screens currently under WooCommerce > Settings) +For example we might have 'General', 'Products', 'Tax', 'Shipping', 'Checkout', 'Accounts', 'Emails', and 'API'. Adding a new page to this area should automatically create a new tab in the UI. + +Metaboxes (Coupon Data or Product Data for example) are also considered sections, and will be listed by this endpoint. They won't be automatically displayed anywhere. + +Here is how they would be registered: + + // Default WooCommerce Setting Sections + apply_filters( 'woocommerce_settings_sections', array( + array( + 'id' => 'general', // ID (required) + 'type' => 'page', // page or metabox + 'label' => __( 'General', 'woocommerce' ), // human readable label (required) + 'description' => '', // human readable description (optional) + ), + array( + 'id' => 'products', + 'type' => 'page', // page or metabox + 'label' => __( 'Products', 'woocommerce' ), + 'description' => '', + ), + ..... + ) ); + +To add a new top level tab/page to WooCommerce > Settings + + add_filter( 'woocommerce_settings_sections', function( $pages ) { + $pages[] = array( + 'id' => 'bookings', + 'type' => 'page', + 'label' => __( 'Bookings', 'woocommerce-bookings' ), + 'description' => __( 'Bookings settings.', 'woocommerce-bookings' ), + ); + return $pages; + } ); + +The actual endpoint would return a JSON object like so: + + [ + { + "id": "general", + "type": "page", + "label": "General", + "description": "" + }, + { + "id": "products", + "type": "page", + "label": "Products", + "description": "" + }, + { + "id": "coupon-data", + "type": "metabox", + "label": "Coupon Data", + "description": "" + } + ] + +There should be a filter for this endpoint (?type=page) to get only sections of a specific type. + +![](https://cldup.com/HHAZ-JBOxU.thumb.png) + +## GET /settings/sections/$section/ + +Lists all settings "groups" on a specific page. + +On the 'Products' page this would be 'General', 'Display', 'Inventory', and 'Downloadable Products'. + +Metaboxes won't need to use this. + +![](https://cldup.com/qXlfpvItr6-3000x3000.png) + +Here is how you would register groups: + + // products would be replaced with whatever page ID you want to register for. These filters automatically exist after registering a page + add_filter( 'woocommerce_settings_groups_products', function( $groups ) { + $groups[] = array( + 'id' => 'general', + 'label' => __( 'General', 'woocommerce' ), // human readable label (required) + 'description' => '', // human readable description (optional) + ); + $groups[] = array( + 'id' => 'display', + 'label' => __( 'Display', 'woocommerce' ), + 'description' => '', + ); + $groups[] = array( + 'id' => 'inventory', + 'label' => __( 'Inventory', 'woocommerce' ), + 'description' => '', + ); + return $groups; + } ); + +To retrive the groups for the 'products' page: + +GET /settings/sections/products + + { + "label": "Products", + "description": "", + "groups": [ + { + "id": "general", + "label": "General", + "description": "" + }, + { + "id": "display", + "label": "Display", + "description": "" + } + ] + } + + +## /settings/$identifer + +Gets the actual settings to be displayed in a specific area. You can load settings for a specific group, or for a specific metabox. + +GET /settings/page:products:general would return settings for Settings > Products > General. +GET /settings/metabox:coupons would return settings for Coupons > Add New Coupon > Coupon Data metabox. + +To register settings: + + // The filter (page_products_general) should match the identifer for the area we are loading settings for. + apply_filters( 'woocommerce_settings_page_products_general', array( + array( + 'label' => __( 'Measurements', 'woocommerce' ), + 'type' => 'title', + 'id' => 'product_measurement_options' + ), + array( + 'label' => __( 'Weight Unit', 'woocommerce' ), + 'description' => __( 'This controls what unit you will define weights in.', 'woocommerce' ), + 'id' => 'woocommerce_weight_unit', + 'default' => 'kg', + 'type' => 'select', + 'options' => array( + 'kg' => __( 'kg', 'woocommerce' ), + 'g' => __( 'g', 'woocommerce' ), + 'lbs' => __( 'lbs', 'woocommerce' ), + 'oz' => __( 'oz', 'woocommerce' ), + ), + ) + ) ); + +Settings response: + + [ + { + "label": "Measurements", + "type": "title", + "id": "product_measurement_options" + }, + { + "label": "Weight Unit", + "description": "This controls what unit you will define weights in.", + "id": "woocommerce_weight_unit", + "default": "kg", + "type": "select", + "options": { + "kg": "kg", + "g": "g", + "lbs": "lbs", + "oz": "oz" + } + } + ] + +We should different form input types for 'type', text, textarea, select, radio, checkbox, ... + +## GET /settings/$identifer/$setting + +Get data for an individual setting. + +## PUT /settings/$identifer/$setting + +Update a setting by passing a new 'value' in the body. A success response will be returned. + +## PUT /settings/$identifer + +Update multiple settings at the same time with key => value pairs. A success response will be returned. From fc076eb57e7b52993430405814b26a20d582797d Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 7 Mar 2016 08:46:58 -0800 Subject: [PATCH 027/298] Initial /settings API controller and /settings/locations route. Loads the WP-API and registers our namespace temporarily until WP-API is loaded by WC core. --- includes/api/wc-rest-settings-controller.php | 90 +++++++++ includes/class-wc-api.php | 3 + includes/vendor/wp-api-functions.php | 199 +++++++++++++++++++ tests/unit-tests/api/settings.php | 11 + 4 files changed, 303 insertions(+) create mode 100644 includes/api/wc-rest-settings-controller.php create mode 100644 includes/vendor/wp-api-functions.php create mode 100644 tests/unit-tests/api/settings.php diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php new file mode 100644 index 00000000000..c9a70867875 --- /dev/null +++ b/includes/api/wc-rest-settings-controller.php @@ -0,0 +1,90 @@ +rest_base . '/locations', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_locations' ), + 'permission_callback' => array( $this, 'permissions_check' ), + 'args' => $this->get_locations_params(), + ), + 'schema' => array( $this, 'get_locations_schema' ), + ) ); + + } + + /** + * Makes sure the current user has access to the settings APIs. + * @since 2.7.0 + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function permissions_check( $request ) { + return true; + } + + /* + |-------------------------------------------------------------------------- + | /settings/locations + |-------------------------------------------------------------------------- + | Returns a list of "settings" locations so all settings for a particular page + | or location can be properly loaded. + */ + + /** + * Get all settings locations. + * @since 2.7.0 + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_locations( $request ) { + $response = rest_ensure_response( array() ); + return $response; + } + + /** + * Get supported query parameters for locations. + * @since 2.7.0 + * @return array + */ + public function get_locations_params() { + $query_params = parent::get_collection_params(); + $query_params['context']['default'] = 'view'; + return $query_params; + } + + /** + * Get the locations chema, conforming to JSON Schema + * @since 2.7.0 + * @return array + */ + public function get_locations_schema() { + + } + +} diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 59af72ee530..81d21796a86 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -144,6 +144,7 @@ class WC_API extends WC_Legacy_API { include_once( 'abstracts/abstract-wc-rest-controller.php' ); include_once( 'abstracts/abstract-wc-rest-posts-controller.php' ); include_once( 'abstracts/abstract-wc-rest-terms-controller.php' ); + include_once( 'abstracts/abstract-wc-settings-api.php' ); // REST API controllers. include_once( 'api/class-wc-rest-coupons-controller.php' ); @@ -162,6 +163,7 @@ class WC_API extends WC_Legacy_API { include_once( 'api/class-wc-rest-report-sales-controller.php' ); include_once( 'api/class-wc-rest-report-top-sellers-controller.php' ); include_once( 'api/class-wc-rest-reports-controller.php' ); + include_once( 'api/wc-rest-settings-controller.php' ); include_once( 'api/class-wc-rest-tax-classes-controller.php' ); include_once( 'api/class-wc-rest-taxes-controller.php' ); include_once( 'api/class-wc-rest-webhook-deliveries.php' ); @@ -190,6 +192,7 @@ class WC_API extends WC_Legacy_API { 'WC_REST_Report_Sales_Controller', 'WC_REST_Report_Top_Sellers_Controller', 'WC_REST_Reports_Controller', + 'WC_Rest_Settings_Controller', 'WC_REST_Tax_Classes_Controller', 'WC_REST_Taxes_Controller', 'WC_REST_Webhook_Deliveries_Controller', diff --git a/includes/vendor/wp-api-functions.php b/includes/vendor/wp-api-functions.php new file mode 100644 index 00000000000..90c0713a229 --- /dev/null +++ b/includes/vendor/wp-api-functions.php @@ -0,0 +1,199 @@ + null, + 'update_callback' => null, + 'schema' => null, + ); + + $args = wp_parse_args( $args, $defaults ); + + global $wp_rest_additional_fields; + + $object_types = (array) $object_type; + + foreach ( $object_types as $object_type ) { + $wp_rest_additional_fields[ $object_type ][ $attribute ] = $args; + } + } +} + +if ( ! function_exists( 'register_api_field' ) ) { + /** + * Backwards compat shim + */ + function register_api_field( $object_type, $attributes, $args = array() ) { + _deprecated_function( 'register_api_field', 'WPAPI-2.0', 'register_rest_field' ); + register_rest_field( $object_type, $attributes, $args ); + } +} + +if ( ! function_exists( 'rest_validate_request_arg' ) ) { + /** + * Validate a request argument based on details registered to the route. + * + * @param mixed $value + * @param WP_REST_Request $request + * @param string $param + * @return WP_Error|boolean + */ + function rest_validate_request_arg( $value, $request, $param ) { + + $attributes = $request->get_attributes(); + if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { + return true; + } + $args = $attributes['args'][ $param ]; + + if ( ! empty( $args['enum'] ) ) { + if ( ! in_array( $value, $args['enum'] ) ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not one of %s' ), $param, implode( ', ', $args['enum'] ) ) ); + } + } + + if ( 'integer' === $args['type'] && ! is_numeric( $value ) ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not of type %s' ), $param, 'integer' ) ); + } + + if ( 'string' === $args['type'] && ! is_string( $value ) ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not of type %s' ), $param, 'string' ) ); + } + + if ( isset( $args['format'] ) ) { + switch ( $args['format'] ) { + case 'date-time' : + if ( ! rest_parse_date( $value ) ) { + return new WP_Error( 'rest_invalid_date', __( 'The date you provided is invalid.' ) ); + } + break; + + case 'email' : + if ( ! is_email( $value ) ) { + return new WP_Error( 'rest_invalid_email', __( 'The email address you provided is invalid.' ) ); + } + break; + } + } + + if ( in_array( $args['type'], array( 'numeric', 'integer' ) ) && ( isset( $args['minimum'] ) || isset( $args['maximum'] ) ) ) { + if ( isset( $args['minimum'] ) && ! isset( $args['maximum'] ) ) { + if ( ! empty( $args['exclusiveMinimum'] ) && $value <= $args['minimum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be greater than %d (exclusive)' ), $param, $args['minimum'] ) ); + } else if ( empty( $args['exclusiveMinimum'] ) && $value < $args['minimum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be greater than %d (inclusive)' ), $param, $args['minimum'] ) ); + } + } else if ( isset( $args['maximum'] ) && ! isset( $args['minimum'] ) ) { + if ( ! empty( $args['exclusiveMaximum'] ) && $value >= $args['maximum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be less than %d (exclusive)' ), $param, $args['maximum'] ) ); + } else if ( empty( $args['exclusiveMaximum'] ) && $value > $args['maximum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be less than %d (inclusive)' ), $param, $args['maximum'] ) ); + } + } else if ( isset( $args['maximum'] ) && isset( $args['minimum'] ) ) { + if ( ! empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) { + if ( $value >= $args['maximum'] || $value <= $args['minimum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (exclusive) and %d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); + } + } else if ( empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) { + if ( $value >= $args['maximum'] || $value < $args['minimum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (inclusive) and %d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); + } + } else if ( ! empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) { + if ( $value > $args['maximum'] || $value <= $args['minimum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (exclusive) and %d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); + } + } else if ( empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) { + if ( $value > $args['maximum'] || $value < $args['minimum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (inclusive) and %d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); + } + } + } + } + + return true; + } +} + +if ( ! function_exists( 'rest_sanitize_request_arg' ) ) { + /** + * Sanitize a request argument based on details registered to the route. + * + * @param mixed $value + * @param WP_REST_Request $request + * @param string $param + * @return mixed + */ + function rest_sanitize_request_arg( $value, $request, $param ) { + + $attributes = $request->get_attributes(); + if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { + return $value; + } + $args = $attributes['args'][ $param ]; + + if ( 'integer' === $args['type'] ) { + return (int) $value; + } + + if ( isset( $args['format'] ) ) { + switch ( $args['format'] ) { + case 'date-time' : + return sanitize_text_field( $value ); + + case 'email' : + /* + * sanitize_email() validates, which would be unexpected + */ + return sanitize_text_field( $value ); + + case 'uri' : + return esc_url_raw( $value ); + } + } + + return $value; + } + +} diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php new file mode 100644 index 00000000000..86c44b50e74 --- /dev/null +++ b/tests/unit-tests/api/settings.php @@ -0,0 +1,11 @@ + Date: Mon, 7 Mar 2016 10:24:03 -0800 Subject: [PATCH 028/298] Make /settings/locations work properly. Add skeleton for tests and add register_routes test. --- includes/api/wc-rest-settings-controller.php | 63 +++++++++++++++++-- tests/bootstrap.php | 7 +++ ...class-wp-test-rest-controller-testcase.php | 45 +++++++++++++ .../class-wp-test-spy-rest-server.php | 38 +++++++++++ tests/unit-tests/api/settings.php | 59 ++++++++++++++++- 5 files changed, 206 insertions(+), 6 deletions(-) create mode 100644 tests/framework/class-wp-test-rest-controller-testcase.php create mode 100644 tests/framework/class-wp-test-spy-rest-server.php diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index c9a70867875..7503aff3c19 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -63,28 +63,83 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @return WP_Error|WP_REST_Response */ public function get_locations( $request ) { - $response = rest_ensure_response( array() ); + $locations = apply_filters( 'woocommerce_settings_locations', array() ); + $defaults = array( + 'id' => null, + 'type' => 'page', + 'label' => null, + 'description' => '', + ); + $filtered_locations = array(); + foreach ( $locations as $location ) { + $location = wp_parse_args( $location, $defaults ); + $location_valid = true; + if ( is_null( $location['id'] ) || is_null( $location['label'] ) || is_null( $location['type'] ) ) { // id, label, and type are required fields + $location_valid = false; + } else if ( ! empty( $request['type'] ) ) { + if ( in_array( $request['type'], $this->get_location_types() ) && $request['type'] !== $location['type'] ) { + $location_valid = false; + } + } + + if ( $location_valid ) { + $filtered_locations[] = array_intersect_key( + $location, + array_flip( array_filter( array_keys( $location ), array( $this, 'filter_location_keys' ) ) ) + ); + } + } + $response = rest_ensure_response( $filtered_locations ); return $response; } + /** + * Callback for Allowed keys for each location response. + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function filter_location_keys( $key ) { + return in_array( $key, array( 'id', 'type', 'label', 'description' ) ); + } + /** * Get supported query parameters for locations. * @since 2.7.0 * @return array */ public function get_locations_params() { - $query_params = parent::get_collection_params(); - $query_params['context']['default'] = 'view'; + $query_params = array(); + + $query_params['type'] = array( + 'description' => __( 'Limit result set to setting locations of a specific type.', 'woocommerce' ), + 'type' => 'string' + ); + return $query_params; } /** - * Get the locations chema, conforming to JSON Schema + * Get the locations chema, conforming to JSON Schema. * @since 2.7.0 * @return array */ public function get_locations_schema() { + /*$schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'locations', + 'type' => 'object', + 'properties' => + );*/ + } + /** + * Returns a list of allowed setting location types. + * @since 2.7.0 + * @return array + */ + protected function get_location_types() { + return apply_filters( 'woocommerce_settings_location_types', array( 'page', 'metabox', 'shipping-zone' ) ); } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 37619b65ce4..3ce081fe8f2 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -112,6 +112,13 @@ class WC_Unit_Tests_Bootstrap { require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-order.php' ); require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-shipping-zones.php' ); require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-payment-token.php' ); + + /** + * WP-API + * @todo to be removed when the wp-api branch is merged. + */ + require_once( $this->tests_dir . '/framework/class-wp-test-rest-controller-testcase.php' ); + require_once( $this->tests_dir . '/framework/class-wp-test-spy-rest-server.php' ); } /** diff --git a/tests/framework/class-wp-test-rest-controller-testcase.php b/tests/framework/class-wp-test-rest-controller-testcase.php new file mode 100644 index 00000000000..f733017873b --- /dev/null +++ b/tests/framework/class-wp-test-rest-controller-testcase.php @@ -0,0 +1,45 @@ +server = $wp_rest_server = new WP_Test_Spy_REST_Server; + do_action( 'rest_api_init' ); + } + + public function tearDown() { + parent::tearDown(); + + /** @var WP_REST_Server $wp_rest_server */ + global $wp_rest_server; + $wp_rest_server = null; + } + + abstract public function test_register_routes(); + + abstract public function test_context_param(); + + abstract public function test_get_items(); + + abstract public function test_get_item(); + + abstract public function test_create_item(); + + abstract public function test_update_item(); + + abstract public function test_delete_item(); + + abstract public function test_prepare_item(); + + abstract public function test_get_item_schema(); + +} diff --git a/tests/framework/class-wp-test-spy-rest-server.php b/tests/framework/class-wp-test-spy-rest-server.php new file mode 100644 index 00000000000..ba485b65a1a --- /dev/null +++ b/tests/framework/class-wp-test-spy-rest-server.php @@ -0,0 +1,38 @@ +endpoints; + } + + /** + * Allow calling protected methods from tests + * + * @param string $method Method to call + * @param array $args Arguments to pass to the method + * @return mixed + */ + public function __call( $method, $args ) { + return call_user_func_array( array( $this, $method ), $args ); + } + + /** + * Call dispatch() with the rest_post_dispatch filter + */ + public function dispatch( $request ) { + $result = parent::dispatch( $request ); + $result = rest_ensure_response( $result ); + if ( is_wp_error( $result ) ) { + $result = $this->error_to_response( $result ); + } + return apply_filters( 'rest_post_dispatch', rest_ensure_response( $result ), $this, $request ); + } +} diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 86c44b50e74..d7fc08516c9 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -4,8 +4,63 @@ namespace WooCommerce\Tests\API; /** * Settings API Tests * @package WooCommerce\Tests\API - * @since 2.x.0 + * @since 2.7.0 */ -class Settings extends \WC_API_Unit_Test_Case { +class Settings extends \WP_Test_REST_Controller_Testcase { + + public function setUp() { + parent::setUp(); + $this->endpoint = new \WC_Rest_Settings_Controller(); + } + + /** + * Test route registration. + * @since 2.7.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v1/settings/locations', $routes ); + } + + /** + * Test normal /settings/locations response. + * @since 2.7.0 + */ + public function test_get_items() { + + } + + /** + * Test /settings/locations without valid permissions/creds. + * @since 2.7.0 + */ + public function test_get_locations_without_permission() { + + } + + /** + * Test /settings/locations correctly filters out bad values. + * Handles required fields and bogus fields. + * @since 2.7.0 + */ + public function test_get_locations_filters_values() { + + } + + /** + * Test /settings/locations with type. + * @since 2.7.0 + */ + public function test_get_locations_with_type() { + + } + + public function test_context_param() { } + public function test_get_item() { } + public function test_create_item() { } + public function test_update_item() { } + public function test_delete_item() { } + public function test_prepare_item() { } + public function test_get_item_schema() { } } From eb9e5edd221254748acb432655e4a3b6fd9d91a5 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 7 Mar 2016 10:46:52 -0800 Subject: [PATCH 029/298] API Docs for our endpoints this far. --- .../README.md | 70 ++----------------- settings-api-docs/locations.md | 38 ++++++++++ 2 files changed, 44 insertions(+), 64 deletions(-) rename settings-api.MD => settings-api-docs/README.md (60%) create mode 100644 settings-api-docs/locations.md diff --git a/settings-api.MD b/settings-api-docs/README.md similarity index 60% rename from settings-api.MD rename to settings-api-docs/README.md index 1fb4237cccc..126d7d918a5 100644 --- a/settings-api.MD +++ b/settings-api-docs/README.md @@ -1,73 +1,15 @@ # Settings API Proposal -The idea of this proposal is to handle custom settings for both WooCommerce > Settings pages and settings panels for "metaboxes" (product data, coupon data). +The Settings API is a set of WP-API endpoints that return information about WooCommerce settings. Settings can also be updated with the API. -All settings are registered with PHP filters. Not through the API. The API is only for retrieving settings and updating them. +The API should be capable of handling settings in many different contexts including pages (WooCommerce > Settings), "metaboxes" (product data, coupon data), shipping zones, and be extendable to other contexts in the future. -## GET /settings/sections +All settings are registered with PHP filters. Not through the REST API. The REST API is only for retrieving settings and updating them. -Dedicated settings sections/pages (for screens currently under WooCommerce > Settings) -For example we might have 'General', 'Products', 'Tax', 'Shipping', 'Checkout', 'Accounts', 'Emails', and 'API'. Adding a new page to this area should automatically create a new tab in the UI. +## Locations +[locations.md](locations.md) -Metaboxes (Coupon Data or Product Data for example) are also considered sections, and will be listed by this endpoint. They won't be automatically displayed anywhere. - -Here is how they would be registered: - - // Default WooCommerce Setting Sections - apply_filters( 'woocommerce_settings_sections', array( - array( - 'id' => 'general', // ID (required) - 'type' => 'page', // page or metabox - 'label' => __( 'General', 'woocommerce' ), // human readable label (required) - 'description' => '', // human readable description (optional) - ), - array( - 'id' => 'products', - 'type' => 'page', // page or metabox - 'label' => __( 'Products', 'woocommerce' ), - 'description' => '', - ), - ..... - ) ); - -To add a new top level tab/page to WooCommerce > Settings - - add_filter( 'woocommerce_settings_sections', function( $pages ) { - $pages[] = array( - 'id' => 'bookings', - 'type' => 'page', - 'label' => __( 'Bookings', 'woocommerce-bookings' ), - 'description' => __( 'Bookings settings.', 'woocommerce-bookings' ), - ); - return $pages; - } ); - -The actual endpoint would return a JSON object like so: - - [ - { - "id": "general", - "type": "page", - "label": "General", - "description": "" - }, - { - "id": "products", - "type": "page", - "label": "Products", - "description": "" - }, - { - "id": "coupon-data", - "type": "metabox", - "label": "Coupon Data", - "description": "" - } - ] - -There should be a filter for this endpoint (?type=page) to get only sections of a specific type. - -![](https://cldup.com/HHAZ-JBOxU.thumb.png) +# The below sections are being moved to their own doc files as the API gets fleshed out. ## GET /settings/sections/$section/ diff --git a/settings-api-docs/locations.md b/settings-api-docs/locations.md new file mode 100644 index 00000000000..dcc1ab22eed --- /dev/null +++ b/settings-api-docs/locations.md @@ -0,0 +1,38 @@ +Settings can be grouped together by location. + +A location is just a grouping of settings that all share a common 'location' key. +This is so you can pull all settings meant to be displayed together in a particular area. + +Example: + +In wp-admin there is a "Coupon Data" box on the "Add New Coupon" page. +The coupon data box is considered location and would be represented like so: + + { + "id": "coupon-data", + "type": "metabox", + "label": "Coupon Data", + "description": "" + } + + +There are 4 fields that make up a location: + +* _id_: A unique identifier that can be used to link settings together. id is an alphanumeric string that should contain no spaces. Required. +* _type_: Context for where the settings in this location are going to be displayed. Right now core accepts 'page' for settings pages (pages currently under WooCommerce > Settings), 'metabox' (for metabox grouped settings like Coupon Data - this name is subject to change as this API develops), and 'shipping-zone' for settings associated with shipping zone settings. Required, defaults to 'page'. +* _label_: A human readable label. This is a translated string that can be used in the UI. Optional. +* _description_: A human readable description. This is a translated string that can be used in the UI. Optional. + +Any other fields passed will be stripped out before the JSON response is sent back to the client. + +Locations can be registered with the `woocommerce_settings_locations` filter: + + add_filter( 'woocommerce_settings_locations', function( $locations ) { + $locations[] = array( + 'id' => 'test-extension', + 'type' => 'page', + 'label' => __( 'Test Extension', 'woocommerce-test-extension' ), + 'description' => __( 'My awesome test settings.', 'woocommerce-test-extension' ), + ); + return $locations; + } ); From 9369d55ff415ae182a7c03d29adf63ff6ef6cbde Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 7 Mar 2016 12:44:07 -0800 Subject: [PATCH 030/298] Add the ability to get data on a single location. --- includes/api/wc-rest-settings-controller.php | 112 ++++++++++++++++--- settings-api-docs/locations.md | 22 +++- tests/unit-tests/api/settings.php | 32 +++++- 3 files changed, 147 insertions(+), 19 deletions(-) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index 7503aff3c19..4090be82e3a 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -33,14 +33,22 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_locations_params(), ), - 'schema' => array( $this, 'get_locations_schema' ), + 'schema' => array( $this, 'get_location_schema' ), ) ); + register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/locations/(?P[\w-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_location' ), + 'permission_callback' => array( $this, 'permissions_check' ), + ), + 'schema' => array( $this, 'get_location_schema' ), + ) ); } /** * Makes sure the current user has access to the settings APIs. - * @since 2.7.0 + * @since 2.7.0 * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ @@ -58,8 +66,8 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { /** * Get all settings locations. - * @since 2.7.0 - * @param WP_REST_Request $request Full details about the request. + * @since 2.7.0 + * @param WP_REST_Request $request Full details about the request. * @return WP_Error|WP_REST_Response */ public function get_locations( $request ) { @@ -93,9 +101,39 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return $response; } + /** + * Return a single setting location. + * @since 2.7.0 + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_location( $request ) { + $locations = apply_filters( 'woocommerce_settings_locations', array() ); + if ( empty( $locations ) ) { + return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); + } + + $index_key = $this->get_array_key_from_location_id( $locations, $request['location'] ); + if ( is_null( $index_key ) || empty( $locations[ $index_key ] ) ) { + return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); + } + + $location = $locations[ $index_key ]; + if ( is_null( $location['id'] ) || is_null( $location['label'] ) || is_null( $location['type'] ) ) { + return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); + } + + $filtered_location = array_intersect_key( + $location, + array_flip( array_filter( array_keys( $location ), array( $this, 'filter_location_keys' ) ) ) + ); + + return $filtered_location; + } + /** * Callback for Allowed keys for each location response. - * @since 2.7.0 + * @since 2.7.0 * @param string $key Key to check * @return boolean */ @@ -105,7 +143,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { /** * Get supported query parameters for locations. - * @since 2.7.0 + * @since 2.7.0 * @return array */ public function get_locations_params() { @@ -121,25 +159,73 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { /** * Get the locations chema, conforming to JSON Schema. - * @since 2.7.0 + * @since 2.7.0 * @return array */ - public function get_locations_schema() { - /*$schema = array( + public function get_location_schema() { + $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'locations', + 'title' => 'settings-locations', 'type' => 'object', - 'properties' => - );*/ + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier that can be used to link settings together.' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'type' => array( + 'description' => __( 'Context for where the settings in this location are going to be displayed.' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'label' => array( + 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'description' => array( + 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); } /** * Returns a list of allowed setting location types. - * @since 2.7.0 + * @todo move this? + * @since 2.7.0 * @return array */ protected function get_location_types() { return apply_filters( 'woocommerce_settings_location_types', array( 'page', 'metabox', 'shipping-zone' ) ); } + /** + * Returns the array key for a specific location ID so it can be pulled out of the 'locations' array. + * @todo move this? + * @param array $locations woocommerce_settings_locations + * @param string $id Location ID to get an array key index for + * @return integer|null + */ + protected function get_array_key_from_location_id( $locations, $id ) { + foreach ( $locations as $key => $location ) { + if ( $id === $location['id'] ) { + return $key; + } + } + return null; + } + } diff --git a/settings-api-docs/locations.md b/settings-api-docs/locations.md index dcc1ab22eed..2f01ccaf396 100644 --- a/settings-api-docs/locations.md +++ b/settings-api-docs/locations.md @@ -1,3 +1,7 @@ +# Locations + +## Basic Info + Settings can be grouped together by location. A location is just a grouping of settings that all share a common 'location' key. @@ -18,13 +22,15 @@ The coupon data box is considered location and would be represented like so: There are 4 fields that make up a location: -* _id_: A unique identifier that can be used to link settings together. id is an alphanumeric string that should contain no spaces. Required. -* _type_: Context for where the settings in this location are going to be displayed. Right now core accepts 'page' for settings pages (pages currently under WooCommerce > Settings), 'metabox' (for metabox grouped settings like Coupon Data - this name is subject to change as this API develops), and 'shipping-zone' for settings associated with shipping zone settings. Required, defaults to 'page'. +* _id_: A unique identifier that can be used to link settings together. Alphanumeric string that contains no spaces. Required. +* _type_: Context for where the settings in this location are going to be displayed. Right now core accepts 'page' for settings pages (pages currently under WooCommerce > Settings), 'metabox' (for metabox grouped settings like Coupon Data - this name is subject to change as this API develops), and 'shipping-zone' for settings associated with shipping zone settings. Alphanumeric string that contains no spaces. Required, defaults to 'page'. * _label_: A human readable label. This is a translated string that can be used in the UI. Optional. * _description_: A human readable description. This is a translated string that can be used in the UI. Optional. Any other fields passed will be stripped out before the JSON response is sent back to the client. +## Registering a Location + Locations can be registered with the `woocommerce_settings_locations` filter: add_filter( 'woocommerce_settings_locations', function( $locations ) { @@ -36,3 +42,15 @@ Locations can be registered with the `woocommerce_settings_locations` filter: ); return $locations; } ); + + +## Endpoints + +### GET /settings/locations + +Returns a list of all locations supported by WC. +There is an optional ?type parameter that allows you to return only locations for a specific context (like all page locations). + +### GET /settings/locations/$id + +Returns information on a single location. \ No newline at end of file diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index d7fc08516c9..34e4f1f5477 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -23,10 +23,10 @@ class Settings extends \WP_Test_REST_Controller_Testcase { } /** - * Test normal /settings/locations response. + * Test getting all locations. * @since 2.7.0 */ - public function test_get_items() { + public function test_get_locations() { } @@ -55,12 +55,36 @@ class Settings extends \WP_Test_REST_Controller_Testcase { } - public function test_context_param() { } + /** + * Test /settings/locations schema. + * @since 2.7.0 + */ + public function test_get_item_schema() { + + } + + /** + * Test getting a single location item. + * @since 2.7.0 + */ + public function test_get_location() { + + } + + /** + * Test getting a single location item. + * @since 2.7.0 + */ + public function test_get_location_without_permission() { + + } + + public function test_get_items() { } public function test_get_item() { } + public function test_context_param() { } public function test_create_item() { } public function test_update_item() { } public function test_delete_item() { } public function test_prepare_item() { } - public function test_get_item_schema() { } } From eb4291f699274b3e53454870b470404638a32354 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 7 Mar 2016 13:46:40 -0800 Subject: [PATCH 031/298] More setting location tests. --- includes/api/wc-rest-settings-controller.php | 26 ++++-- tests/bootstrap.php | 1 + .../helpers/class-wc-helper-settings.php | 46 ++++++++++ tests/unit-tests/api/settings.php | 91 ++++++++++++++++++- 4 files changed, 154 insertions(+), 10 deletions(-) create mode 100644 tests/framework/helpers/class-wc-helper-settings.php diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index 4090be82e3a..11c2c4d9c76 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -72,12 +72,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { */ public function get_locations( $request ) { $locations = apply_filters( 'woocommerce_settings_locations', array() ); - $defaults = array( - 'id' => null, - 'type' => 'page', - 'label' => null, - 'description' => '', - ); + $defaults = $this->get_location_defaults(); $filtered_locations = array(); foreach ( $locations as $location ) { $location = wp_parse_args( $location, $defaults ); @@ -119,6 +114,8 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { } $location = $locations[ $index_key ]; + $defaults = $this->get_location_defaults(); + $location = wp_parse_args( $location, $defaults ); if ( is_null( $location['id'] ) || is_null( $location['label'] ) || is_null( $location['type'] ) ) { return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); } @@ -212,6 +209,21 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return apply_filters( 'woocommerce_settings_location_types', array( 'page', 'metabox', 'shipping-zone' ) ); } + /** + * Returns default settings for the various locations. null means the field is required. + * @todo move this? + * @since 2.7.0 + * @return array + */ + protected function get_location_defaults() { + return array( + 'id' => null, + 'type' => 'page', + 'label' => null, + 'description' => '', + ); + } + /** * Returns the array key for a specific location ID so it can be pulled out of the 'locations' array. * @todo move this? @@ -221,7 +233,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { */ protected function get_array_key_from_location_id( $locations, $id ) { foreach ( $locations as $key => $location ) { - if ( $id === $location['id'] ) { + if ( ! empty( $location['id'] ) && $id === $location['id'] ) { return $key; } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 3ce081fe8f2..8e5864f2c3c 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -112,6 +112,7 @@ class WC_Unit_Tests_Bootstrap { require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-order.php' ); require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-shipping-zones.php' ); require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-payment-token.php' ); + require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-settings.php' ); /** * WP-API diff --git a/tests/framework/helpers/class-wc-helper-settings.php b/tests/framework/helpers/class-wc-helper-settings.php new file mode 100644 index 00000000000..4f3634948ff --- /dev/null +++ b/tests/framework/helpers/class-wc-helper-settings.php @@ -0,0 +1,46 @@ + 'test', + 'type' => 'page', + 'bad' => 'value', + 'label' => __( 'Test Extension', 'woocommerce' ), + 'description' => __( 'My awesome test settings.', 'woocommerce' ), + ); + $locations[] = array( + 'id' => 'coupon-data', + 'type' => 'metabox', + 'label' => __( 'Coupon Data', 'woocommerce' ), + ); + $locations[] = array( + 'label' => __( 'Invalid', 'woocommerce' ), + ); + $locations[] = array( + 'id' => 'invalid', + ); + return $locations; + } + +} diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 34e4f1f5477..44083f562de 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -11,6 +11,7 @@ class Settings extends \WP_Test_REST_Controller_Testcase { public function setUp() { parent::setUp(); $this->endpoint = new \WC_Rest_Settings_Controller(); + \WC_Helper_Settings::register(); } /** @@ -27,7 +28,25 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_locations() { + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); + $data = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $data ) ); + + $this->check_get_location_response( $data[0], array( + 'id' => 'test', + 'type' => 'page', + 'label' => 'Test Extension', + 'description' => 'My awesome test settings.', + ) ); + + $this->check_get_location_response( $data[1], array( + 'id' => 'coupon-data', + 'type' => 'metabox', + 'label' => 'Coupon Data', + 'description' => '', + ) ); } /** @@ -43,8 +62,12 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * Handles required fields and bogus fields. * @since 2.7.0 */ - public function test_get_locations_filters_values() { + public function test_get_locations_correctly_filters_values() { + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); + $data = $response->get_data(); + $this->assertEquals( 'test', $data[0]['id'] ); + $this->assertArrayNotHasKey( 'bad', $data[0] ); } /** @@ -52,15 +75,42 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_locations_with_type() { + $request = new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ); + $request->set_param( 'type', 'not-a-real-type' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 2, count( $data ) ); // all results + $request = new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ); + $request->set_param( 'type', 'page' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $data ) ); + + $this->check_get_location_response( $data[0], array( + 'id' => 'test', + 'type' => 'page', + 'label' => 'Test Extension', + 'description' => 'My awesome test settings.', + ) ); } /** * Test /settings/locations schema. * @since 2.7.0 */ - public function test_get_item_schema() { - + public function test_get_location_schema() { + $request = new \WP_REST_Request( 'OPTIONS', '/wc/v1/settings/locations' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 4, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'type', $properties ); + $this->assertArrayHasKey( 'label', $properties ); + $this->assertArrayHasKey( 'description', $properties ); } /** @@ -68,7 +118,28 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_location() { + // test getting a location that does not exist + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/not-real' ) ); + $data = $response->get_data(); + $this->assertEquals( 404, $response->get_status() ); + // test getting the 'invalid' location + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/invalid' ) ); + $data = $response->get_data(); + $this->assertEquals( 404, $response->get_status() ); + + // test getting a valid location + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/coupon-data' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->check_get_location_response( $data, array( + 'id' => 'coupon-data', + 'type' => 'metabox', + 'label' => 'Coupon Data', + 'description' => '', + ) ); } /** @@ -86,5 +157,19 @@ class Settings extends \WP_Test_REST_Controller_Testcase { public function test_update_item() { } public function test_delete_item() { } public function test_prepare_item() { } + public function test_get_item_schema() { } + + /** + * Ensure valid location data response. + * @since 2.7.0 + * @param array $response + * @param array $expected + */ + protected function check_get_location_response( $response, $expected ) { + $this->assertEquals( $expected['id'], $response['id'] ); + $this->assertEquals( $expected['type'], $response['type'] ); + $this->assertEquals( $expected['label'], $response['label'] ); + $this->assertEquals( $expected['description'], $response['description'] ); + } } From 6c2be482cae87e85f0ee61520759f34eac913bc1 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 7 Mar 2016 13:54:28 -0800 Subject: [PATCH 032/298] Add a permissions check to the locations endpoints and fill out the tests for them. --- includes/api/wc-rest-settings-controller.php | 4 ++++ tests/unit-tests/api/settings.php | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index 11c2c4d9c76..ae322bd30bb 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -53,6 +53,10 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @return WP_Error|boolean */ public function permissions_check( $request ) { + if ( ! current_user_can( 'manage_options' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; } diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 44083f562de..15380336b99 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -12,6 +12,9 @@ class Settings extends \WP_Test_REST_Controller_Testcase { parent::setUp(); $this->endpoint = new \WC_Rest_Settings_Controller(); \WC_Helper_Settings::register(); + $this->user = $this->factory->user->create( array( + 'role' => 'administrator', + ) ); } /** @@ -28,6 +31,8 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_locations() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); $data = $response->get_data(); @@ -54,7 +59,10 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_locations_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); + $this->assertEquals( 401, $response->get_status() ); } /** @@ -63,6 +71,8 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_locations_correctly_filters_values() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); $data = $response->get_data(); @@ -75,6 +85,8 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_locations_with_type() { + wp_set_current_user( $this->user ); + $request = new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ); $request->set_param( 'type', 'not-a-real-type' ); $response = $this->server->dispatch( $request ); @@ -118,6 +130,8 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_location() { + wp_set_current_user( $this->user ); + // test getting a location that does not exist $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/not-real' ) ); $data = $response->get_data(); @@ -147,7 +161,10 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_location_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/coupon-data' ) ); + $this->assertEquals( 401, $response->get_status() ); } public function test_get_items() { } From 06e787a26ddc250dac0f2ad8fad6d676e306d0fd Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 21 Mar 2016 11:29:27 -0700 Subject: [PATCH 033/298] Misc cleanup. --- includes/api/wc-rest-settings-controller.php | 3 +- tests/bootstrap.php | 1 - ...class-wp-test-rest-controller-testcase.php | 45 ------------------- tests/unit-tests/api/settings.php | 28 +++++++----- 4 files changed, 20 insertions(+), 57 deletions(-) delete mode 100644 tests/framework/class-wp-test-rest-controller-testcase.php diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index ae322bd30bb..b3bbc8bd3ff 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -129,7 +129,8 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { array_flip( array_filter( array_keys( $location ), array( $this, 'filter_location_keys' ) ) ) ); - return $filtered_location; + $response = rest_ensure_response( $filtered_location ); + return $response; } /** diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 8e5864f2c3c..87e65f64053 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -118,7 +118,6 @@ class WC_Unit_Tests_Bootstrap { * WP-API * @todo to be removed when the wp-api branch is merged. */ - require_once( $this->tests_dir . '/framework/class-wp-test-rest-controller-testcase.php' ); require_once( $this->tests_dir . '/framework/class-wp-test-spy-rest-server.php' ); } diff --git a/tests/framework/class-wp-test-rest-controller-testcase.php b/tests/framework/class-wp-test-rest-controller-testcase.php deleted file mode 100644 index f733017873b..00000000000 --- a/tests/framework/class-wp-test-rest-controller-testcase.php +++ /dev/null @@ -1,45 +0,0 @@ -server = $wp_rest_server = new WP_Test_Spy_REST_Server; - do_action( 'rest_api_init' ); - } - - public function tearDown() { - parent::tearDown(); - - /** @var WP_REST_Server $wp_rest_server */ - global $wp_rest_server; - $wp_rest_server = null; - } - - abstract public function test_register_routes(); - - abstract public function test_context_param(); - - abstract public function test_get_items(); - - abstract public function test_get_item(); - - abstract public function test_create_item(); - - abstract public function test_update_item(); - - abstract public function test_delete_item(); - - abstract public function test_prepare_item(); - - abstract public function test_get_item_schema(); - -} diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 15380336b99..eacf0c4be0f 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -6,10 +6,18 @@ namespace WooCommerce\Tests\API; * @package WooCommerce\Tests\API * @since 2.7.0 */ -class Settings extends \WP_Test_REST_Controller_Testcase { +class Settings extends \WC_Unit_Test_Case { + protected $server; + + /** + * Setup our test server, endpoints, and user info. + */ public function setUp() { parent::setUp(); + global $wp_rest_server; + $this->server = $wp_rest_server = new \WP_Test_Spy_REST_Server; + do_action( 'rest_api_init' ); $this->endpoint = new \WC_Rest_Settings_Controller(); \WC_Helper_Settings::register(); $this->user = $this->factory->user->create( array( @@ -17,6 +25,15 @@ class Settings extends \WP_Test_REST_Controller_Testcase { ) ); } + /** + * Unset the server. + */ + public function tearDown() { + parent::tearDown(); + global $wp_rest_server; + $wp_rest_server = null; + } + /** * Test route registration. * @since 2.7.0 @@ -167,15 +184,6 @@ class Settings extends \WP_Test_REST_Controller_Testcase { $this->assertEquals( 401, $response->get_status() ); } - public function test_get_items() { } - public function test_get_item() { } - public function test_context_param() { } - public function test_create_item() { } - public function test_update_item() { } - public function test_delete_item() { } - public function test_prepare_item() { } - public function test_get_item_schema() { } - /** * Ensure valid location data response. * @since 2.7.0 From 785e43a2079d03728c8569995a0bd91a7e8a7ba3 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 21 Mar 2016 13:38:22 -0700 Subject: [PATCH 034/298] Add group info to the single locations endpoint & update our docs --- includes/api/wc-rest-settings-controller.php | 14 ++++- settings-api-docs/README.md | 57 +------------------ settings-api-docs/groups.md | 58 ++++++++++++++++++++ settings-api-docs/locations.md | 4 +- 4 files changed, 75 insertions(+), 58 deletions(-) create mode 100644 settings-api-docs/groups.md diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index b3bbc8bd3ff..f4988d01da3 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -54,7 +54,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { */ public function permissions_check( $request ) { if ( ! current_user_can( 'manage_options' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + // return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -124,6 +124,16 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); } + if ( 'page' === $location['type'] ) { + $location['groups'] = array(); + $groups = apply_filters( 'woocommerce_settings_groups_' . $location['id'], array() ); + if ( ! empty( $groups ) ) { + foreach ( $groups as $group ) { + $location['groups'][] = array( 'id' => $group['id'], 'label' => $group['label'], 'description' => $group['description'] ); + } + } + } + $filtered_location = array_intersect_key( $location, array_flip( array_filter( array_keys( $location ), array( $this, 'filter_location_keys' ) ) ) @@ -140,7 +150,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @return boolean */ public function filter_location_keys( $key ) { - return in_array( $key, array( 'id', 'type', 'label', 'description' ) ); + return in_array( $key, array( 'id', 'type', 'label', 'description', 'groups' ) ); } /** diff --git a/settings-api-docs/README.md b/settings-api-docs/README.md index 126d7d918a5..c5d06efa821 100644 --- a/settings-api-docs/README.md +++ b/settings-api-docs/README.md @@ -9,61 +9,10 @@ All settings are registered with PHP filters. Not through the REST API. The REST ## Locations [locations.md](locations.md) -# The below sections are being moved to their own doc files as the API gets fleshed out. - -## GET /settings/sections/$section/ - -Lists all settings "groups" on a specific page. - -On the 'Products' page this would be 'General', 'Display', 'Inventory', and 'Downloadable Products'. - -Metaboxes won't need to use this. - -![](https://cldup.com/qXlfpvItr6-3000x3000.png) - -Here is how you would register groups: - - // products would be replaced with whatever page ID you want to register for. These filters automatically exist after registering a page - add_filter( 'woocommerce_settings_groups_products', function( $groups ) { - $groups[] = array( - 'id' => 'general', - 'label' => __( 'General', 'woocommerce' ), // human readable label (required) - 'description' => '', // human readable description (optional) - ); - $groups[] = array( - 'id' => 'display', - 'label' => __( 'Display', 'woocommerce' ), - 'description' => '', - ); - $groups[] = array( - 'id' => 'inventory', - 'label' => __( 'Inventory', 'woocommerce' ), - 'description' => '', - ); - return $groups; - } ); - -To retrive the groups for the 'products' page: - -GET /settings/sections/products - - { - "label": "Products", - "description": "", - "groups": [ - { - "id": "general", - "label": "General", - "description": "" - }, - { - "id": "display", - "label": "Display", - "description": "" - } - ] - } +## Groups +[groups.md](groups.md) +# The below sections are being moved to their own doc files (and may change) as the API gets fleshed out. ## /settings/$identifer diff --git a/settings-api-docs/groups.md b/settings-api-docs/groups.md new file mode 100644 index 00000000000..60ddf19d7fd --- /dev/null +++ b/settings-api-docs/groups.md @@ -0,0 +1,58 @@ +# Groups + +## Basic Info + +Groups are settings thats are grouped together on setting pages _only_ (type=page). That means setting locations like metaboxes don't have groups. + +For example, a location would be the 'Products' page. +The products page would ave the following groups: 'General', 'Display', 'Inventory', and 'Downloadable Products'. + +![](https://cldup.com/qXlfpvItr6-3000x3000.png) + + { + "id": "general", + "label": "General", + "description": "" + } + +There are 3 fields that make up a group: + +* _id_: A unique identifier that can be used to link settings together. The identifiers for groups only need to be unique on a specific page, so you can have a 'general' group under 'Products' and a 'general' group under Shipping. Alphanumeric string that contains no spaces. Required. +* _label_: A human readable label. This is a translated string that can be used in the UI. Required. +* _description_: A human readable description. This is a translated string that can be used in the UI. Optional. + +Any other fields passed will be stripped out before the JSON response is sent back to the client. + +## Registering a group + +Groups can be registered with the `woocommerce_settings_groups_{$location_id}` filter: + + add_filter( 'woocommerce_settings_groups_products', function( $groups ) { + $groups[] = array( + 'id' => 'extra-settings', + 'label' => __( 'Extras', 'woocommerce-test-extension' ), + 'description' => '', + ); + return $groups; + } ); + + +## Endpoints + +There are no separate endpoints for groups. You can access a list of groups for a specific page/location by calling that location's endpoint. + +### GET /settings/locations/$id + + { + "id": "test", + "type": "page", + "label": "Test Extension", + "description": "My awesome test settings.", + "groups": [ + { + "id": "general", + "label": "General", + "description": "" + } + ] + } \ No newline at end of file diff --git a/settings-api-docs/locations.md b/settings-api-docs/locations.md index 2f01ccaf396..a65f425ceb1 100644 --- a/settings-api-docs/locations.md +++ b/settings-api-docs/locations.md @@ -22,9 +22,9 @@ The coupon data box is considered location and would be represented like so: There are 4 fields that make up a location: -* _id_: A unique identifier that can be used to link settings together. Alphanumeric string that contains no spaces. Required. +* _id_: A unique identifier that can be used to link settings together. This shoud be a unique (for the whole system) value. Prefixing with your plugin slug is recommended for non-core changes. Alphanumeric string that contains no spaces. Required. * _type_: Context for where the settings in this location are going to be displayed. Right now core accepts 'page' for settings pages (pages currently under WooCommerce > Settings), 'metabox' (for metabox grouped settings like Coupon Data - this name is subject to change as this API develops), and 'shipping-zone' for settings associated with shipping zone settings. Alphanumeric string that contains no spaces. Required, defaults to 'page'. -* _label_: A human readable label. This is a translated string that can be used in the UI. Optional. +* _label_: A human readable label. This is a translated string that can be used in the UI. Required. * _description_: A human readable description. This is a translated string that can be used in the UI. Optional. Any other fields passed will be stripped out before the JSON response is sent back to the client. From f425a3735a75a52f8e246a87d7c92a553db47b58 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 21 Mar 2016 14:45:08 -0700 Subject: [PATCH 035/298] Add a test for settings groups, make sure any bad keys/values are filtered out, update docs. --- includes/api/wc-rest-settings-controller.php | 19 +++++++-- settings-api-docs/locations.md | 7 +++- .../helpers/class-wc-helper-settings.php | 25 ++++++++++++ tests/unit-tests/api/settings.php | 40 ++++++++++++++----- 4 files changed, 75 insertions(+), 16 deletions(-) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index f4988d01da3..1baf4b8a9a7 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -54,7 +54,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { */ public function permissions_check( $request ) { if ( ! current_user_can( 'manage_options' ) ) { - // return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -129,7 +129,10 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { $groups = apply_filters( 'woocommerce_settings_groups_' . $location['id'], array() ); if ( ! empty( $groups ) ) { foreach ( $groups as $group ) { - $location['groups'][] = array( 'id' => $group['id'], 'label' => $group['label'], 'description' => $group['description'] ); + $location['groups'][] = array_intersect_key( + $group, + array_flip( array_filter( array_keys( $group ), array( $this, 'filter_group_keys' ) ) ) + ); } } } @@ -144,7 +147,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { } /** - * Callback for Allowed keys for each location response. + * Callback for allowed keys for each location response. * @since 2.7.0 * @param string $key Key to check * @return boolean @@ -153,6 +156,16 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return in_array( $key, array( 'id', 'type', 'label', 'description', 'groups' ) ); } + /** + * Callback for allowed keys for each group. + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function filter_group_keys( $key ) { + return in_array( $key, array( 'id', 'label', 'description' ) ); + } + /** * Get supported query parameters for locations. * @since 2.7.0 diff --git a/settings-api-docs/locations.md b/settings-api-docs/locations.md index a65f425ceb1..287727402b1 100644 --- a/settings-api-docs/locations.md +++ b/settings-api-docs/locations.md @@ -20,7 +20,7 @@ The coupon data box is considered location and would be represented like so: } -There are 4 fields that make up a location: +There are 4 fields that make up all locations: * _id_: A unique identifier that can be used to link settings together. This shoud be a unique (for the whole system) value. Prefixing with your plugin slug is recommended for non-core changes. Alphanumeric string that contains no spaces. Required. * _type_: Context for where the settings in this location are going to be displayed. Right now core accepts 'page' for settings pages (pages currently under WooCommerce > Settings), 'metabox' (for metabox grouped settings like Coupon Data - this name is subject to change as this API develops), and 'shipping-zone' for settings associated with shipping zone settings. Alphanumeric string that contains no spaces. Required, defaults to 'page'. @@ -29,6 +29,9 @@ There are 4 fields that make up a location: Any other fields passed will be stripped out before the JSON response is sent back to the client. +Locations with type 'page' can also have an associated set of 'groups' which are sub sections/pages. See [groups.md](groups.md). +Pages will return an array of groups in their response. + ## Registering a Location Locations can be registered with the `woocommerce_settings_locations` filter: @@ -53,4 +56,4 @@ There is an optional ?type parameter that allows you to return only locations fo ### GET /settings/locations/$id -Returns information on a single location. \ No newline at end of file +Returns information on a single location + any associated groups. \ No newline at end of file diff --git a/tests/framework/helpers/class-wc-helper-settings.php b/tests/framework/helpers/class-wc-helper-settings.php index 4f3634948ff..af69df7590f 100644 --- a/tests/framework/helpers/class-wc-helper-settings.php +++ b/tests/framework/helpers/class-wc-helper-settings.php @@ -13,6 +13,7 @@ class WC_Helper_Settings { */ public static function register() { add_filter( 'woocommerce_settings_locations', array( 'WC_Helper_Settings', 'register_locations' ) ); + add_filter( 'woocommerce_settings_groups_test', array( 'WC_Helper_Settings', 'register_test_groups' ) ); } /** @@ -29,6 +30,12 @@ class WC_Helper_Settings { 'label' => __( 'Test Extension', 'woocommerce' ), 'description' => __( 'My awesome test settings.', 'woocommerce' ), ); + $locations[] = array( + 'id' => 'test-2', + 'type' => 'page', + 'label' => __( 'Test Extension', 'woocommerce' ), + 'description' => '', + ); $locations[] = array( 'id' => 'coupon-data', 'type' => 'metabox', @@ -43,4 +50,22 @@ class WC_Helper_Settings { return $locations; } + /** + * Registers some example groups for the 'test' page. + * @since 2.7.0 + * @param array $groups + * @return array + */ + public static function register_test_groups( $groups ) { + $groups[] = array( + 'id' => 'general', + 'label' => __( 'General', 'woocommerce' ), + ); + $groups[] = array( + 'id' => 'inventory', + 'label' => __( 'Inventory', 'woocommerce' ), + ); + return $groups; + } + } diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index eacf0c4be0f..93f1b6e7573 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -54,7 +54,7 @@ class Settings extends \WC_Unit_Test_Case { $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $data ) ); + $this->assertEquals( 3, count( $data ) ); $this->check_get_location_response( $data[0], array( 'id' => 'test', @@ -63,7 +63,7 @@ class Settings extends \WC_Unit_Test_Case { 'description' => 'My awesome test settings.', ) ); - $this->check_get_location_response( $data[1], array( + $this->check_get_location_response( $data[2], array( 'id' => 'coupon-data', 'type' => 'metabox', 'label' => 'Coupon Data', @@ -108,7 +108,7 @@ class Settings extends \WC_Unit_Test_Case { $request->set_param( 'type', 'not-a-real-type' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); - $this->assertEquals( 2, count( $data ) ); // all results + $this->assertEquals( 3, count( $data ) ); // all results $request = new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ); $request->set_param( 'type', 'page' ); @@ -116,14 +116,7 @@ class Settings extends \WC_Unit_Test_Case { $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $data ) ); - - $this->check_get_location_response( $data[0], array( - 'id' => 'test', - 'type' => 'page', - 'label' => 'Test Extension', - 'description' => 'My awesome test settings.', - ) ); + $this->assertEquals( 2, count( $data ) ); } /** @@ -184,6 +177,31 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 401, $response->get_status() ); } + /** + * Test settings groups (for pages) + * @since 2.7.0 + */ + public function test_settings_groups() { + wp_set_current_user( $this->user ); + + // test getting a non page location + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/coupon-data' ) ); + $data = $response->get_data(); + $this->assertArrayNotHasKey( 'groups', $data ); + + // test getting a page with no groups + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/test-2' ) ); + $data = $response->get_data(); + $this->assertArrayHasKey( 'groups', $data ); + $this->assertEmpty( $data['groups'] ); + + // test getting a page with groups + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/test' ) ); + $data = $response->get_data(); + $this->assertArrayHasKey( 'groups', $data ); + $this->assertEquals( 2, count( $data['groups'] ) ); + } + /** * Ensure valid location data response. * @since 2.7.0 From fa5425109e612dbbf0f0e2c27dd3bc48756b4979 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 23 Mar 2016 12:36:59 -0700 Subject: [PATCH 036/298] Refactor down to two concepts - settings groups and settings. Fix up tests, and start working on returning actual settings and their values. --- includes/api/wc-rest-settings-controller.php | 336 +++++++++++------- .../helpers/class-wc-helper-settings.php | 74 ++-- tests/unit-tests/api/settings.php | 110 ++---- 3 files changed, 284 insertions(+), 236 deletions(-) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index 1baf4b8a9a7..dc10932ad89 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -26,23 +26,31 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @since 2.7.0 */ public function register_routes() { - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/locations', array( + register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_locations' ), + 'callback' => array( $this, 'get_groups' ), 'permission_callback' => array( $this, 'permissions_check' ), - 'args' => $this->get_locations_params(), ), - 'schema' => array( $this, 'get_location_schema' ), + 'schema' => array( $this, 'group_schema' ), ) ); - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/locations/(?P[\w-]+)', array( + register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_location' ), + 'callback' => array( $this, 'get_group' ), 'permission_callback' => array( $this, 'permissions_check' ), ), - 'schema' => array( $this, 'get_location_schema' ), + 'schema' => array( $this, 'group_schema' ), + ) ); + // @todo change this to support settings with array keys / multiple values? + register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_setting' ), + 'permission_callback' => array( $this, 'permissions_check' ), + ), + 'schema' => array( $this, 'setting_schema' ), ) ); } @@ -54,7 +62,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { */ public function permissions_check( $request ) { if ( ! current_user_can( 'manage_options' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + //return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -62,135 +70,112 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { /* |-------------------------------------------------------------------------- - | /settings/locations + | /settings |-------------------------------------------------------------------------- - | Returns a list of "settings" locations so all settings for a particular page - | or location can be properly loaded. + | Returns a list of "settings" groups so all settings for a particular page + | or section can be properly loaded. */ /** - * Get all settings locations. + * Get all settings groups. * @since 2.7.0 - * @param WP_REST_Request $request Full details about the request. + * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function get_locations( $request ) { - $locations = apply_filters( 'woocommerce_settings_locations', array() ); - $defaults = $this->get_location_defaults(); - $filtered_locations = array(); - foreach ( $locations as $location ) { - $location = wp_parse_args( $location, $defaults ); - $location_valid = true; - if ( is_null( $location['id'] ) || is_null( $location['label'] ) || is_null( $location['type'] ) ) { // id, label, and type are required fields - $location_valid = false; - } else if ( ! empty( $request['type'] ) ) { - if ( in_array( $request['type'], $this->get_location_types() ) && $request['type'] !== $location['type'] ) { - $location_valid = false; - } - } + public function get_groups( $request ) { + $groups = apply_filters( 'woocommerce_settings_groups', array() ); + if ( empty( $groups ) ) { + return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); + } - if ( $location_valid ) { - $filtered_locations[] = array_intersect_key( - $location, - array_flip( array_filter( array_keys( $location ), array( $this, 'filter_location_keys' ) ) ) - ); + $defaults = $this->group_defaults(); + $filtered_groups = array(); + foreach ( $groups as $group ) { + $group = wp_parse_args( $group, $defaults ); + if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { + $filtered_groups[] = $this->filter_group( $group ); } } - $response = rest_ensure_response( $filtered_locations ); + + $response = rest_ensure_response( $filtered_groups ); return $response; } /** - * Return a single setting location. + * Return a single setting group and its settings. * @since 2.7.0 - * @param WP_REST_Request $request Full details about the request. + * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function get_location( $request ) { - $locations = apply_filters( 'woocommerce_settings_locations', array() ); - if ( empty( $locations ) ) { - return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); + public function get_group( $request ) { + $groups = apply_filters( 'woocommerce_settings_groups', array() ); + if ( empty( $groups ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } - $index_key = $this->get_array_key_from_location_id( $locations, $request['location'] ); - if ( is_null( $index_key ) || empty( $locations[ $index_key ] ) ) { - return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); + $index_key = array_keys( wp_list_pluck( $groups, 'id' ), $request['group'] ); + if ( empty( $index_key ) || empty( $groups[ $index_key[0] ] ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.' ), array( 'status' => 404 ) ); } - $location = $locations[ $index_key ]; - $defaults = $this->get_location_defaults(); - $location = wp_parse_args( $location, $defaults ); - if ( is_null( $location['id'] ) || is_null( $location['label'] ) || is_null( $location['type'] ) ) { - return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); + $group = wp_parse_args( $groups[ $index_key[0] ], $this->group_defaults() ); + if ( is_null( $group['id'] ) || is_null( $group['label'] ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.' ), array( 'status' => 404 ) ); } - if ( 'page' === $location['type'] ) { - $location['groups'] = array(); - $groups = apply_filters( 'woocommerce_settings_groups_' . $location['id'], array() ); - if ( ! empty( $groups ) ) { - foreach ( $groups as $group ) { - $location['groups'][] = array_intersect_key( - $group, - array_flip( array_filter( array_keys( $group ), array( $this, 'filter_group_keys' ) ) ) - ); + $filtered_group = $this->filter_group( $group ); + $filtered_group['settings'] = array(); + $settings = apply_filters( 'woocommerce_settings_' . $group['id'], array() ); + if ( ! empty( $settings ) ) { + foreach ( $settings as $setting ) { + $setting = $this->filter_setting( $setting ); + $setting['value'] = $this->get_value( $setting['id'] ); + if ( $this->is_valid_type( $setting['type'] ) ) { + $filtered_group['settings'][] = $setting; } } } - $filtered_location = array_intersect_key( - $location, - array_flip( array_filter( array_keys( $location ), array( $this, 'filter_location_keys' ) ) ) - ); - - $response = rest_ensure_response( $filtered_location ); - return $response; + return rest_ensure_response( $filtered_group ); } /** - * Callback for allowed keys for each location response. + * Return a single setting. * @since 2.7.0 - * @param string $key Key to check - * @return boolean + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response */ - public function filter_location_keys( $key ) { - return in_array( $key, array( 'id', 'type', 'label', 'description', 'groups' ) ); + public function get_setting( $request ) { + if ( empty( $request['group'] ) || empty( $request['setting'] ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.' ), array( 'status' => 404 ) ); + } + + $settings = apply_filters( 'woocommerce_settings_' . $request['group'], array() ); + $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $request['setting'] ); + + if ( empty( $array_key ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.' ), array( 'status' => 404 ) ); + } + + $setting = $this->filter_setting( $settings[ $array_key[0] ] ); + $setting['value'] = $this->get_value( $setting['id'] ); + + if ( ! $this->is_valid_type( $setting['type'] ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.' ), array( 'status' => 404 ) ); + } + + return rest_ensure_response( $setting ); } /** - * Callback for allowed keys for each group. - * @since 2.7.0 - * @param string $key Key to check - * @return boolean - */ - public function filter_group_keys( $key ) { - return in_array( $key, array( 'id', 'label', 'description' ) ); - } - - /** - * Get supported query parameters for locations. + * Get the groups schema, conforming to JSON Schema. * @since 2.7.0 * @return array */ - public function get_locations_params() { - $query_params = array(); - - $query_params['type'] = array( - 'description' => __( 'Limit result set to setting locations of a specific type.', 'woocommerce' ), - 'type' => 'string' - ); - - return $query_params; - } - - /** - * Get the locations chema, conforming to JSON Schema. - * @since 2.7.0 - * @return array - */ - public function get_location_schema() { + public function group_schema() { $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'settings-locations', + 'title' => 'settings-group', 'type' => 'object', 'properties' => array( 'id' => array( @@ -200,13 +185,6 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { 'sanitize_callback' => 'sanitize_title', ), ), - 'type' => array( - 'description' => __( 'Context for where the settings in this location are going to be displayed.' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), 'label' => array( 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.' ), 'type' => 'string', @@ -221,6 +199,13 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { 'sanitize_callback' => 'sanitize_text_field', ), ), + 'parent_id' => array( + 'description' => __( 'ID of parent grouping.' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), ), ); @@ -228,44 +213,137 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { } /** - * Returns a list of allowed setting location types. - * @todo move this? + * Get a value from WP's settings API. * @since 2.7.0 - * @return array + * @param string $setting + * @param string $default + * @return mixed */ - protected function get_location_types() { - return apply_filters( 'woocommerce_settings_location_types', array( 'page', 'metabox', 'shipping-zone' ) ); + public function get_value( $setting, $default = '' ) { + if ( strstr( $setting, '[' ) ) { // Array value + parse_str( $setting, $setting_array ); + $setting = current( array_keys( $setting ) ); + $values = get_option( $setting, '' ); + $key = key( $setting_array[ $setting ] ); + if ( isset( $values[ $key ] ) ) { + $value = $values[ $key ]; + } else { + $value = null; + } + } else { // Single value + $value = get_option( $setting, null ); + } + + if ( is_array( $setting ) ) { + $value = array_map( 'stripslashes', $value ); + } elseif ( ! is_null( $value ) ) { + $value = stripslashes( $value ); + } + + return $value === null ? $default : $value; } /** - * Returns default settings for the various locations. null means the field is required. - * @todo move this? - * @since 2.7.0 + * Filters out bad values from the groups array/filter so we + * only return known values via the API. + * @since 2.7.0 + * @param array $group * @return array */ - protected function get_location_defaults() { - return array( - 'id' => null, - 'type' => 'page', - 'label' => null, - 'description' => '', + public function filter_group( $group ) { + return array_intersect_key( + $group, + array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) ); } /** - * Returns the array key for a specific location ID so it can be pulled out of the 'locations' array. - * @todo move this? - * @param array $locations woocommerce_settings_locations - * @param string $id Location ID to get an array key index for - * @return integer|null + * Filters out bad values from the settings array/filter so we + * only return known values via the API. + * @since 2.7.0 + * @param array $setting + * @return array */ - protected function get_array_key_from_location_id( $locations, $id ) { - foreach ( $locations as $key => $location ) { - if ( ! empty( $location['id'] ) && $id === $location['id'] ) { - return $key; - } + public function filter_setting( $setting ) { + $setting = array_intersect_key( + $setting, + array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) + ); + + if ( empty( $setting['options'] ) ) { + unset( $setting['options'] ); } - return null; + + return $setting; + } + + /** + * Callback for allowed keys for each group response. + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function allowed_group_keys( $key ) { + return in_array( $key, array( 'id', 'label', 'description', 'parent_id' ) ); + } + + /** + * Callback for allowed keys for each setting response. + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function allowed_setting_keys( $key ) { + return in_array( $key, array( + 'id', 'label', 'description', 'default', 'tip', + 'placeholder', 'type', 'options', 'value', + ) ); + } + + /** + * Boolean for if a setting type is a valid supported setting type. + * @since 2.7.0 + * @param string $type + * @return boolean + */ + public function is_valid_type( $type ) { + return in_array( $type, array( + 'text', 'email', 'number', 'color', 'password', + 'textarea', 'select', 'multiselect', 'radio', 'checkbox', + ) ); + } + + /** + * Returns default settings for groups. null means the field is required. + * @since 2.7.0 + * @return array + */ + protected function group_defaults() { + return array( + 'id' => null, + 'label' => null, + 'description' => '', + 'parent_id' => '', + ); + } + + /** + * Returns default settings for settings. null means the field is required. + * @since 2.7.0 + * @return array + */ + protected function setting_defaults() { + return array( + 'id' => null, + 'label' => null, + 'type' => null, + 'description' => '', + 'tip' => '', + 'placeholder' => '', + 'default' => '', + 'options' => array(), + 'value' => '', + ); } } diff --git a/tests/framework/helpers/class-wc-helper-settings.php b/tests/framework/helpers/class-wc-helper-settings.php index af69df7590f..c55e86909e5 100644 --- a/tests/framework/helpers/class-wc-helper-settings.php +++ b/tests/framework/helpers/class-wc-helper-settings.php @@ -12,60 +12,74 @@ class WC_Helper_Settings { * @since 2.7.0 */ public static function register() { - add_filter( 'woocommerce_settings_locations', array( 'WC_Helper_Settings', 'register_locations' ) ); - add_filter( 'woocommerce_settings_groups_test', array( 'WC_Helper_Settings', 'register_test_groups' ) ); + add_filter( 'woocommerce_settings_groups', array( 'WC_Helper_Settings', 'register_groups' ) ); + add_filter( 'woocommerce_settings_test', array( 'WC_Helper_Settings', 'register_test_settings' ) ); } /** - * Registers some example locations, including invalid ones that should not show up in JSON responses. + * Registers some example setting groups, including invalid ones that should not show up in JSON responses. * @since 2.7.0 - * @param array $locations + * @param array $groups * @return array */ - public static function register_locations( $locations ) { - $locations[] = array( + public static function register_groups( $groups ) { + $groups[] = array( 'id' => 'test', 'type' => 'page', 'bad' => 'value', 'label' => __( 'Test Extension', 'woocommerce' ), 'description' => __( 'My awesome test settings.', 'woocommerce' ), ); - $locations[] = array( + $groups[] = array( 'id' => 'test-2', 'type' => 'page', 'label' => __( 'Test Extension', 'woocommerce' ), 'description' => '', ); - $locations[] = array( + $groups[] = array( 'id' => 'coupon-data', 'type' => 'metabox', 'label' => __( 'Coupon Data', 'woocommerce' ), ); - $locations[] = array( - 'label' => __( 'Invalid', 'woocommerce' ), - ); - $locations[] = array( + $groups[] = array( 'id' => 'invalid', ); - return $locations; - } - - /** - * Registers some example groups for the 'test' page. - * @since 2.7.0 - * @param array $groups - * @return array - */ - public static function register_test_groups( $groups ) { - $groups[] = array( - 'id' => 'general', - 'label' => __( 'General', 'woocommerce' ), - ); - $groups[] = array( - 'id' => 'inventory', - 'label' => __( 'Inventory', 'woocommerce' ), - ); return $groups; } + /** + * Registers some example settings. + * @since 2.7.0 + * @param array $settings + * @return array + */ + public static function register_settings( $settings ) { + $settings[] = array( + 'id' => 'catalog_options', + 'label' => __( 'Shop & Product Pages', 'woocommerce' ), + 'type' => 'title', + ); + $settings[] = array( + 'id' => 'woocommerce_shop_page_display', + 'label' => __( 'Shop Page Display', 'woocommerce' ), + 'description' => __( 'This controls what is shown on the product archive.', 'woocommerce' ), + 'default' => '', + 'type' => 'select', + 'options' => array( + '' => __( 'Show products', 'woocommerce' ), + 'subcategories' => __( 'Show categories & subcategories', 'woocommerce' ), + 'both' => __( 'Show both', 'woocommerce' ), + ), + ); + $settings[] = array( + 'id' => 'woocommerce_enable_lightbox', + 'label' => __( 'Product Image Gallery', 'woocommerce' ), + 'description' => __( 'Enable Lightbox for product images', 'woocommerce' ), + 'default' => 'yes', + 'tip' => __( 'Product gallery images will open in a lightbox.', 'woocommerce' ), + 'type' => 'checkbox', + ); + return $settings; + } + } diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 93f1b6e7573..bad7176f07e 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -40,57 +40,58 @@ class Settings extends \WC_Unit_Test_Case { */ public function test_register_routes() { $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v1/settings/locations', $routes ); + $this->assertArrayHasKey( '/wc/v1/settings', $routes ); + // @todo test others } /** - * Test getting all locations. + * Test getting all groups. * @since 2.7.0 */ - public function test_get_locations() { + public function test_get_groups() { wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings' ) ); $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); $this->assertEquals( 3, count( $data ) ); - $this->check_get_location_response( $data[0], array( + $this->check_get_group_response( $data[0], array( 'id' => 'test', - 'type' => 'page', 'label' => 'Test Extension', + 'parent_id' => '', 'description' => 'My awesome test settings.', ) ); - $this->check_get_location_response( $data[2], array( + $this->check_get_group_response( $data[2], array( 'id' => 'coupon-data', - 'type' => 'metabox', 'label' => 'Coupon Data', + 'parent_id' => '', 'description' => '', ) ); } /** - * Test /settings/locations without valid permissions/creds. + * Test /settings without valid permissions/creds. * @since 2.7.0 */ - public function test_get_locations_without_permission() { + public function test_get_groups_without_permission() { wp_set_current_user( 0 ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings' ) ); $this->assertEquals( 401, $response->get_status() ); } /** - * Test /settings/locations correctly filters out bad values. + * Test /settings/ correctly filters out bad values. * Handles required fields and bogus fields. * @since 2.7.0 */ - public function test_get_locations_correctly_filters_values() { + public function test_get_groups_correctly_filters_values() { wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings' ) ); $data = $response->get_data(); $this->assertEquals( 'test', $data[0]['id'] ); @@ -98,119 +99,74 @@ class Settings extends \WC_Unit_Test_Case { } /** - * Test /settings/locations with type. + * Test /settings schema. * @since 2.7.0 */ - public function test_get_locations_with_type() { - wp_set_current_user( $this->user ); - - $request = new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ); - $request->set_param( 'type', 'not-a-real-type' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $this->assertEquals( 3, count( $data ) ); // all results - - $request = new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ); - $request->set_param( 'type', 'page' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $data ) ); - } - - /** - * Test /settings/locations schema. - * @since 2.7.0 - */ - public function test_get_location_schema() { - $request = new \WP_REST_Request( 'OPTIONS', '/wc/v1/settings/locations' ); + public function test_get_group_schema() { + $request = new \WP_REST_Request( 'OPTIONS', '/wc/v1/settings' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; $this->assertEquals( 4, count( $properties ) ); $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'type', $properties ); + $this->assertArrayHasKey( 'parent_id', $properties ); $this->assertArrayHasKey( 'label', $properties ); $this->assertArrayHasKey( 'description', $properties ); } /** - * Test getting a single location item. + * Test getting a single group. * @since 2.7.0 */ - public function test_get_location() { + public function test_get_group() { wp_set_current_user( $this->user ); // test getting a location that does not exist - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/not-real' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/not-real' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting the 'invalid' location - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/invalid' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/invalid' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting a valid location - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/coupon-data' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/coupon-data' ) ); $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); - $this->check_get_location_response( $data, array( + $this->check_get_group_response( $data, array( 'id' => 'coupon-data', - 'type' => 'metabox', 'label' => 'Coupon Data', + 'parent_id' => '', 'description' => '', ) ); + + // @todo make sure settings are set correctly } /** - * Test getting a single location item. + * Test getting a single group without permission. * @since 2.7.0 */ - public function test_get_location_without_permission() { + public function test_get_group_without_permission() { wp_set_current_user( 0 ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/coupon-data' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/coupon-data' ) ); $this->assertEquals( 401, $response->get_status() ); } - /** - * Test settings groups (for pages) - * @since 2.7.0 - */ - public function test_settings_groups() { - wp_set_current_user( $this->user ); - - // test getting a non page location - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/coupon-data' ) ); - $data = $response->get_data(); - $this->assertArrayNotHasKey( 'groups', $data ); - - // test getting a page with no groups - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/test-2' ) ); - $data = $response->get_data(); - $this->assertArrayHasKey( 'groups', $data ); - $this->assertEmpty( $data['groups'] ); - - // test getting a page with groups - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/test' ) ); - $data = $response->get_data(); - $this->assertArrayHasKey( 'groups', $data ); - $this->assertEquals( 2, count( $data['groups'] ) ); - } - /** * Ensure valid location data response. * @since 2.7.0 * @param array $response * @param array $expected */ - protected function check_get_location_response( $response, $expected ) { + protected function check_get_group_response( $response, $expected ) { $this->assertEquals( $expected['id'], $response['id'] ); - $this->assertEquals( $expected['type'], $response['type'] ); + $this->assertEquals( $expected['parent_id'], $response['parent_id'] ); $this->assertEquals( $expected['label'], $response['label'] ); $this->assertEquals( $expected['description'], $response['description'] ); } From 05a26440663b3fc9c90dcd9aa0c8076d43d2b1f9 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Thu, 24 Mar 2016 14:01:22 -0700 Subject: [PATCH 037/298] Wrap up settings endpoints for updating, finish tests. --- includes/api/wc-rest-settings-controller.php | 300 ++++++++++++++---- .../helpers/class-wc-helper-settings.php | 10 +- tests/unit-tests/api/settings.php | 284 ++++++++++++++++- 3 files changed, 528 insertions(+), 66 deletions(-) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index dc10932ad89..d1bc059fe28 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -34,22 +34,32 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { ), 'schema' => array( $this, 'group_schema' ), ) ); - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_group' ), 'permission_callback' => array( $this, 'permissions_check' ), ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_settings' ), + 'permission_callback' => array( $this, 'permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), 'schema' => array( $this, 'group_schema' ), ) ); - // @todo change this to support settings with array keys / multiple values? register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_setting' ), 'permission_callback' => array( $this, 'permissions_check' ), ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_setting' ), + 'permission_callback' => array( $this, 'permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), 'schema' => array( $this, 'setting_schema' ), ) ); } @@ -62,20 +72,15 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { */ public function permissions_check( $request ) { if ( ! current_user_can( 'manage_options' ) ) { - //return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( + 'woocommerce_rest_cannot_view', + __( 'Sorry, you cannot access settings.', 'woocommerce' ), + array( 'status' => rest_authorization_required_code() ) + ); } - return true; } - /* - |-------------------------------------------------------------------------- - | /settings - |-------------------------------------------------------------------------- - | Returns a list of "settings" groups so all settings for a particular page - | or section can be properly loaded. - */ - /** * Get all settings groups. * @since 2.7.0 @@ -108,35 +113,11 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @return WP_Error|WP_REST_Response */ public function get_group( $request ) { - $groups = apply_filters( 'woocommerce_settings_groups', array() ); - if ( empty( $groups ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + $group = $this->_get_group_from_request( $request ); + if ( is_wp_error( $group ) ) { + return $group; } - - $index_key = array_keys( wp_list_pluck( $groups, 'id' ), $request['group'] ); - if ( empty( $index_key ) || empty( $groups[ $index_key[0] ] ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.' ), array( 'status' => 404 ) ); - } - - $group = wp_parse_args( $groups[ $index_key[0] ], $this->group_defaults() ); - if ( is_null( $group['id'] ) || is_null( $group['label'] ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.' ), array( 'status' => 404 ) ); - } - - $filtered_group = $this->filter_group( $group ); - $filtered_group['settings'] = array(); - $settings = apply_filters( 'woocommerce_settings_' . $group['id'], array() ); - if ( ! empty( $settings ) ) { - foreach ( $settings as $setting ) { - $setting = $this->filter_setting( $setting ); - $setting['value'] = $this->get_value( $setting['id'] ); - if ( $this->is_valid_type( $setting['type'] ) ) { - $filtered_group['settings'][] = $setting; - } - } - } - - return rest_ensure_response( $filtered_group ); + return rest_ensure_response( $group ); } /** @@ -146,25 +127,171 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @return WP_Error|WP_REST_Response */ public function get_setting( $request ) { + $setting = $this->_get_setting_from_request( $request ); + if ( is_wp_error( $setting ) ) { + return $setting; + } + return rest_ensure_response( $setting ); + } + + /** + * Update a single setting. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function update_setting( $request ) { + $setting = $this->_get_setting_from_request( $request ); + if ( is_wp_error( $setting ) ) { + return $setting; + } + + $value = $setting['value'] = $this->sanitize_setting_value( $setting, $request['value'] ); + update_option( $setting['id'], $value ); + + return rest_ensure_response( $setting ); + } + + /** + * Update a multiple settings at once. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function update_settings( $request ) { + $group = $this->_get_group_from_request( $request ); + if ( is_wp_error( $group ) ) { + return $group; + } + + foreach ( $group['settings'] as $array_key => $setting ) { + if ( isset( $request['values'][ $setting['id'] ] ) ) { + $value = $this->sanitize_setting_value( $setting, $request['values'][ $setting['id'] ] ); + $group['settings'][ $array_key ]['value'] = $value; + update_option( $setting['id'], $value ); + } + } + + return rest_ensure_response( $group ); + } + + /** + * Cleans a value before setting it. + * @since 2.7.0 + * @param array $setting WC Setting Array + * @param mixed $raw_value Raw value from PUT request + * @return mixed Sanitized value + */ + public function sanitize_setting_value( $setting, $raw_value ) { + switch ( $setting['type'] ) { + case 'checkbox' : + $default = ( ! empty( $setting['default'] ) ? $setting['default'] : 'no' ); + $value = ( in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : $default ); + break; + case 'email' : + $value = sanitize_email( $raw_value ); + $default = ( ! empty( $setting['default'] ) ? $setting['default'] : '' ); + $value = ( ! empty( $value ) ? $value : $default ); + break; + case 'textarea' : + $value = wp_kses_post( trim( $raw_value ) ); + break; + case 'multiselect' : + case 'multi_select_countries' : + $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) ); + break; + case 'image_width' : + $value = array(); + if ( isset( $raw_value['width'] ) ) { + $value['width'] = wc_clean( $raw_value['width'] ); + $value['height'] = wc_clean( $raw_value['height'] ); + $value['crop'] = isset( $raw_value['crop'] ) ? 1 : 0; + } else { + $value['width'] = $setting['default']['width']; + $value['height'] = $setting['default']['height']; + $value['crop'] = $setting['default']['crop']; + } + break; + default : + $value = wc_clean( $raw_value ); + break; + } + + // A couple fields changed in the REST API -- we can just pass these too so old filters still work + $setting['desc'] = ( ! empty( $setting['description'] ) ? $setting['description'] : '' ); + $setting['title'] = ( ! empty( $setting['label'] ) ? $setting['label'] : '' ); + + $value = apply_filters( 'woocommerce_admin_settings_sanitize_option', $value, $setting, $raw_value ); + $value = apply_filters( "woocommerce_admin_settings_sanitize_option_" . $setting['id'], $value, $setting, $raw_value ); + do_action( 'woocommerce_update_option', $setting ); + + return $value; + } + + /** + * Takes a valid request and returns back the corresponding setting array. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|array + */ + private function _get_setting_from_request( $request ) { if ( empty( $request['group'] ) || empty( $request['setting'] ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } $settings = apply_filters( 'woocommerce_settings_' . $request['group'], array() ); $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $request['setting'] ); if ( empty( $array_key ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } $setting = $this->filter_setting( $settings[ $array_key[0] ] ); $setting['value'] = $this->get_value( $setting['id'] ); if ( ! $this->is_valid_type( $setting['type'] ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } - return rest_ensure_response( $setting ); + return $setting; + } + + /** + * Takes a valid request and returns back the corresponding group array. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|array + */ + private function _get_group_from_request( $request ) { + $groups = apply_filters( 'woocommerce_settings_groups', array() ); + if ( empty( $groups ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $index_key = array_keys( wp_list_pluck( $groups, 'id' ), $request['group'] ); + if ( empty( $index_key ) || empty( $groups[ $index_key[0] ] ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $group = wp_parse_args( $groups[ $index_key[0] ], $this->group_defaults() ); + if ( is_null( $group['id'] ) || is_null( $group['label'] ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $filtered_group = $this->filter_group( $group ); + $filtered_group['settings'] = array(); + $settings = apply_filters( 'woocommerce_settings_' . $group['id'], array() ); + if ( ! empty( $settings ) ) { + foreach ( $settings as $setting ) { + $setting = $this->filter_setting( $setting ); + $setting['value'] = $this->get_value( $setting['id'] ); + if ( $this->is_valid_type( $setting['type'] ) ) { + $filtered_group['settings'][] = $setting; + } + } + } + + return $filtered_group; } /** @@ -179,30 +306,30 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier that can be used to link settings together.' ), + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_title', ), ), - 'label' => array( - 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.' ), + 'label' => array( + 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.', 'woocommerce' ), 'type' => 'string', - 'arg_options' => array( + 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), - 'description' => array( - 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.' ), + 'description' => array( + 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.', 'woocommerce' ), 'type' => 'string', - 'arg_options' => array( + 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'parent_id' => array( - 'description' => __( 'ID of parent grouping.' ), + 'description' => __( 'ID of parent grouping.', 'woocommerce' ), 'type' => 'string', - 'arg_options' => array( + 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), @@ -212,6 +339,73 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return $this->add_additional_fields_schema( $schema ); } + /** + * Get the settings schema, conforming to JSON Schema. + * @since 2.7.0 + * @return array + */ + public function setting_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'settings', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'label' => array( + 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'description' => array( + 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'mixed', + ), + 'tip' => array( + 'description' => __( 'Extra help text explaining the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'type' => array( + 'description' => __( 'Type of setting. Allowed values: text, email, number, color, password, textarea, select, multiselect, radio, image_width, checkbox.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'options' => array( + 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ), + 'type' => 'array', + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + /** * Get a value from WP's settings API. * @since 2.7.0 diff --git a/tests/framework/helpers/class-wc-helper-settings.php b/tests/framework/helpers/class-wc-helper-settings.php index c55e86909e5..480e5e46add 100644 --- a/tests/framework/helpers/class-wc-helper-settings.php +++ b/tests/framework/helpers/class-wc-helper-settings.php @@ -25,20 +25,18 @@ class WC_Helper_Settings { public static function register_groups( $groups ) { $groups[] = array( 'id' => 'test', - 'type' => 'page', 'bad' => 'value', 'label' => __( 'Test Extension', 'woocommerce' ), 'description' => __( 'My awesome test settings.', 'woocommerce' ), ); $groups[] = array( - 'id' => 'test-2', - 'type' => 'page', - 'label' => __( 'Test Extension', 'woocommerce' ), + 'id' => 'sub-test', + 'parent_id' => 'test', + 'label' => __( 'Sub test', 'woocommerce' ), 'description' => '', ); $groups[] = array( 'id' => 'coupon-data', - 'type' => 'metabox', 'label' => __( 'Coupon Data', 'woocommerce' ), ); $groups[] = array( @@ -53,7 +51,7 @@ class WC_Helper_Settings { * @param array $settings * @return array */ - public static function register_settings( $settings ) { + public static function register_test_settings( $settings ) { $settings[] = array( 'id' => 'catalog_options', 'label' => __( 'Shop & Product Pages', 'woocommerce' ), diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index bad7176f07e..18e3ad0177c 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -41,7 +41,8 @@ class Settings extends \WC_Unit_Test_Case { public function test_register_routes() { $routes = $this->server->get_routes(); $this->assertArrayHasKey( '/wc/v1/settings', $routes ); - // @todo test others + $this->assertArrayHasKey( '/wc/v1/settings/(?P[\w-]+)', $routes ); + $this->assertArrayHasKey( '/wc/v1/settings/(?P[\w-]+)/(?P[\w-]+)', $routes ); } /** @@ -64,6 +65,13 @@ class Settings extends \WC_Unit_Test_Case { 'description' => 'My awesome test settings.', ) ); + $this->check_get_group_response( $data[1], array( + 'id' => 'sub-test', + 'label' => 'Sub test', + 'parent_id' => 'test', + 'description' => '', + ) ); + $this->check_get_group_response( $data[2], array( 'id' => 'coupon-data', 'label' => 'Coupon Data', @@ -99,7 +107,7 @@ class Settings extends \WC_Unit_Test_Case { } /** - * Test /settings schema. + * Test groups schema. * @since 2.7.0 */ public function test_get_group_schema() { @@ -114,6 +122,26 @@ class Settings extends \WC_Unit_Test_Case { $this->assertArrayHasKey( 'description', $properties ); } + /** + * Test settings schema. + * @since 2.7.0 + */ + public function test_get_setting_schema() { + $request = new \WP_REST_Request( 'OPTIONS', '/wc/v1/settings/test/woocommerce_shop_page_display' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 8, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'label', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'default', $properties ); + $this->assertArrayHasKey( 'tip', $properties ); + $this->assertArrayHasKey( 'placeholder', $properties ); + $this->assertArrayHasKey( 'type', $properties ); + $this->assertArrayHasKey( 'options', $properties ); + } + /** * Test getting a single group. * @since 2.7.0 @@ -121,17 +149,17 @@ class Settings extends \WC_Unit_Test_Case { public function test_get_group() { wp_set_current_user( $this->user ); - // test getting a location that does not exist + // test getting a group that does not exist $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/not-real' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); - // test getting the 'invalid' location + // test getting the 'invalid' group $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/invalid' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); - // test getting a valid location + // test getting a valid group $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/coupon-data' ) ); $data = $response->get_data(); @@ -144,7 +172,15 @@ class Settings extends \WC_Unit_Test_Case { 'description' => '', ) ); - // @todo make sure settings are set correctly + // test getting a valid group with settings attached to it + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); + $data = $response->get_data(); + + $this->assertEquals( 2, count( $data['settings'] ) ); + $this->assertEquals( 'woocommerce_shop_page_display', $data['settings'][0]['id'] ); + $this->assertEmpty( $data['settings'][0]['value'] ); + $this->assertEquals( 'woocommerce_enable_lightbox', $data['settings'][1]['id'] ); + $this->assertEquals( 'yes', $data['settings'][1]['value'] ); } /** @@ -159,7 +195,241 @@ class Settings extends \WC_Unit_Test_Case { } /** - * Ensure valid location data response. + * Test updating a single setting. + * @since 2.7.0 + */ + public function test_update_setting() { + wp_set_current_user( $this->user ); + + // test defaults first + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_shop_page_display' ) ); + $data = $response->get_data(); + $this->assertEquals( '', $data['value'] ); + + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); + $data = $response->get_data(); + $this->assertEquals( 'yes', $data['value'] ); + + // test updating shop display setting + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( array( + 'value' => 'both', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'both', $data['value'] ); + $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); + + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( array( + 'value' => 'subcategories', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'subcategories', $data['value'] ); + $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); + + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( array( + 'value' => '', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '', $data['value'] ); + $this->assertEquals( '', get_option( 'woocommerce_shop_page_display' ) ); + + // test updating ligtbox + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); + $request->set_body_params( array( + 'value' => 'no', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'no', $data['value'] ); + $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); + + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); + $request->set_body_params( array( + 'value' => 'yes', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'yes', $data['value'] ); + $this->assertEquals( 'yes', get_option( 'woocommerce_enable_lightbox' ) ); + } + + /** + * Test updating multiple settings at once. + * @since 2.7.0 + */ + public function test_update_settings() { + wp_set_current_user( $this->user ); + + // test defaults first + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); + $data = $response->get_data(); + $this->assertEquals( '', $data['settings'][0]['value'] ); + $this->assertEquals( 'yes', $data['settings'][1]['value'] ); + + // test setting both at once + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s', 'test' ) ); + $request->set_body_params( array( + 'values' => array( + 'woocommerce_shop_page_display' => 'both', + 'woocommerce_enable_lightbox' => 'no', + ), + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 'both', $data['settings'][0]['value'] ); + $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); + $this->assertEquals( 'no', $data['settings'][1]['value'] ); + $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); + + // test updating one, but making sure the other value stays the same + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s', 'test' ) ); + $request->set_body_params( array( + 'values' => array( + 'woocommerce_shop_page_display' => 'subcategories', + ), + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 'subcategories', $data['settings'][0]['value'] ); + $this->assertEquals( 'no', $data['settings'][1]['value'] ); + $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); + $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); + } + + /** + * Test getting a single setting. + * @since 2.7.0 + */ + public function test_get_setting() { + wp_set_current_user( $this->user ); + + // test getting an invalid setting from a group that does not exist + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/not-real/woocommerce_enable_lightbox' ) ); + $data = $response->get_data(); + $this->assertEquals( 404, $response->get_status() ); + + // test getting an invalid setting from a group that does exist + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/invalid/invalid' ) ); + $data = $response->get_data(); + $this->assertEquals( 404, $response->get_status() ); + + // test getting a valid setting + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 'woocommerce_enable_lightbox', $data['id'] ); + $this->assertEquals( 'Product Image Gallery', $data['label'] ); + $this->assertEquals( 'yes', $data['default'] ); + $this->assertEquals( 'Product gallery images will open in a lightbox.', $data['tip'] ); + $this->assertEquals( 'checkbox', $data['type'] ); + $this->assertEquals( 'yes', $data['value'] ); + } + + /** + * Test getting a single setting without valid user permissions. + * @since 2.7.0 + */ + public function test_get_setting_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + + /** + * Test updating a single setting without valid user permissions. + * @since 2.7.0 + */ + public function test_update_setting_without_permission() { + wp_set_current_user( 0 ); + + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); + $request->set_body_params( array( + 'value' => 'yes', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + + /** + * Test updating multiple settings without valid user permissions. + * @since 2.7.0 + */ + public function test_update_settings_without_permission() { + wp_set_current_user( 0 ); + + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s', 'test' ) ); + $request->set_body_params( array( + 'values' => array( + 'woocommerce_shop_page_display' => 'subcategories', + ), + ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Makes sure our sanitize function runs correctly for different types. + * @since 2.7.0 + */ + public function test_sanitize_setting() { + $endpoint = new \WC_Rest_Settings_Controller; + + // checkbox + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'checkbox', 'default' => 'yes' ), 'no' ); + $this->assertEquals( 'no', $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'checkbox', 'default' => 'yes' ), 'yes' ); + $this->assertEquals( 'yes', $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'checkbox', 'default' => 'yes' ), 'invalid' ); + $this->assertEquals( 'yes', $value ); + + // email + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email' ), 'test@woo.local' ); + $this->assertEquals( 'test@woo.local', $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email' ), ' admin@woo.local! ' ); + $this->assertEquals( 'admin@woo.local', $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email' ), 'blah' ); + $this->assertEquals( '', $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email', 'default' => 'woo@woo.local' ), 'blah' ); + $this->assertEquals( 'woo@woo.local', $value ); + + // textarea + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'textarea' ), ' blah' ); + $this->assertEquals( 'blah', $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'textarea' ), 'blah' ); + $this->assertEquals( 'blah', $value ); + + // multiselect / multiselect countries + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'multiselect' ), array( 'test', 'assertEquals( array( 'test', '<test' ), $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'multi_select_countries' ), array( 'test', 'assertEquals( array( 'test', '<test' ), $value ); + + // image_width + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'image_width' ), array( 'width' => ' 100%', 'height' => '25px ' ) ); + $this->assertEquals( array( 'width' => '100%', 'height' => '25px', 'crop' => 0 ), $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'image_width' ), array( 'width' => '100%', 'height' => '25px', 'crop' => 'something' ) ); + $this->assertEquals( array( 'width' => '100%', 'height' => '25px', 'crop' => 1 ), $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'image_width', 'default' => array( 'width' => '50px', 'height' => '50px', 'crop' => true ) ), array() ); + $this->assertEquals( array( 'width' => '50px', 'height' => '50px', 'crop' => 1 ), $value ); + } + + /** + * Ensure valid group data response. * @since 2.7.0 * @param array $response * @param array $expected From 6bb546e11c4ea498ec25414e2f91ba480dcf81e2 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 28 Mar 2016 12:04:26 -0700 Subject: [PATCH 038/298] Wrap up settings api --- .../admin/settings/class-wc-settings-page.php | 18 ++++ includes/api/wc-rest-settings-controller.php | 78 +++++++++++----- .../class-wc-register-classic-settings.php | 88 +++++++++++++++++++ .../helpers/class-wc-helper-settings.php | 7 +- tests/unit-tests/api/settings.php | 80 +++++++++++------ woocommerce.php | 1 + 6 files changed, 215 insertions(+), 57 deletions(-) create mode 100644 includes/class-wc-register-classic-settings.php diff --git a/includes/admin/settings/class-wc-settings-page.php b/includes/admin/settings/class-wc-settings-page.php index fb09893fcd1..7831649cc5f 100644 --- a/includes/admin/settings/class-wc-settings-page.php +++ b/includes/admin/settings/class-wc-settings-page.php @@ -43,6 +43,24 @@ abstract class WC_Settings_Page { add_action( 'woocommerce_settings_save_' . $this->id, array( $this, 'save' ) ); } + /** + * Get settings page ID. + * @since 2.7.0 + * @return string + */ + public function get_id() { + return $this->id; + } + + /** + * Get settings page label. + * @since 2.7.0 + * @return string + */ + public function get_label() { + return $this->label; + } + /** * Add this page to settings. */ diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index d1bc059fe28..dd1c48b973e 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -96,6 +96,14 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { $defaults = $this->group_defaults(); $filtered_groups = array(); foreach ( $groups as $group ) { + $sub_groups = array(); + foreach ( $groups as $_group ) { + if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { + $sub_groups[] = $_group['id']; + } + } + $group['sub_groups'] = $sub_groups; + $group = wp_parse_args( $group, $defaults ); if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { $filtered_groups[] = $this->filter_group( $group ); @@ -194,7 +202,14 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { $value = ( ! empty( $value ) ? $value : $default ); break; case 'textarea' : - $value = wp_kses_post( trim( $raw_value ) ); + $value = wp_kses( trim( $raw_value ), + array_merge( + array( + 'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true ) + ), + wp_kses_allowed_html( 'post' ) + ) + ); break; case 'multiselect' : case 'multi_select_countries' : @@ -239,7 +254,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } - $settings = apply_filters( 'woocommerce_settings_' . $request['group'], array() ); + $settings = apply_filters( 'woocommerce_settings-' . $request['group'], array() ); $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $request['setting'] ); if ( empty( $array_key ) ) { @@ -278,9 +293,18 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } + // Find sub groups + $sub_groups = array(); + foreach ( $groups as $_group ) { + if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { + $sub_groups[] = $_group['id']; + } + } + $filtered_group = $this->filter_group( $group ); $filtered_group['settings'] = array(); - $settings = apply_filters( 'woocommerce_settings_' . $group['id'], array() ); + $settings = apply_filters( 'woocommerce_settings-' . $group['id'], array() ); + if ( ! empty( $settings ) ) { foreach ( $settings as $setting ) { $setting = $this->filter_setting( $setting ); @@ -291,6 +315,8 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { } } + $filtered_group['sub_groups'] = $sub_groups; + return $filtered_group; } @@ -333,6 +359,13 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { 'sanitize_callback' => 'sanitize_text_field', ), ), + 'sub_groups' => array( + 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), ), ); @@ -415,26 +448,26 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { */ public function get_value( $setting, $default = '' ) { if ( strstr( $setting, '[' ) ) { // Array value - parse_str( $setting, $setting_array ); - $setting = current( array_keys( $setting ) ); - $values = get_option( $setting, '' ); - $key = key( $setting_array[ $setting ] ); - if ( isset( $values[ $key ] ) ) { - $value = $values[ $key ]; - } else { - $value = null; - } - } else { // Single value - $value = get_option( $setting, null ); - } + parse_str( $setting, $setting_array ); + $setting = current( array_keys( $setting ) ); + $values = get_option( $setting, '' ); + $key = key( $setting_array[ $setting ] ); + if ( isset( $values[ $key ] ) ) { + $value = $values[ $key ]; + } else { + $value = null; + } + } else { // Single value + $value = get_option( $setting, null ); + } - if ( is_array( $setting ) ) { - $value = array_map( 'stripslashes', $value ); - } elseif ( ! is_null( $value ) ) { - $value = stripslashes( $value ); - } + if ( is_array( $value ) ) { + $value = array_map( 'stripslashes', $value ); + } elseif ( ! is_null( $value ) ) { + $value = stripslashes( $value ); + } - return $value === null ? $default : $value; + return $value === null ? $default : $value; } /** @@ -478,7 +511,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @return boolean */ public function allowed_group_keys( $key ) { - return in_array( $key, array( 'id', 'label', 'description', 'parent_id' ) ); + return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); } /** @@ -518,6 +551,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { 'label' => null, 'description' => '', 'parent_id' => '', + 'sub_groups' => array(), ); } diff --git a/includes/class-wc-register-classic-settings.php b/includes/class-wc-register-classic-settings.php new file mode 100644 index 00000000000..8cb0397f6eb --- /dev/null +++ b/includes/class-wc-register-classic-settings.php @@ -0,0 +1,88 @@ +page = $page; + add_filter( 'woocommerce_settings-' . $this->page->get_id() . '', array( $this, 'register_classic_settings' ) ); + } + + /** + * Registers the actual settings to the group they came from. + * @since 2.7.0 + * @param array $settings Existing registered settings + * @return array + */ + public function register_classic_settings( $settings ) { + $classic_sections = $this->page->get_sections(); + if ( empty( $classic_sections ) ) { + $classic_sections = array( '' ); + } + + foreach ( $classic_sections as $classic_section => $classic_section_label ) { + $classic_settings = $this->page->get_settings( $classic_section ); + foreach ( $classic_settings as $classic_setting ) { + $new_setting = array( + 'id' => $classic_setting['id'], + 'label' => ( ! empty( $classic_setting['title'] ) ? $classic_setting['title'] : '' ), + 'description' => ( ! empty( $classic_setting['desc'] ) ? $classic_setting['desc'] : '' ), + 'type' => $classic_setting['type'], + ); + if ( isset( $classic_setting['default'] ) ) { + $new_setting['default'] = $classic_setting['default']; + } + if ( isset( $classic_setting['options'] ) ) { + $new_setting['options'] = $classic_setting['options']; + } + if ( isset( $classic_setting['desc_tip'] ) ) { + if ( true === $classic_setting['desc_tip'] ) { + $new_setting['tip'] = $classic_setting['desc']; + } else if ( ! empty( $classic_setting['desc_tip'] ) ) { + $new_setting['tip'] = $classic_setting['desc_tip']; + } + } + $settings[] = $new_setting; + } + } + return $settings; + } +} + +/** + * Register full settings sections to a single group. + * @since 2.7.0 + * @param array $groups Existing registered groups. + * @return array + */ + function wc_settings_api_register_classic_groups( $groups ) { + $pages = WC_Admin_Settings::get_settings_pages(); + foreach ( $pages as $page ) { + $groups[] = array( + 'id' => $page->get_id(), + 'label' => $page->get_label(), + ); + new WC_Register_Classic_Settings( $page ); + } + return $groups; +} + +add_action( 'woocommerce_settings_groups', 'wc_settings_api_register_classic_groups' ); diff --git a/tests/framework/helpers/class-wc-helper-settings.php b/tests/framework/helpers/class-wc-helper-settings.php index 480e5e46add..2a042bc624b 100644 --- a/tests/framework/helpers/class-wc-helper-settings.php +++ b/tests/framework/helpers/class-wc-helper-settings.php @@ -13,7 +13,7 @@ class WC_Helper_Settings { */ public static function register() { add_filter( 'woocommerce_settings_groups', array( 'WC_Helper_Settings', 'register_groups' ) ); - add_filter( 'woocommerce_settings_test', array( 'WC_Helper_Settings', 'register_test_settings' ) ); + add_filter( 'woocommerce_settings-test', array( 'WC_Helper_Settings', 'register_test_settings' ) ); } /** @@ -52,11 +52,6 @@ class WC_Helper_Settings { * @return array */ public static function register_test_settings( $settings ) { - $settings[] = array( - 'id' => 'catalog_options', - 'label' => __( 'Shop & Product Pages', 'woocommerce' ), - 'type' => 'title', - ); $settings[] = array( 'id' => 'woocommerce_shop_page_display', 'label' => __( 'Shop Page Display', 'woocommerce' ), diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 18e3ad0177c..c43943e1634 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -56,28 +56,22 @@ class Settings extends \WC_Unit_Test_Case { $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 3, count( $data ) ); - $this->check_get_group_response( $data[0], array( + $this->assertContains( array( 'id' => 'test', 'label' => 'Test Extension', 'parent_id' => '', 'description' => 'My awesome test settings.', - ) ); + 'sub_groups' => array( 'sub-test' ), + ), $data ); - $this->check_get_group_response( $data[1], array( + $this->assertContains( array( 'id' => 'sub-test', 'label' => 'Sub test', 'parent_id' => 'test', 'description' => '', - ) ); - - $this->check_get_group_response( $data[2], array( - 'id' => 'coupon-data', - 'label' => 'Coupon Data', - 'parent_id' => '', - 'description' => '', - ) ); + 'sub_groups' => array(), + ), $data ); } /** @@ -91,21 +85,6 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 401, $response->get_status() ); } - /** - * Test /settings/ correctly filters out bad values. - * Handles required fields and bogus fields. - * @since 2.7.0 - */ - public function test_get_groups_correctly_filters_values() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings' ) ); - $data = $response->get_data(); - - $this->assertEquals( 'test', $data[0]['id'] ); - $this->assertArrayNotHasKey( 'bad', $data[0] ); - } - /** * Test groups schema. * @since 2.7.0 @@ -115,11 +94,12 @@ class Settings extends \WC_Unit_Test_Case { $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; - $this->assertEquals( 4, count( $properties ) ); + $this->assertEquals( 5, count( $properties ) ); $this->assertArrayHasKey( 'id', $properties ); $this->assertArrayHasKey( 'parent_id', $properties ); $this->assertArrayHasKey( 'label', $properties ); $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'sub_groups', $properties ); } /** @@ -172,15 +152,17 @@ class Settings extends \WC_Unit_Test_Case { 'description' => '', ) ); + $this->assertEmpty( $data['sub_groups'] ); + // test getting a valid group with settings attached to it $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); $data = $response->get_data(); - $this->assertEquals( 2, count( $data['settings'] ) ); $this->assertEquals( 'woocommerce_shop_page_display', $data['settings'][0]['id'] ); $this->assertEmpty( $data['settings'][0]['value'] ); $this->assertEquals( 'woocommerce_enable_lightbox', $data['settings'][1]['id'] ); $this->assertEquals( 'yes', $data['settings'][1]['value'] ); + $this->assertEquals( array( 'sub-test' ), $data['sub_groups'] ); } /** @@ -428,6 +410,46 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( array( 'width' => '50px', 'height' => '50px', 'crop' => 1 ), $value ); } + /** + * Tests our classic setting registeration to make sure settings added for WP-Admin are available over the API. + * @since 2.7.0 + */ + public function test_classic_settings() { + wp_set_current_user( $this->user ); + + // Make sure the group is properly registered + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/products' ) ); + $data = $response->get_data(); + + $this->assertEquals( 'products', $data['id'] ); + $this->assertContains( array( + 'id' => 'woocommerce_downloads_require_login', + 'label' => 'Access Restriction', + 'description' => 'Downloads require login', + 'type' => 'checkbox', + 'default' => 'no', + 'tip' => 'This setting does not apply to guest purchases.', + 'value' => 'no', + ), $data['settings'] ); + + // test get single + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/products/woocommerce_dimension_unit' ) ); + $data = $response->get_data(); + + $this->assertEquals( 'cm', $data['default'] ); + + // test update + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) ); + $request->set_body_params( array( + 'value' => 'yd', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'yd', $data['value'] ); + $this->assertEquals( 'yd', get_option(' woocommerce_dimension_unit' ) ); + } + /** * Ensure valid group data response. * @since 2.7.0 diff --git a/woocommerce.php b/woocommerce.php index cb72b03e635..eede4602473 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -225,6 +225,7 @@ final class WooCommerce { public function includes() { include_once( 'includes/class-wc-autoloader.php' ); include_once( 'includes/wc-core-functions.php' ); + include_once( 'includes/class-wc-register-classic-settings.php' ); include_once( 'includes/wc-widget-functions.php' ); include_once( 'includes/wc-webhook-functions.php' ); include_once( 'includes/class-wc-install.php' ); From 9f7c769c4fc93fd6a3f3b200ebf362ded4c12701 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 28 Mar 2016 12:08:43 -0700 Subject: [PATCH 039/298] Remove settings api docs, moving to wiki --- settings-api-docs/README.md | 83 ---------------------------------- settings-api-docs/groups.md | 58 ------------------------ settings-api-docs/locations.md | 59 ------------------------ 3 files changed, 200 deletions(-) delete mode 100644 settings-api-docs/README.md delete mode 100644 settings-api-docs/groups.md delete mode 100644 settings-api-docs/locations.md diff --git a/settings-api-docs/README.md b/settings-api-docs/README.md deleted file mode 100644 index c5d06efa821..00000000000 --- a/settings-api-docs/README.md +++ /dev/null @@ -1,83 +0,0 @@ -# Settings API Proposal - -The Settings API is a set of WP-API endpoints that return information about WooCommerce settings. Settings can also be updated with the API. - -The API should be capable of handling settings in many different contexts including pages (WooCommerce > Settings), "metaboxes" (product data, coupon data), shipping zones, and be extendable to other contexts in the future. - -All settings are registered with PHP filters. Not through the REST API. The REST API is only for retrieving settings and updating them. - -## Locations -[locations.md](locations.md) - -## Groups -[groups.md](groups.md) - -# The below sections are being moved to their own doc files (and may change) as the API gets fleshed out. - -## /settings/$identifer - -Gets the actual settings to be displayed in a specific area. You can load settings for a specific group, or for a specific metabox. - -GET /settings/page:products:general would return settings for Settings > Products > General. -GET /settings/metabox:coupons would return settings for Coupons > Add New Coupon > Coupon Data metabox. - -To register settings: - - // The filter (page_products_general) should match the identifer for the area we are loading settings for. - apply_filters( 'woocommerce_settings_page_products_general', array( - array( - 'label' => __( 'Measurements', 'woocommerce' ), - 'type' => 'title', - 'id' => 'product_measurement_options' - ), - array( - 'label' => __( 'Weight Unit', 'woocommerce' ), - 'description' => __( 'This controls what unit you will define weights in.', 'woocommerce' ), - 'id' => 'woocommerce_weight_unit', - 'default' => 'kg', - 'type' => 'select', - 'options' => array( - 'kg' => __( 'kg', 'woocommerce' ), - 'g' => __( 'g', 'woocommerce' ), - 'lbs' => __( 'lbs', 'woocommerce' ), - 'oz' => __( 'oz', 'woocommerce' ), - ), - ) - ) ); - -Settings response: - - [ - { - "label": "Measurements", - "type": "title", - "id": "product_measurement_options" - }, - { - "label": "Weight Unit", - "description": "This controls what unit you will define weights in.", - "id": "woocommerce_weight_unit", - "default": "kg", - "type": "select", - "options": { - "kg": "kg", - "g": "g", - "lbs": "lbs", - "oz": "oz" - } - } - ] - -We should different form input types for 'type', text, textarea, select, radio, checkbox, ... - -## GET /settings/$identifer/$setting - -Get data for an individual setting. - -## PUT /settings/$identifer/$setting - -Update a setting by passing a new 'value' in the body. A success response will be returned. - -## PUT /settings/$identifer - -Update multiple settings at the same time with key => value pairs. A success response will be returned. diff --git a/settings-api-docs/groups.md b/settings-api-docs/groups.md deleted file mode 100644 index 60ddf19d7fd..00000000000 --- a/settings-api-docs/groups.md +++ /dev/null @@ -1,58 +0,0 @@ -# Groups - -## Basic Info - -Groups are settings thats are grouped together on setting pages _only_ (type=page). That means setting locations like metaboxes don't have groups. - -For example, a location would be the 'Products' page. -The products page would ave the following groups: 'General', 'Display', 'Inventory', and 'Downloadable Products'. - -![](https://cldup.com/qXlfpvItr6-3000x3000.png) - - { - "id": "general", - "label": "General", - "description": "" - } - -There are 3 fields that make up a group: - -* _id_: A unique identifier that can be used to link settings together. The identifiers for groups only need to be unique on a specific page, so you can have a 'general' group under 'Products' and a 'general' group under Shipping. Alphanumeric string that contains no spaces. Required. -* _label_: A human readable label. This is a translated string that can be used in the UI. Required. -* _description_: A human readable description. This is a translated string that can be used in the UI. Optional. - -Any other fields passed will be stripped out before the JSON response is sent back to the client. - -## Registering a group - -Groups can be registered with the `woocommerce_settings_groups_{$location_id}` filter: - - add_filter( 'woocommerce_settings_groups_products', function( $groups ) { - $groups[] = array( - 'id' => 'extra-settings', - 'label' => __( 'Extras', 'woocommerce-test-extension' ), - 'description' => '', - ); - return $groups; - } ); - - -## Endpoints - -There are no separate endpoints for groups. You can access a list of groups for a specific page/location by calling that location's endpoint. - -### GET /settings/locations/$id - - { - "id": "test", - "type": "page", - "label": "Test Extension", - "description": "My awesome test settings.", - "groups": [ - { - "id": "general", - "label": "General", - "description": "" - } - ] - } \ No newline at end of file diff --git a/settings-api-docs/locations.md b/settings-api-docs/locations.md deleted file mode 100644 index 287727402b1..00000000000 --- a/settings-api-docs/locations.md +++ /dev/null @@ -1,59 +0,0 @@ -# Locations - -## Basic Info - -Settings can be grouped together by location. - -A location is just a grouping of settings that all share a common 'location' key. -This is so you can pull all settings meant to be displayed together in a particular area. - -Example: - -In wp-admin there is a "Coupon Data" box on the "Add New Coupon" page. -The coupon data box is considered location and would be represented like so: - - { - "id": "coupon-data", - "type": "metabox", - "label": "Coupon Data", - "description": "" - } - - -There are 4 fields that make up all locations: - -* _id_: A unique identifier that can be used to link settings together. This shoud be a unique (for the whole system) value. Prefixing with your plugin slug is recommended for non-core changes. Alphanumeric string that contains no spaces. Required. -* _type_: Context for where the settings in this location are going to be displayed. Right now core accepts 'page' for settings pages (pages currently under WooCommerce > Settings), 'metabox' (for metabox grouped settings like Coupon Data - this name is subject to change as this API develops), and 'shipping-zone' for settings associated with shipping zone settings. Alphanumeric string that contains no spaces. Required, defaults to 'page'. -* _label_: A human readable label. This is a translated string that can be used in the UI. Required. -* _description_: A human readable description. This is a translated string that can be used in the UI. Optional. - -Any other fields passed will be stripped out before the JSON response is sent back to the client. - -Locations with type 'page' can also have an associated set of 'groups' which are sub sections/pages. See [groups.md](groups.md). -Pages will return an array of groups in their response. - -## Registering a Location - -Locations can be registered with the `woocommerce_settings_locations` filter: - - add_filter( 'woocommerce_settings_locations', function( $locations ) { - $locations[] = array( - 'id' => 'test-extension', - 'type' => 'page', - 'label' => __( 'Test Extension', 'woocommerce-test-extension' ), - 'description' => __( 'My awesome test settings.', 'woocommerce-test-extension' ), - ); - return $locations; - } ); - - -## Endpoints - -### GET /settings/locations - -Returns a list of all locations supported by WC. -There is an optional ?type parameter that allows you to return only locations for a specific context (like all page locations). - -### GET /settings/locations/$id - -Returns information on a single location + any associated groups. \ No newline at end of file From 8c211b87ef7c53f3b5011573e29dc3b6a60a605e Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 28 Mar 2016 13:51:17 -0700 Subject: [PATCH 040/298] Fix how classic groups/settings are registered so that they are always avaiable when calling filters. --- includes/api/wc-rest-settings-controller.php | 3 +- .../class-wc-register-classic-settings.php | 40 +++++++++++-------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index dd1c48b973e..53c634f0fa6 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -537,6 +537,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return in_array( $type, array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'checkbox', + 'multi_select_countries', 'image_width', ) ); } @@ -563,7 +564,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { protected function setting_defaults() { return array( 'id' => null, - 'label' => null, + 'label' => '', 'type' => null, 'description' => '', 'tip' => '', diff --git a/includes/class-wc-register-classic-settings.php b/includes/class-wc-register-classic-settings.php index 8cb0397f6eb..d5351b3406a 100644 --- a/includes/class-wc-register-classic-settings.php +++ b/includes/class-wc-register-classic-settings.php @@ -23,7 +23,22 @@ class WC_Register_Classic_Settings { */ public function __construct( $page ) { $this->page = $page; - add_filter( 'woocommerce_settings-' . $this->page->get_id() . '', array( $this, 'register_classic_settings' ) ); + add_filter( 'woocommerce_settings_groups', array( $this, 'register_classic_group' ) ); + add_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $this, 'register_classic_settings' ) ); + } + + /** + * Registers a setting group. + * @since 2.7.0 + * @param array $group + * @return array + */ + public function register_classic_group( $groups ) { + $groups[] = array( + 'id' => $this->page->get_id(), + 'label' => $this->page->get_label(), + ); + return $groups; } /** @@ -68,21 +83,14 @@ class WC_Register_Classic_Settings { } /** - * Register full settings sections to a single group. + * Register full classic settings to the REST API. * @since 2.7.0 - * @param array $groups Existing registered groups. - * @return array */ - function wc_settings_api_register_classic_groups( $groups ) { - $pages = WC_Admin_Settings::get_settings_pages(); - foreach ( $pages as $page ) { - $groups[] = array( - 'id' => $page->get_id(), - 'label' => $page->get_label(), - ); - new WC_Register_Classic_Settings( $page ); - } - return $groups; -} + function wc_settings_api_register_classic() { + $pages = WC_Admin_Settings::get_settings_pages(); + foreach ( $pages as $page ) { + new WC_Register_Classic_Settings( $page ); + } + } -add_action( 'woocommerce_settings_groups', 'wc_settings_api_register_classic_groups' ); +add_action( 'rest_api_init', 'wc_settings_api_register_classic' ); From e814dcc2f4de600ff1cedae74898f123aed111c9 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 30 Mar 2016 09:46:20 -0700 Subject: [PATCH 041/298] Rename classic -> legacy --- .../class-wc-register-classic-settings.php | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/includes/class-wc-register-classic-settings.php b/includes/class-wc-register-classic-settings.php index d5351b3406a..ba314b0f030 100644 --- a/includes/class-wc-register-classic-settings.php +++ b/includes/class-wc-register-classic-settings.php @@ -12,19 +12,19 @@ if ( ! defined( 'ABSPATH' ) ) { * @package WooCommerce/Classes * @category Class */ -class WC_Register_Classic_Settings { +class WC_Register_Legacy_Settings { /** @var class Current settings class. Used to pull settings. */ protected $page; /** - * Hooks into the settings API and starts registering our classic settings. + * Hooks into the settings API and starts registering our settings registered via legacy hooks/filters. * @since 2.7.0 */ public function __construct( $page ) { $this->page = $page; - add_filter( 'woocommerce_settings_groups', array( $this, 'register_classic_group' ) ); - add_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $this, 'register_classic_settings' ) ); + add_filter( 'woocommerce_settings_groups', array( $this, 'register_legacy_group' ) ); + add_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $this, 'register_legacy_settings' ) ); } /** @@ -33,7 +33,7 @@ class WC_Register_Classic_Settings { * @param array $group * @return array */ - public function register_classic_group( $groups ) { + public function register_legacy_group( $groups ) { $groups[] = array( 'id' => $this->page->get_id(), 'label' => $this->page->get_label(), @@ -47,32 +47,32 @@ class WC_Register_Classic_Settings { * @param array $settings Existing registered settings * @return array */ - public function register_classic_settings( $settings ) { - $classic_sections = $this->page->get_sections(); - if ( empty( $classic_sections ) ) { - $classic_sections = array( '' ); + public function register_legacy_settings( $settings ) { + $legacy_sections = $this->page->get_sections(); + if ( empty( $legacy_sections ) ) { + $legacy_sections = array( '' ); } - foreach ( $classic_sections as $classic_section => $classic_section_label ) { - $classic_settings = $this->page->get_settings( $classic_section ); - foreach ( $classic_settings as $classic_setting ) { + foreach ( $legacy_sections as $legacy_section => $legacy_section_label ) { + $legacy_settings = $this->page->get_settings( $legacy_section ); + foreach ( $legacy_settings as $legacy_setting ) { $new_setting = array( - 'id' => $classic_setting['id'], - 'label' => ( ! empty( $classic_setting['title'] ) ? $classic_setting['title'] : '' ), - 'description' => ( ! empty( $classic_setting['desc'] ) ? $classic_setting['desc'] : '' ), - 'type' => $classic_setting['type'], + 'id' => $legacy_setting['id'], + 'label' => ( ! empty( $legacy_setting['title'] ) ? $legacy_setting['title'] : '' ), + 'description' => ( ! empty( $legacy_setting['desc'] ) ? $legacy_setting['desc'] : '' ), + 'type' => $legacy_setting['type'], ); - if ( isset( $classic_setting['default'] ) ) { - $new_setting['default'] = $classic_setting['default']; + if ( isset( $legacy_setting['default'] ) ) { + $new_setting['default'] = $legacy_setting['default']; } - if ( isset( $classic_setting['options'] ) ) { - $new_setting['options'] = $classic_setting['options']; + if ( isset( $legacy_setting['options'] ) ) { + $new_setting['options'] = $legacy_setting['options']; } - if ( isset( $classic_setting['desc_tip'] ) ) { - if ( true === $classic_setting['desc_tip'] ) { - $new_setting['tip'] = $classic_setting['desc']; - } else if ( ! empty( $classic_setting['desc_tip'] ) ) { - $new_setting['tip'] = $classic_setting['desc_tip']; + if ( isset( $legacy_setting['desc_tip'] ) ) { + if ( true === $legacy_setting['desc_tip'] ) { + $new_setting['tip'] = $legacy_setting['desc']; + } else if ( ! empty( $legacy_setting['desc_tip'] ) ) { + $new_setting['tip'] = $legacy_setting['desc_tip']; } } $settings[] = $new_setting; @@ -83,14 +83,14 @@ class WC_Register_Classic_Settings { } /** - * Register full classic settings to the REST API. + * Register legacy settings to the REST API. * @since 2.7.0 */ - function wc_settings_api_register_classic() { + function wc_settings_api_register_legacy() { $pages = WC_Admin_Settings::get_settings_pages(); foreach ( $pages as $page ) { - new WC_Register_Classic_Settings( $page ); + new WC_Register_Legacy_Settings( $page ); } } -add_action( 'rest_api_init', 'wc_settings_api_register_classic' ); +add_action( 'rest_api_init', 'wc_settings_api_register_legacy' ); From 5d0e15fdaedebd8422b8530d3823f3f14fc38630 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 30 Mar 2016 09:47:42 -0700 Subject: [PATCH 042/298] Rename classic settings file to legacy settings --- ...assic-settings.php => class-wc-register-legacy-settings.php} | 0 woocommerce.php | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename includes/{class-wc-register-classic-settings.php => class-wc-register-legacy-settings.php} (100%) diff --git a/includes/class-wc-register-classic-settings.php b/includes/class-wc-register-legacy-settings.php similarity index 100% rename from includes/class-wc-register-classic-settings.php rename to includes/class-wc-register-legacy-settings.php diff --git a/woocommerce.php b/woocommerce.php index eede4602473..8c3bb8d5353 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -225,7 +225,7 @@ final class WooCommerce { public function includes() { include_once( 'includes/class-wc-autoloader.php' ); include_once( 'includes/wc-core-functions.php' ); - include_once( 'includes/class-wc-register-classic-settings.php' ); + include_once( 'includes/class-wc-register-legacy-settings.php' ); include_once( 'includes/wc-widget-functions.php' ); include_once( 'includes/wc-webhook-functions.php' ); include_once( 'includes/class-wc-install.php' ); From 170e2a1346b8aaad03b55d061808ce166138fb2f Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 30 Mar 2016 10:29:57 -0700 Subject: [PATCH 043/298] Split settings and groups controllers into two separate files. --- includes/api/wc-rest-settings-base.php | 178 ++++++++ includes/api/wc-rest-settings-controller.php | 412 +----------------- .../wc-rest-settings-groups-controller.php | 257 +++++++++++ includes/class-wc-api.php | 3 + 4 files changed, 441 insertions(+), 409 deletions(-) create mode 100644 includes/api/wc-rest-settings-base.php create mode 100644 includes/api/wc-rest-settings-groups-controller.php diff --git a/includes/api/wc-rest-settings-base.php b/includes/api/wc-rest-settings-base.php new file mode 100644 index 00000000000..753ff0e0e35 --- /dev/null +++ b/includes/api/wc-rest-settings-base.php @@ -0,0 +1,178 @@ + rest_authorization_required_code() ) + ); + } + return true; + } + + /** + * Cleans a value before setting it. + * @since 2.7.0 + * @param array $setting WC Setting Array + * @param mixed $raw_value Raw value from PUT request + * @return mixed Sanitized value + */ + public function sanitize_setting_value( $setting, $raw_value ) { + switch ( $setting['type'] ) { + case 'checkbox' : + $default = ( ! empty( $setting['default'] ) ? $setting['default'] : 'no' ); + $value = ( in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : $default ); + break; + case 'email' : + $value = sanitize_email( $raw_value ); + $default = ( ! empty( $setting['default'] ) ? $setting['default'] : '' ); + $value = ( ! empty( $value ) ? $value : $default ); + break; + case 'textarea' : + $value = wp_kses( trim( $raw_value ), + array_merge( + array( + 'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true ) + ), + wp_kses_allowed_html( 'post' ) + ) + ); + break; + case 'multiselect' : + case 'multi_select_countries' : + $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) ); + break; + case 'image_width' : + $value = array(); + if ( isset( $raw_value['width'] ) ) { + $value['width'] = wc_clean( $raw_value['width'] ); + $value['height'] = wc_clean( $raw_value['height'] ); + $value['crop'] = isset( $raw_value['crop'] ) ? 1 : 0; + } else { + $value['width'] = $setting['default']['width']; + $value['height'] = $setting['default']['height']; + $value['crop'] = $setting['default']['crop']; + } + break; + default : + $value = wc_clean( $raw_value ); + break; + } + + // A couple fields changed in the REST API -- we can just pass these too so old filters still work + $setting['desc'] = ( ! empty( $setting['description'] ) ? $setting['description'] : '' ); + $setting['title'] = ( ! empty( $setting['label'] ) ? $setting['label'] : '' ); + + $value = apply_filters( 'woocommerce_admin_settings_sanitize_option', $value, $setting, $raw_value ); + $value = apply_filters( "woocommerce_admin_settings_sanitize_option_" . $setting['id'], $value, $setting, $raw_value ); + do_action( 'woocommerce_update_option', $setting ); + + return $value; + } + + /** + * Get a value from WP's settings API. + * @since 2.7.0 + * @param string $setting + * @param string $default + * @return mixed + */ + public function get_value( $setting, $default = '' ) { + if ( strstr( $setting, '[' ) ) { // Array value + parse_str( $setting, $setting_array ); + $setting = current( array_keys( $setting ) ); + $values = get_option( $setting, '' ); + $key = key( $setting_array[ $setting ] ); + if ( isset( $values[ $key ] ) ) { + $value = $values[ $key ]; + } else { + $value = null; + } + } else { // Single value + $value = get_option( $setting, null ); + } + + if ( is_array( $value ) ) { + $value = array_map( 'stripslashes', $value ); + } elseif ( ! is_null( $value ) ) { + $value = stripslashes( $value ); + } + + return $value === null ? $default : $value; + } + + /** + * Filters out bad values from the settings array/filter so we + * only return known values via the API. + * @since 2.7.0 + * @param array $setting + * @return array + */ + public function filter_setting( $setting ) { + $setting = array_intersect_key( + $setting, + array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) + ); + + if ( empty( $setting['options'] ) ) { + unset( $setting['options'] ); + } + + return $setting; + } + + /** + * Callback for allowed keys for each setting response. + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function allowed_setting_keys( $key ) { + return in_array( $key, array( + 'id', 'label', 'description', 'default', 'tip', + 'placeholder', 'type', 'options', 'value', + ) ); + } + + /** + * Boolean for if a setting type is a valid supported setting type. + * @since 2.7.0 + * @param string $type + * @return boolean + */ + public function is_setting_type_valid( $type ) { + return in_array( $type, array( + 'text', 'email', 'number', 'color', 'password', + 'textarea', 'select', 'multiselect', 'radio', 'checkbox', + 'multi_select_countries', 'image_width', + ) ); + } + +} diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index 53c634f0fa6..2da91e3cbff 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Settings Controller. - * Handles requests to the /settings endpoints. + * Handles requests to the /settings/$group/$setting endpoints. * * @author WooThemes * @category API @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Controller extends WP_Rest_Controller { +class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { /** * Route base. @@ -26,28 +26,6 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @since 2.7.0 */ public function register_routes() { - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base, array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_groups' ), - 'permission_callback' => array( $this, 'permissions_check' ), - ), - 'schema' => array( $this, 'group_schema' ), - ) ); - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)', array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_group' ), - 'permission_callback' => array( $this, 'permissions_check' ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_settings' ), - 'permission_callback' => array( $this, 'permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'group_schema' ), - ) ); register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, @@ -64,70 +42,6 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { ) ); } - /** - * Makes sure the current user has access to the settings APIs. - * @since 2.7.0 - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function permissions_check( $request ) { - if ( ! current_user_can( 'manage_options' ) ) { - return new WP_Error( - 'woocommerce_rest_cannot_view', - __( 'Sorry, you cannot access settings.', 'woocommerce' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - return true; - } - - /** - * Get all settings groups. - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|WP_REST_Response - */ - public function get_groups( $request ) { - $groups = apply_filters( 'woocommerce_settings_groups', array() ); - if ( empty( $groups ) ) { - return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); - } - - $defaults = $this->group_defaults(); - $filtered_groups = array(); - foreach ( $groups as $group ) { - $sub_groups = array(); - foreach ( $groups as $_group ) { - if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { - $sub_groups[] = $_group['id']; - } - } - $group['sub_groups'] = $sub_groups; - - $group = wp_parse_args( $group, $defaults ); - if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { - $filtered_groups[] = $this->filter_group( $group ); - } - } - - $response = rest_ensure_response( $filtered_groups ); - return $response; - } - - /** - * Return a single setting group and its settings. - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|WP_REST_Response - */ - public function get_group( $request ) { - $group = $this->_get_group_from_request( $request ); - if ( is_wp_error( $group ) ) { - return $group; - } - return rest_ensure_response( $group ); - } - /** * Return a single setting. * @since 2.7.0 @@ -160,89 +74,6 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return rest_ensure_response( $setting ); } - /** - * Update a multiple settings at once. - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|WP_REST_Response - */ - public function update_settings( $request ) { - $group = $this->_get_group_from_request( $request ); - if ( is_wp_error( $group ) ) { - return $group; - } - - foreach ( $group['settings'] as $array_key => $setting ) { - if ( isset( $request['values'][ $setting['id'] ] ) ) { - $value = $this->sanitize_setting_value( $setting, $request['values'][ $setting['id'] ] ); - $group['settings'][ $array_key ]['value'] = $value; - update_option( $setting['id'], $value ); - } - } - - return rest_ensure_response( $group ); - } - - /** - * Cleans a value before setting it. - * @since 2.7.0 - * @param array $setting WC Setting Array - * @param mixed $raw_value Raw value from PUT request - * @return mixed Sanitized value - */ - public function sanitize_setting_value( $setting, $raw_value ) { - switch ( $setting['type'] ) { - case 'checkbox' : - $default = ( ! empty( $setting['default'] ) ? $setting['default'] : 'no' ); - $value = ( in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : $default ); - break; - case 'email' : - $value = sanitize_email( $raw_value ); - $default = ( ! empty( $setting['default'] ) ? $setting['default'] : '' ); - $value = ( ! empty( $value ) ? $value : $default ); - break; - case 'textarea' : - $value = wp_kses( trim( $raw_value ), - array_merge( - array( - 'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true ) - ), - wp_kses_allowed_html( 'post' ) - ) - ); - break; - case 'multiselect' : - case 'multi_select_countries' : - $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) ); - break; - case 'image_width' : - $value = array(); - if ( isset( $raw_value['width'] ) ) { - $value['width'] = wc_clean( $raw_value['width'] ); - $value['height'] = wc_clean( $raw_value['height'] ); - $value['crop'] = isset( $raw_value['crop'] ) ? 1 : 0; - } else { - $value['width'] = $setting['default']['width']; - $value['height'] = $setting['default']['height']; - $value['crop'] = $setting['default']['crop']; - } - break; - default : - $value = wc_clean( $raw_value ); - break; - } - - // A couple fields changed in the REST API -- we can just pass these too so old filters still work - $setting['desc'] = ( ! empty( $setting['description'] ) ? $setting['description'] : '' ); - $setting['title'] = ( ! empty( $setting['label'] ) ? $setting['label'] : '' ); - - $value = apply_filters( 'woocommerce_admin_settings_sanitize_option', $value, $setting, $raw_value ); - $value = apply_filters( "woocommerce_admin_settings_sanitize_option_" . $setting['id'], $value, $setting, $raw_value ); - do_action( 'woocommerce_update_option', $setting ); - - return $value; - } - /** * Takes a valid request and returns back the corresponding setting array. * @since 2.7.0 @@ -264,114 +95,13 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { $setting = $this->filter_setting( $settings[ $array_key[0] ] ); $setting['value'] = $this->get_value( $setting['id'] ); - if ( ! $this->is_valid_type( $setting['type'] ) ) { + if ( ! $this->is_setting_type_valid( $setting['type'] ) ) { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } return $setting; } - /** - * Takes a valid request and returns back the corresponding group array. - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|array - */ - private function _get_group_from_request( $request ) { - $groups = apply_filters( 'woocommerce_settings_groups', array() ); - if ( empty( $groups ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $index_key = array_keys( wp_list_pluck( $groups, 'id' ), $request['group'] ); - if ( empty( $index_key ) || empty( $groups[ $index_key[0] ] ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $group = wp_parse_args( $groups[ $index_key[0] ], $this->group_defaults() ); - if ( is_null( $group['id'] ) || is_null( $group['label'] ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - // Find sub groups - $sub_groups = array(); - foreach ( $groups as $_group ) { - if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { - $sub_groups[] = $_group['id']; - } - } - - $filtered_group = $this->filter_group( $group ); - $filtered_group['settings'] = array(); - $settings = apply_filters( 'woocommerce_settings-' . $group['id'], array() ); - - if ( ! empty( $settings ) ) { - foreach ( $settings as $setting ) { - $setting = $this->filter_setting( $setting ); - $setting['value'] = $this->get_value( $setting['id'] ); - if ( $this->is_valid_type( $setting['type'] ) ) { - $filtered_group['settings'][] = $setting; - } - } - } - - $filtered_group['sub_groups'] = $sub_groups; - - return $filtered_group; - } - - /** - * Get the groups schema, conforming to JSON Schema. - * @since 2.7.0 - * @return array - */ - public function group_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'settings-group', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'label' => array( - 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'description' => array( - 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'parent_id' => array( - 'description' => __( 'ID of parent grouping.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'sub_groups' => array( - 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - /** * Get the settings schema, conforming to JSON Schema. * @since 2.7.0 @@ -439,140 +169,4 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return $this->add_additional_fields_schema( $schema ); } - /** - * Get a value from WP's settings API. - * @since 2.7.0 - * @param string $setting - * @param string $default - * @return mixed - */ - public function get_value( $setting, $default = '' ) { - if ( strstr( $setting, '[' ) ) { // Array value - parse_str( $setting, $setting_array ); - $setting = current( array_keys( $setting ) ); - $values = get_option( $setting, '' ); - $key = key( $setting_array[ $setting ] ); - if ( isset( $values[ $key ] ) ) { - $value = $values[ $key ]; - } else { - $value = null; - } - } else { // Single value - $value = get_option( $setting, null ); - } - - if ( is_array( $value ) ) { - $value = array_map( 'stripslashes', $value ); - } elseif ( ! is_null( $value ) ) { - $value = stripslashes( $value ); - } - - return $value === null ? $default : $value; - } - - /** - * Filters out bad values from the groups array/filter so we - * only return known values via the API. - * @since 2.7.0 - * @param array $group - * @return array - */ - public function filter_group( $group ) { - return array_intersect_key( - $group, - array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) - ); - } - - /** - * Filters out bad values from the settings array/filter so we - * only return known values via the API. - * @since 2.7.0 - * @param array $setting - * @return array - */ - public function filter_setting( $setting ) { - $setting = array_intersect_key( - $setting, - array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) - ); - - if ( empty( $setting['options'] ) ) { - unset( $setting['options'] ); - } - - return $setting; - } - - /** - * Callback for allowed keys for each group response. - * @since 2.7.0 - * @param string $key Key to check - * @return boolean - */ - public function allowed_group_keys( $key ) { - return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); - } - - /** - * Callback for allowed keys for each setting response. - * @since 2.7.0 - * @param string $key Key to check - * @return boolean - */ - public function allowed_setting_keys( $key ) { - return in_array( $key, array( - 'id', 'label', 'description', 'default', 'tip', - 'placeholder', 'type', 'options', 'value', - ) ); - } - - /** - * Boolean for if a setting type is a valid supported setting type. - * @since 2.7.0 - * @param string $type - * @return boolean - */ - public function is_valid_type( $type ) { - return in_array( $type, array( - 'text', 'email', 'number', 'color', 'password', - 'textarea', 'select', 'multiselect', 'radio', 'checkbox', - 'multi_select_countries', 'image_width', - ) ); - } - - /** - * Returns default settings for groups. null means the field is required. - * @since 2.7.0 - * @return array - */ - protected function group_defaults() { - return array( - 'id' => null, - 'label' => null, - 'description' => '', - 'parent_id' => '', - 'sub_groups' => array(), - ); - } - - /** - * Returns default settings for settings. null means the field is required. - * @since 2.7.0 - * @return array - */ - protected function setting_defaults() { - return array( - 'id' => null, - 'label' => '', - 'type' => null, - 'description' => '', - 'tip' => '', - 'placeholder' => '', - 'default' => '', - 'options' => array(), - 'value' => '', - ); - } - } diff --git a/includes/api/wc-rest-settings-groups-controller.php b/includes/api/wc-rest-settings-groups-controller.php new file mode 100644 index 00000000000..b3840282000 --- /dev/null +++ b/includes/api/wc-rest-settings-groups-controller.php @@ -0,0 +1,257 @@ + endpoints. + * + * @author WooThemes + * @category API + * @package WooCommerce/API + * @version 2.7.0 + * @since 2.7.0 + */ +class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { + + /** + * Register routes. + * @since 2.7.0 + */ + public function register_routes() { + register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_groups' ), + 'permission_callback' => array( $this, 'permissions_check' ), + ), + 'schema' => array( $this, 'group_schema' ), + ) ); + register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_group' ), + 'permission_callback' => array( $this, 'permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_settings' ), + 'permission_callback' => array( $this, 'permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'group_schema' ), + ) ); + } + + /** + * Get all settings groups. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function get_groups( $request ) { + $groups = apply_filters( 'woocommerce_settings_groups', array() ); + if ( empty( $groups ) ) { + return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $defaults = $this->group_defaults(); + $filtered_groups = array(); + foreach ( $groups as $group ) { + $sub_groups = array(); + foreach ( $groups as $_group ) { + if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { + $sub_groups[] = $_group['id']; + } + } + $group['sub_groups'] = $sub_groups; + + $group = wp_parse_args( $group, $defaults ); + if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { + $filtered_groups[] = $this->filter_group( $group ); + } + } + + $response = rest_ensure_response( $filtered_groups ); + return $response; + } + + /** + * Return a single setting group and its settings. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function get_group( $request ) { + $group = $this->_get_group_from_request( $request ); + if ( is_wp_error( $group ) ) { + return $group; + } + return rest_ensure_response( $group ); + } + + /** + * Update a multiple settings at once. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function update_settings( $request ) { + $group = $this->_get_group_from_request( $request ); + if ( is_wp_error( $group ) ) { + return $group; + } + + foreach ( $group['settings'] as $array_key => $setting ) { + if ( isset( $request['values'][ $setting['id'] ] ) ) { + $value = $this->sanitize_setting_value( $setting, $request['values'][ $setting['id'] ] ); + $group['settings'][ $array_key ]['value'] = $value; + update_option( $setting['id'], $value ); + } + } + + return rest_ensure_response( $group ); + } + + /** + * Takes a valid request and returns back the corresponding group array. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|array + */ + private function _get_group_from_request( $request ) { + $groups = apply_filters( 'woocommerce_settings_groups', array() ); + if ( empty( $groups ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $index_key = array_keys( wp_list_pluck( $groups, 'id' ), $request['group'] ); + if ( empty( $index_key ) || empty( $groups[ $index_key[0] ] ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $group = wp_parse_args( $groups[ $index_key[0] ], $this->group_defaults() ); + if ( is_null( $group['id'] ) || is_null( $group['label'] ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Find sub groups + $sub_groups = array(); + foreach ( $groups as $_group ) { + if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { + $sub_groups[] = $_group['id']; + } + } + + $filtered_group = $this->filter_group( $group ); + $filtered_group['settings'] = array(); + $settings = apply_filters( 'woocommerce_settings-' . $group['id'], array() ); + + if ( ! empty( $settings ) ) { + foreach ( $settings as $setting ) { + $setting = $this->filter_setting( $setting ); + $setting['value'] = $this->get_value( $setting['id'] ); + if ( $this->is_setting_type_valid( $setting['type'] ) ) { + $filtered_group['settings'][] = $setting; + } + } + } + + $filtered_group['sub_groups'] = $sub_groups; + + return $filtered_group; + } + + /** + * Get the groups schema, conforming to JSON Schema. + * @since 2.7.0 + * @return array + */ + public function group_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'settings-group', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'label' => array( + 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'description' => array( + 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'parent_id' => array( + 'description' => __( 'ID of parent grouping.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'sub_groups' => array( + 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Filters out bad values from the groups array/filter so we + * only return known values via the API. + * @since 2.7.0 + * @param array $group + * @return array + */ + public function filter_group( $group ) { + return array_intersect_key( + $group, + array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) + ); + } + + /** + * Callback for allowed keys for each group response. + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function allowed_group_keys( $key ) { + return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); + } + + /** + * Returns default settings for groups. null means the field is required. + * @since 2.7.0 + * @return array + */ + protected function group_defaults() { + return array( + 'id' => null, + 'label' => null, + 'description' => '', + 'parent_id' => '', + 'sub_groups' => array(), + ); + } + +} diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 81d21796a86..3292d5624d5 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -163,7 +163,9 @@ class WC_API extends WC_Legacy_API { include_once( 'api/class-wc-rest-report-sales-controller.php' ); include_once( 'api/class-wc-rest-report-top-sellers-controller.php' ); include_once( 'api/class-wc-rest-reports-controller.php' ); + include_once( 'api/wc-rest-settings-base.php' ); include_once( 'api/wc-rest-settings-controller.php' ); + include_once( 'api/wc-rest-settings-groups-controller.php' ); include_once( 'api/class-wc-rest-tax-classes-controller.php' ); include_once( 'api/class-wc-rest-taxes-controller.php' ); include_once( 'api/class-wc-rest-webhook-deliveries.php' ); @@ -193,6 +195,7 @@ class WC_API extends WC_Legacy_API { 'WC_REST_Report_Top_Sellers_Controller', 'WC_REST_Reports_Controller', 'WC_Rest_Settings_Controller', + 'WC_REST_Settings_Groups_Controller', 'WC_REST_Tax_Classes_Controller', 'WC_REST_Taxes_Controller', 'WC_REST_Webhook_Deliveries_Controller', From 2580c3970808b1f0b4a4f254e9e639329a7309ab Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 4 Apr 2016 10:34:14 -0700 Subject: [PATCH 044/298] Rename update_ functions to edit_item, and get_groups/get_settings to get_item and get_items per feedback. Also move the namespace into each class. --- includes/api/wc-rest-settings-controller.php | 15 ++++++++---- .../wc-rest-settings-groups-controller.php | 23 +++++++++++-------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index 2da91e3cbff..25d56e07308 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -15,6 +15,11 @@ if ( ! defined( 'ABSPATH' ) ) { */ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { + /** + * WP REST API namespace/version. + */ + protected $namespace = 'wc/v1'; + /** * Route base. * @var string @@ -26,15 +31,15 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { * @since 2.7.0 */ public function register_routes() { - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_setting' ), + 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'permissions_check' ), ), array( 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_setting' ), + 'callback' => array( $this, 'edit_item' ), 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), @@ -48,7 +53,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function get_setting( $request ) { + public function get_item( $request ) { $setting = $this->_get_setting_from_request( $request ); if ( is_wp_error( $setting ) ) { return $setting; @@ -62,7 +67,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function update_setting( $request ) { + public function edit_item( $request ) { $setting = $this->_get_setting_from_request( $request ); if ( is_wp_error( $setting ) ) { return $setting; diff --git a/includes/api/wc-rest-settings-groups-controller.php b/includes/api/wc-rest-settings-groups-controller.php index b3840282000..e44ba3d33bd 100644 --- a/includes/api/wc-rest-settings-groups-controller.php +++ b/includes/api/wc-rest-settings-groups-controller.php @@ -15,28 +15,33 @@ if ( ! defined( 'ABSPATH' ) ) { */ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { + /** + * WP REST API namespace/version. + */ + protected $namespace = 'wc/v1'; + /** * Register routes. * @since 2.7.0 */ public function register_routes() { - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base, array( + register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_groups' ), + 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'permissions_check' ), ), 'schema' => array( $this, 'group_schema' ), ) ); - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)', array( + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_group' ), + 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'permissions_check' ), ), array( 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_settings' ), + 'callback' => array( $this, 'edit_item' ), 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), @@ -45,12 +50,12 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { } /** - * Get all settings groups. + * Get all settings groups items. * @since 2.7.0 * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function get_groups( $request ) { + public function get_items( $request ) { $groups = apply_filters( 'woocommerce_settings_groups', array() ); if ( empty( $groups ) ) { return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); @@ -83,7 +88,7 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function get_group( $request ) { + public function get_item( $request ) { $group = $this->_get_group_from_request( $request ); if ( is_wp_error( $group ) ) { return $group; @@ -97,7 +102,7 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function update_settings( $request ) { + public function edit_item( $request ) { $group = $this->_get_group_from_request( $request ); if ( is_wp_error( $group ) ) { return $group; From 5cb823f6c6edbefa7a5c9e57ccba8fd59116b7a2 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 4 Apr 2016 12:09:32 -0700 Subject: [PATCH 045/298] edit_item should be update_item --- includes/api/wc-rest-settings-controller.php | 4 ++-- includes/api/wc-rest-settings-groups-controller.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index 25d56e07308..39ea067d0c1 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -39,7 +39,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { ), array( 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'edit_item' ), + 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), @@ -67,7 +67,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function edit_item( $request ) { + public function update_item( $request ) { $setting = $this->_get_setting_from_request( $request ); if ( is_wp_error( $setting ) ) { return $setting; diff --git a/includes/api/wc-rest-settings-groups-controller.php b/includes/api/wc-rest-settings-groups-controller.php index e44ba3d33bd..0ab9a2d4976 100644 --- a/includes/api/wc-rest-settings-groups-controller.php +++ b/includes/api/wc-rest-settings-groups-controller.php @@ -41,7 +41,7 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { ), array( 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'edit_item' ), + 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), @@ -102,7 +102,7 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function edit_item( $request ) { + public function update_item( $request ) { $group = $this->_get_group_from_request( $request ); if ( is_wp_error( $group ) ) { return $group; From cd01e71c3fc9d6033961cb49d969901cad137903 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 6 Jun 2016 14:59:54 -0300 Subject: [PATCH 046/298] Small tweaks to make it follow the REST API standards --- ...stract-wc-rest-settings-api-controller.php | 183 ++++++++++++++++++ ... => class-wc-rest-settings-controller.php} | 31 ++- ...ss-wc-rest-settings-groups-controller.php} | 114 ++++++----- includes/api/wc-rest-settings-base.php | 178 ----------------- includes/class-wc-api.php | 6 +- 5 files changed, 260 insertions(+), 252 deletions(-) create mode 100644 includes/abstracts/abstract-wc-rest-settings-api-controller.php rename includes/api/{wc-rest-settings-controller.php => class-wc-rest-settings-controller.php} (89%) rename includes/api/{wc-rest-settings-groups-controller.php => class-wc-rest-settings-groups-controller.php} (90%) delete mode 100644 includes/api/wc-rest-settings-base.php diff --git a/includes/abstracts/abstract-wc-rest-settings-api-controller.php b/includes/abstracts/abstract-wc-rest-settings-api-controller.php new file mode 100644 index 00000000000..207df4137a6 --- /dev/null +++ b/includes/abstracts/abstract-wc-rest-settings-api-controller.php @@ -0,0 +1,183 @@ + rest_authorization_required_code() ) + ); + } + + return true; + } + + /** + * Cleans a value before setting it. + * + * @since 2.7.0 + * + * @param array $setting WC Setting Array + * @param mixed $raw_value Raw value from PUT request + * @return mixed Sanitized value + */ + public function sanitize_setting_value( $setting, $raw_value ) { + switch ( $setting['type'] ) { + case 'checkbox' : + $default = ( ! empty( $setting['default'] ) ? $setting['default'] : 'no' ); + $value = ( in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : $default ); + break; + case 'email' : + $value = sanitize_email( $raw_value ); + $default = ( ! empty( $setting['default'] ) ? $setting['default'] : '' ); + $value = ( ! empty( $value ) ? $value : $default ); + break; + case 'textarea' : + $value = wp_kses( trim( $raw_value ), + array_merge( + array( + 'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true ) + ), + wp_kses_allowed_html( 'post' ) + ) + ); + break; + case 'multiselect' : + case 'multi_select_countries' : + $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) ); + break; + case 'image_width' : + $value = array(); + if ( isset( $raw_value['width'] ) ) { + $value['width'] = wc_clean( $raw_value['width'] ); + $value['height'] = wc_clean( $raw_value['height'] ); + $value['crop'] = isset( $raw_value['crop'] ) ? 1 : 0; + } else { + $value['width'] = $setting['default']['width']; + $value['height'] = $setting['default']['height']; + $value['crop'] = $setting['default']['crop']; + } + break; + default : + $value = wc_clean( $raw_value ); + break; + } + + // A couple fields changed in the REST API -- we can just pass these too so old filters still work + $setting['desc'] = ( ! empty( $setting['description'] ) ? $setting['description'] : '' ); + $setting['title'] = ( ! empty( $setting['label'] ) ? $setting['label'] : '' ); + + $value = apply_filters( 'woocommerce_admin_settings_sanitize_option', $value, $setting, $raw_value ); + $value = apply_filters( "woocommerce_admin_settings_sanitize_option_" . $setting['id'], $value, $setting, $raw_value ); + do_action( 'woocommerce_update_option', $setting ); + + return $value; + } + + /** + * Get a value from WP's settings API. + * + * @since 2.7.0 + * @param string $setting + * @param string $default + * @return mixed + */ + public function get_value( $setting, $default = '' ) { + if ( strstr( $setting, '[' ) ) { // Array value. + parse_str( $setting, $setting_array ); + $setting = current( array_keys( $setting ) ); + $values = get_option( $setting, '' ); + $key = key( $setting_array[ $setting ] ); + $value = isset( $values[ $key ] ) ? $values[ $key ] : null; + } else { // Single value. + $value = get_option( $setting, null ); + } + + if ( is_array( $value ) ) { + $value = array_map( 'stripslashes', $value ); + } elseif ( ! is_null( $value ) ) { + $value = stripslashes( $value ); + } + + return $value === null ? $default : $value; + } + + /** + * Filters out bad values from the settings array/filter so we + * only return known values via the API. + * + * @since 2.7.0 + * @param array $setting + * @return array + */ + public function filter_setting( $setting ) { + $setting = array_intersect_key( + $setting, + array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) + ); + + if ( empty( $setting['options'] ) ) { + unset( $setting['options'] ); + } + + return $setting; + } + + /** + * Callback for allowed keys for each setting response. + * + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function allowed_setting_keys( $key ) { + return in_array( $key, array( + 'id', 'label', 'description', 'default', 'tip', + 'placeholder', 'type', 'options', 'value', + ) ); + } + + /** + * Boolean for if a setting type is a valid supported setting type. + * + * @since 2.7.0 + * @param string $type + * @return boolean + */ + public function is_setting_type_valid( $type ) { + return in_array( $type, array( + 'text', 'email', 'number', 'color', 'password', + 'textarea', 'select', 'multiselect', 'radio', 'checkbox', + 'multi_select_countries', 'image_width', + ) ); + } +} diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php similarity index 89% rename from includes/api/wc-rest-settings-controller.php rename to includes/api/class-wc-rest-settings-controller.php index 39ea067d0c1..1df6100997e 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -13,19 +13,13 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { +class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { /** * WP REST API namespace/version. */ protected $namespace = 'wc/v1'; - /** - * Route base. - * @var string - */ - protected $rest_base = 'settings'; - /** * Register routes. * @since 2.7.0 @@ -43,7 +37,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), - 'schema' => array( $this, 'setting_schema' ), + 'schema' => array( $this, 'get_public_item_schema' ), ) ); } @@ -54,7 +48,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { * @return WP_Error|WP_REST_Response */ public function get_item( $request ) { - $setting = $this->_get_setting_from_request( $request ); + $setting = $this->prepare_item_for_response( $request ); if ( is_wp_error( $setting ) ) { return $setting; } @@ -68,7 +62,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { * @return WP_Error|WP_REST_Response */ public function update_item( $request ) { - $setting = $this->_get_setting_from_request( $request ); + $setting = $this->prepare_item_for_response( $request ); if ( is_wp_error( $setting ) ) { return $setting; } @@ -80,12 +74,13 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { } /** - * Takes a valid request and returns back the corresponding setting array. - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|array + * Prepare a report sales object for serialization. + * + * @param null $_ + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. */ - private function _get_setting_from_request( $request ) { + public function prepare_item_for_response( $_, $request ) { if ( empty( $request['group'] ) || empty( $request['setting'] ) ) { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } @@ -109,10 +104,11 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { /** * Get the settings schema, conforming to JSON Schema. - * @since 2.7.0 + * + * @since 2.7.0 * @return array */ - public function setting_schema() { + public function get_item_schema() { $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'settings', @@ -173,5 +169,4 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { return $this->add_additional_fields_schema( $schema ); } - } diff --git a/includes/api/wc-rest-settings-groups-controller.php b/includes/api/class-wc-rest-settings-groups-controller.php similarity index 90% rename from includes/api/wc-rest-settings-groups-controller.php rename to includes/api/class-wc-rest-settings-groups-controller.php index 0ab9a2d4976..0cb38048d4a 100644 --- a/includes/api/wc-rest-settings-groups-controller.php +++ b/includes/api/class-wc-rest-settings-groups-controller.php @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { +class WC_Rest_Settings_Groups_Controller extends WC_REST_Settings_API_Controller { /** * WP REST API namespace/version. @@ -31,8 +31,9 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'permissions_check' ), ), - 'schema' => array( $this, 'group_schema' ), + 'schema' => array( $this, 'get_public_item_schema' ), ) ); + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, @@ -45,12 +46,13 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), - 'schema' => array( $this, 'group_schema' ), + 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Get all settings groups items. + * * @since 2.7.0 * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response @@ -84,12 +86,13 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { /** * Return a single setting group and its settings. + * * @since 2.7.0 * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ public function get_item( $request ) { - $group = $this->_get_group_from_request( $request ); + $group = $this->prepare_item_for_response( $request ); if ( is_wp_error( $group ) ) { return $group; } @@ -98,12 +101,13 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { /** * Update a multiple settings at once. + * * @since 2.7.0 * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ public function update_item( $request ) { - $group = $this->_get_group_from_request( $request ); + $group = $this->prepare_item_for_response( $request ); if ( is_wp_error( $group ) ) { return $group; } @@ -120,12 +124,13 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { } /** - * Takes a valid request and returns back the corresponding group array. - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|array + * Prepare a report sales object for serialization. + * + * @param null $_ + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. */ - private function _get_group_from_request( $request ) { + public function prepare_item_for_response( $_, $request ) { $groups = apply_filters( 'woocommerce_settings_groups', array() ); if ( empty( $groups ) ) { return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); @@ -141,7 +146,7 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } - // Find sub groups + // Find sub groups. $sub_groups = array(); foreach ( $groups as $_group ) { if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { @@ -169,11 +174,54 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { } /** - * Get the groups schema, conforming to JSON Schema. + * Filters out bad values from the groups array/filter so we + * only return known values via the API. + * + * @since 2.7.0 + * @param array $group + * @return array + */ + public function filter_group( $group ) { + return array_intersect_key( + $group, + array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) + ); + } + + /** + * Callback for allowed keys for each group response. + * + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function allowed_group_keys( $key ) { + return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); + } + + /** + * Returns default settings for groups. null means the field is required. + * * @since 2.7.0 * @return array */ - public function group_schema() { + protected function group_defaults() { + return array( + 'id' => null, + 'label' => null, + 'description' => '', + 'parent_id' => '', + 'sub_groups' => array(), + ); + } + + /** + * Get the groups schema, conforming to JSON Schema. + * + * @since 2.7.0 + * @return array + */ + public function get_item_schema() { $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'settings-group', @@ -219,44 +267,4 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { return $this->add_additional_fields_schema( $schema ); } - - /** - * Filters out bad values from the groups array/filter so we - * only return known values via the API. - * @since 2.7.0 - * @param array $group - * @return array - */ - public function filter_group( $group ) { - return array_intersect_key( - $group, - array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) - ); - } - - /** - * Callback for allowed keys for each group response. - * @since 2.7.0 - * @param string $key Key to check - * @return boolean - */ - public function allowed_group_keys( $key ) { - return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); - } - - /** - * Returns default settings for groups. null means the field is required. - * @since 2.7.0 - * @return array - */ - protected function group_defaults() { - return array( - 'id' => null, - 'label' => null, - 'description' => '', - 'parent_id' => '', - 'sub_groups' => array(), - ); - } - } diff --git a/includes/api/wc-rest-settings-base.php b/includes/api/wc-rest-settings-base.php deleted file mode 100644 index 753ff0e0e35..00000000000 --- a/includes/api/wc-rest-settings-base.php +++ /dev/null @@ -1,178 +0,0 @@ - rest_authorization_required_code() ) - ); - } - return true; - } - - /** - * Cleans a value before setting it. - * @since 2.7.0 - * @param array $setting WC Setting Array - * @param mixed $raw_value Raw value from PUT request - * @return mixed Sanitized value - */ - public function sanitize_setting_value( $setting, $raw_value ) { - switch ( $setting['type'] ) { - case 'checkbox' : - $default = ( ! empty( $setting['default'] ) ? $setting['default'] : 'no' ); - $value = ( in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : $default ); - break; - case 'email' : - $value = sanitize_email( $raw_value ); - $default = ( ! empty( $setting['default'] ) ? $setting['default'] : '' ); - $value = ( ! empty( $value ) ? $value : $default ); - break; - case 'textarea' : - $value = wp_kses( trim( $raw_value ), - array_merge( - array( - 'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true ) - ), - wp_kses_allowed_html( 'post' ) - ) - ); - break; - case 'multiselect' : - case 'multi_select_countries' : - $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) ); - break; - case 'image_width' : - $value = array(); - if ( isset( $raw_value['width'] ) ) { - $value['width'] = wc_clean( $raw_value['width'] ); - $value['height'] = wc_clean( $raw_value['height'] ); - $value['crop'] = isset( $raw_value['crop'] ) ? 1 : 0; - } else { - $value['width'] = $setting['default']['width']; - $value['height'] = $setting['default']['height']; - $value['crop'] = $setting['default']['crop']; - } - break; - default : - $value = wc_clean( $raw_value ); - break; - } - - // A couple fields changed in the REST API -- we can just pass these too so old filters still work - $setting['desc'] = ( ! empty( $setting['description'] ) ? $setting['description'] : '' ); - $setting['title'] = ( ! empty( $setting['label'] ) ? $setting['label'] : '' ); - - $value = apply_filters( 'woocommerce_admin_settings_sanitize_option', $value, $setting, $raw_value ); - $value = apply_filters( "woocommerce_admin_settings_sanitize_option_" . $setting['id'], $value, $setting, $raw_value ); - do_action( 'woocommerce_update_option', $setting ); - - return $value; - } - - /** - * Get a value from WP's settings API. - * @since 2.7.0 - * @param string $setting - * @param string $default - * @return mixed - */ - public function get_value( $setting, $default = '' ) { - if ( strstr( $setting, '[' ) ) { // Array value - parse_str( $setting, $setting_array ); - $setting = current( array_keys( $setting ) ); - $values = get_option( $setting, '' ); - $key = key( $setting_array[ $setting ] ); - if ( isset( $values[ $key ] ) ) { - $value = $values[ $key ]; - } else { - $value = null; - } - } else { // Single value - $value = get_option( $setting, null ); - } - - if ( is_array( $value ) ) { - $value = array_map( 'stripslashes', $value ); - } elseif ( ! is_null( $value ) ) { - $value = stripslashes( $value ); - } - - return $value === null ? $default : $value; - } - - /** - * Filters out bad values from the settings array/filter so we - * only return known values via the API. - * @since 2.7.0 - * @param array $setting - * @return array - */ - public function filter_setting( $setting ) { - $setting = array_intersect_key( - $setting, - array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) - ); - - if ( empty( $setting['options'] ) ) { - unset( $setting['options'] ); - } - - return $setting; - } - - /** - * Callback for allowed keys for each setting response. - * @since 2.7.0 - * @param string $key Key to check - * @return boolean - */ - public function allowed_setting_keys( $key ) { - return in_array( $key, array( - 'id', 'label', 'description', 'default', 'tip', - 'placeholder', 'type', 'options', 'value', - ) ); - } - - /** - * Boolean for if a setting type is a valid supported setting type. - * @since 2.7.0 - * @param string $type - * @return boolean - */ - public function is_setting_type_valid( $type ) { - return in_array( $type, array( - 'text', 'email', 'number', 'color', 'password', - 'textarea', 'select', 'multiselect', 'radio', 'checkbox', - 'multi_select_countries', 'image_width', - ) ); - } - -} diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 3292d5624d5..eb278b6f92c 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -143,6 +143,7 @@ class WC_API extends WC_Legacy_API { // Abstract controllers. include_once( 'abstracts/abstract-wc-rest-controller.php' ); include_once( 'abstracts/abstract-wc-rest-posts-controller.php' ); + include_once( 'abstracts/abstract-wc-rest-settings-api-controller.php' ); include_once( 'abstracts/abstract-wc-rest-terms-controller.php' ); include_once( 'abstracts/abstract-wc-settings-api.php' ); @@ -163,9 +164,8 @@ class WC_API extends WC_Legacy_API { include_once( 'api/class-wc-rest-report-sales-controller.php' ); include_once( 'api/class-wc-rest-report-top-sellers-controller.php' ); include_once( 'api/class-wc-rest-reports-controller.php' ); - include_once( 'api/wc-rest-settings-base.php' ); - include_once( 'api/wc-rest-settings-controller.php' ); - include_once( 'api/wc-rest-settings-groups-controller.php' ); + include_once( 'api/class-wc-rest-settings-controller.php' ); + include_once( 'api/class-wc-rest-settings-groups-controller.php' ); include_once( 'api/class-wc-rest-tax-classes-controller.php' ); include_once( 'api/class-wc-rest-taxes-controller.php' ); include_once( 'api/class-wc-rest-webhook-deliveries.php' ); From 092bfcb19659120024b1044922f73ca41b7dd002 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 6 Jun 2016 17:00:09 -0600 Subject: [PATCH 047/298] Match parent signature of prepare_item_for_response(), add getter method for settings. --- .../api/class-wc-rest-settings-controller.php | 76 ++++++++++++------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index 1df6100997e..adbca2995a9 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -48,52 +48,38 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { * @return WP_Error|WP_REST_Response */ public function get_item( $request ) { - $setting = $this->prepare_item_for_response( $request ); - if ( is_wp_error( $setting ) ) { - return $setting; - } - return rest_ensure_response( $setting ); - } + $setting = $this->get_setting( $request['group'], $request['setting'] ); - /** - * Update a single setting. - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $setting = $this->prepare_item_for_response( $request ); if ( is_wp_error( $setting ) ) { return $setting; } - $value = $setting['value'] = $this->sanitize_setting_value( $setting, $request['value'] ); - update_option( $setting['id'], $value ); + $response = $this->prepare_item_for_response( $setting, $request ); - return rest_ensure_response( $setting ); + return rest_ensure_response( $response ); } /** - * Prepare a report sales object for serialization. + * Get setting data. * - * @param null $_ - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @param string $group Group ID. + * @param string $setting_id Setting ID. + * + * @return stdClass|WP_Error */ - public function prepare_item_for_response( $_, $request ) { - if ( empty( $request['group'] ) || empty( $request['setting'] ) ) { + public function get_setting( $group, $setting_id ) { + if ( empty( $group ) || empty( $setting_id ) ) { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } - $settings = apply_filters( 'woocommerce_settings-' . $request['group'], array() ); - $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $request['setting'] ); + $settings = apply_filters( 'woocommerce_settings-' . $group, array() ); + $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id ); if ( empty( $array_key ) ) { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } - $setting = $this->filter_setting( $settings[ $array_key[0] ] ); - $setting['value'] = $this->get_value( $setting['id'] ); + $setting = $settings[ $array_key[0] ]; if ( ! $this->is_setting_type_valid( $setting['type'] ) ) { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); @@ -102,6 +88,42 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { return $setting; } + /** + * Update a single setting in a group. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $setting = $this->get_setting( $request['group'], $request['setting'] ); + + if ( is_wp_error( $setting ) ) { + return $setting; + } + + $response = $this->prepare_item_for_response( $setting, $request ); + $value = $this->sanitize_setting_value( $setting, $request['value'] ); + $response['value'] = $value; + + update_option( $setting['id'], $value ); + + return rest_ensure_response( $response ); + } + + /** + * Prepare a single setting object for response. + * + * @param object $item Setting object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + $setting = $this->filter_setting( $item ); + $setting['value'] = $this->get_value( $setting['id'] ); + + return $setting; + } + /** * Get the settings schema, conforming to JSON Schema. * From aff1c82de2e83f1ea2b76cccd26ad6d8c74e7a9b Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 6 Jun 2016 18:50:11 -0600 Subject: [PATCH 048/298] Add Settings controller getter method for all group settings. --- .../api/class-wc-rest-settings-controller.php | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index adbca2995a9..473d84a291f 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -59,20 +59,56 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { return rest_ensure_response( $response ); } + /** + * Get all settings in a group. + * + * @param string $group_id Group ID. + * + * @return array|WP_Error + */ + public function get_group_settings( $group_id ) { + if ( empty( $group_id ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); + + if ( empty( $settings ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $filtered_settings = array(); + + foreach ( $settings as $setting ) { + $setting = $this->filter_setting( $setting ); + if ( $this->is_setting_type_valid( $setting['type'] ) ) { + $setting['value'] = $this->get_value( $setting['id'] ); + $filtered_settings[] = $setting; + } + } + + return $filtered_settings; + } + /** * Get setting data. * - * @param string $group Group ID. + * @param string $group_id Group ID. * @param string $setting_id Setting ID. * * @return stdClass|WP_Error */ - public function get_setting( $group, $setting_id ) { - if ( empty( $group ) || empty( $setting_id ) ) { + public function get_setting( $group_id, $setting_id ) { + if ( empty( $setting_id ) ) { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } - $settings = apply_filters( 'woocommerce_settings-' . $group, array() ); + $settings = $this->get_group_settings( $group_id ); + + if ( is_wp_error( $settings ) ) { + return $settings; + } + $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id ); if ( empty( $array_key ) ) { From 0ddb8e777a21f30b9d81bd73ebe820081b5e40af Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 6 Jun 2016 19:06:02 -0600 Subject: [PATCH 049/298] =?UTF-8?q?Move=20settings=20group=20endpoint=20to?= =?UTF-8?q?=20Settings=20controller=20and=20only=20return=20settings-schem?= =?UTF-8?q?a=E2=80=99d=20items.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/class-wc-rest-settings-controller.php | 25 +++++++++++++++++++ ...ass-wc-rest-settings-groups-controller.php | 5 ---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index 473d84a291f..4eda627fc66 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -25,6 +25,15 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { * @since 2.7.0 */ public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, @@ -59,6 +68,22 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { return rest_ensure_response( $response ); } + /** + * Return all settings in a group. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $settings = $this->get_group_settings( $request['group'] ); + + if ( is_wp_error( $settings ) ) { + return $settings; + } + + return rest_ensure_response( $settings ); + } + /** * Get all settings in a group. * diff --git a/includes/api/class-wc-rest-settings-groups-controller.php b/includes/api/class-wc-rest-settings-groups-controller.php index 0cb38048d4a..9f3f6004adf 100644 --- a/includes/api/class-wc-rest-settings-groups-controller.php +++ b/includes/api/class-wc-rest-settings-groups-controller.php @@ -35,11 +35,6 @@ class WC_Rest_Settings_Groups_Controller extends WC_REST_Settings_API_Controller ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'permissions_check' ), - ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), From c9636bff394699cb0472691d7c5dd45e53d0f807 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 7 Jun 2016 09:22:35 -0600 Subject: [PATCH 050/298] Add _links to /settings/ and /settings// responses. --- .../api/class-wc-rest-settings-controller.php | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index 4eda627fc66..1a2b9449bd2 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -81,7 +81,15 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { return $settings; } - return rest_ensure_response( $settings ); + $data = array(); + + foreach ( $settings as $setting_obj ) { + $setting = $this->prepare_item_for_response( $setting_obj, $request ); + $setting = $this->prepare_response_for_collection( $setting ); + $data[] = $setting; + } + + return rest_ensure_response( $data ); } /** @@ -179,10 +187,39 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { - $setting = $this->filter_setting( $item ); - $setting['value'] = $this->get_value( $setting['id'] ); + $data = $this->filter_setting( $item ); + $data['value'] = $this->get_value( $data['id'] ); - return $setting; + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $data['id'], $request['group'] ) ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param string $setting_id Setting ID. + * @param string $group_id Group ID. + * @return array Links for the given setting. + */ + protected function prepare_links( $setting_id, $group_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $group_id; + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $setting_id ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + ); + + return $links; } /** From 49b1c188c7432c984b1f16a9b21e2e506ab78343 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 7 Jun 2016 16:53:52 -0600 Subject: [PATCH 051/298] Move bulk settings updating to the Settings controller, following existing batch endpoint patterns. --- .../api/class-wc-rest-settings-controller.php | 49 ++++++++++++++++--- ...ass-wc-rest-settings-groups-controller.php | 34 ------------- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index 1a2b9449bd2..91bdec0a962 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -34,7 +34,17 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { 'schema' => array( $this, 'get_public_item_schema' ), ) ); - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), @@ -57,7 +67,7 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { * @return WP_Error|WP_REST_Response */ public function get_item( $request ) { - $setting = $this->get_setting( $request['group'], $request['setting'] ); + $setting = $this->get_setting( $request['group'], $request['id'] ); if ( is_wp_error( $setting ) ) { return $setting; @@ -157,6 +167,32 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { return $setting; } + /** + * Bulk create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * @return array Of WP_Error or WP_REST_Response. + */ + public function batch_items( $request ) { + // Get the request params. + $items = array_filter( $request->get_params() ); + + /* + * Since our batch settings update is group-specific and matches based on the route, + * we inject the URL parameters (containing group) into the batch items + */ + if ( ! empty( $items['update'] ) ) { + $to_update = array(); + foreach ( $items['update'] as $item ) { + $to_update[] = array_merge( $request->get_url_params(), $item ); + } + $request = new WP_REST_Request( $request->get_method() ); + $request->set_body_params( array( 'update' => $to_update ) ); + } + + return parent::batch_items( $request ); + } + /** * Update a single setting in a group. * @since 2.7.0 @@ -164,15 +200,16 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { * @return WP_Error|WP_REST_Response */ public function update_item( $request ) { - $setting = $this->get_setting( $request['group'], $request['setting'] ); + $setting = $this->get_setting( $request['group'], $request['id'] ); if ( is_wp_error( $setting ) ) { return $setting; } - $response = $this->prepare_item_for_response( $setting, $request ); - $value = $this->sanitize_setting_value( $setting, $request['value'] ); - $response['value'] = $value; + $response = $this->prepare_item_for_response( $setting, $request ); + $value = $this->sanitize_setting_value( $setting, $request['value'] ); + + $response->set_data( array_merge( $response->get_data(), compact( 'value' ) ) ); update_option( $setting['id'], $value ); diff --git a/includes/api/class-wc-rest-settings-groups-controller.php b/includes/api/class-wc-rest-settings-groups-controller.php index 9f3f6004adf..310f00b8895 100644 --- a/includes/api/class-wc-rest-settings-groups-controller.php +++ b/includes/api/class-wc-rest-settings-groups-controller.php @@ -33,16 +33,6 @@ class WC_Rest_Settings_Groups_Controller extends WC_REST_Settings_API_Controller ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); } /** @@ -94,30 +84,6 @@ class WC_Rest_Settings_Groups_Controller extends WC_REST_Settings_API_Controller return rest_ensure_response( $group ); } - /** - * Update a multiple settings at once. - * - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $group = $this->prepare_item_for_response( $request ); - if ( is_wp_error( $group ) ) { - return $group; - } - - foreach ( $group['settings'] as $array_key => $setting ) { - if ( isset( $request['values'][ $setting['id'] ] ) ) { - $value = $this->sanitize_setting_value( $setting, $request['values'][ $setting['id'] ] ); - $group['settings'][ $array_key ]['value'] = $value; - update_option( $setting['id'], $value ); - } - } - - return rest_ensure_response( $group ); - } - /** * Prepare a report sales object for serialization. * From 0b940badeb21571b1e9b9506731089cd91c74d3b Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 7 Jun 2016 16:54:28 -0600 Subject: [PATCH 052/298] Handle select options in setting sanitization function. --- .../abstracts/abstract-wc-rest-settings-api-controller.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/includes/abstracts/abstract-wc-rest-settings-api-controller.php b/includes/abstracts/abstract-wc-rest-settings-api-controller.php index 207df4137a6..1d148dd8487 100644 --- a/includes/abstracts/abstract-wc-rest-settings-api-controller.php +++ b/includes/abstracts/abstract-wc-rest-settings-api-controller.php @@ -87,6 +87,11 @@ class WC_REST_Settings_API_Controller extends WC_REST_Controller { $value['crop'] = $setting['default']['crop']; } break; + case 'select': + $options = array_keys( $setting['options'] ); + $default = ( empty( $setting['default'] ) ? $options[0] : $setting['default'] ); + $value = in_array( $raw_value, $options ) ? $raw_value : $default; + break; default : $value = wc_clean( $raw_value ); break; From 7209369eab3bfb7091e9c28de4681786f54bca37 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 8 Jun 2016 10:25:07 -0600 Subject: [PATCH 053/298] =?UTF-8?q?Don=E2=80=99t=20register=20legacy=20set?= =?UTF-8?q?tings=20without=20IDs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/class-wc-register-legacy-settings.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/class-wc-register-legacy-settings.php b/includes/class-wc-register-legacy-settings.php index ba314b0f030..a9d262ac632 100644 --- a/includes/class-wc-register-legacy-settings.php +++ b/includes/class-wc-register-legacy-settings.php @@ -56,6 +56,9 @@ class WC_Register_Legacy_Settings { foreach ( $legacy_sections as $legacy_section => $legacy_section_label ) { $legacy_settings = $this->page->get_settings( $legacy_section ); foreach ( $legacy_settings as $legacy_setting ) { + if ( ! isset( $legacy_setting['id'] ) ) { + continue; + } $new_setting = array( 'id' => $legacy_setting['id'], 'label' => ( ! empty( $legacy_setting['title'] ) ? $legacy_setting['title'] : '' ), From 8939af0d0f40141bcb5e79818e1537ac99dc269c Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 8 Jun 2016 10:34:44 -0600 Subject: [PATCH 054/298] Add _links to returned settings groups. --- ...ass-wc-rest-settings-groups-controller.php | 76 +++++++------------ 1 file changed, 26 insertions(+), 50 deletions(-) diff --git a/includes/api/class-wc-rest-settings-groups-controller.php b/includes/api/class-wc-rest-settings-groups-controller.php index 310f00b8895..1884c028b55 100644 --- a/includes/api/class-wc-rest-settings-groups-controller.php +++ b/includes/api/class-wc-rest-settings-groups-controller.php @@ -61,7 +61,11 @@ class WC_Rest_Settings_Groups_Controller extends WC_REST_Settings_API_Controller $group = wp_parse_args( $group, $defaults ); if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { - $filtered_groups[] = $this->filter_group( $group ); + $group_obj = $this->filter_group( $group ); + $group_data = $this->prepare_item_for_response( $group_obj, $request ); + $group_data = $this->prepare_response_for_collection( $group_data ); + + $filtered_groups[] = $group_data; } } @@ -70,68 +74,40 @@ class WC_Rest_Settings_Groups_Controller extends WC_REST_Settings_API_Controller } /** - * Return a single setting group and its settings. + * Prepare links for the request. * - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|WP_REST_Response + * @param string $group_id Group ID. + * @return array Links for the given group. */ - public function get_item( $request ) { - $group = $this->prepare_item_for_response( $request ); - if ( is_wp_error( $group ) ) { - return $group; - } - return rest_ensure_response( $group ); + protected function prepare_links( $group_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'item' => array( + 'href' => rest_url( trailingslashit( $base ) . $group_id ), + 'embeddable' => true, + ), + ); + + return $links; } /** * Prepare a report sales object for serialization. * - * @param null $_ + * @param array $item Group object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ - public function prepare_item_for_response( $_, $request ) { - $groups = apply_filters( 'woocommerce_settings_groups', array() ); - if ( empty( $groups ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); - } + public function prepare_item_for_response( $item, $request ) { + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); - $index_key = array_keys( wp_list_pluck( $groups, 'id' ), $request['group'] ); - if ( empty( $index_key ) || empty( $groups[ $index_key[0] ] ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); - } + $response = rest_ensure_response( $data ); - $group = wp_parse_args( $groups[ $index_key[0] ], $this->group_defaults() ); - if ( is_null( $group['id'] ) || is_null( $group['label'] ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); - } + $response->add_links( $this->prepare_links( $item['id'] ) ); - // Find sub groups. - $sub_groups = array(); - foreach ( $groups as $_group ) { - if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { - $sub_groups[] = $_group['id']; - } - } - - $filtered_group = $this->filter_group( $group ); - $filtered_group['settings'] = array(); - $settings = apply_filters( 'woocommerce_settings-' . $group['id'], array() ); - - if ( ! empty( $settings ) ) { - foreach ( $settings as $setting ) { - $setting = $this->filter_setting( $setting ); - $setting['value'] = $this->get_value( $setting['id'] ); - if ( $this->is_setting_type_valid( $setting['type'] ) ) { - $filtered_group['settings'][] = $setting; - } - } - } - - $filtered_group['sub_groups'] = $sub_groups; - - return $filtered_group; + return $response; } /** From fde3318b410b088d0aea8244c6ae1efaff451d45 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 8 Jun 2016 13:08:49 -0600 Subject: [PATCH 055/298] Fix unit tests. --- tests/unit-tests/api/settings.php | 153 +++++++++++++++++++----------- 1 file changed, 96 insertions(+), 57 deletions(-) diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index c43943e1634..4cf2ac1104e 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -42,7 +42,7 @@ class Settings extends \WC_Unit_Test_Case { $routes = $this->server->get_routes(); $this->assertArrayHasKey( '/wc/v1/settings', $routes ); $this->assertArrayHasKey( '/wc/v1/settings/(?P[\w-]+)', $routes ); - $this->assertArrayHasKey( '/wc/v1/settings/(?P[\w-]+)/(?P[\w-]+)', $routes ); + $this->assertArrayHasKey( '/wc/v1/settings/(?P[\w-]+)/(?P[\w-]+)', $routes ); } /** @@ -62,7 +62,15 @@ class Settings extends \WC_Unit_Test_Case { 'label' => 'Test Extension', 'parent_id' => '', 'description' => 'My awesome test settings.', - 'sub_groups' => array( 'sub-test' ), + 'sub_groups' => array( 'sub-test' ), + '_links' => array( + 'item' => array( + array( + 'href' => rest_url( '/wc/v1/settings/test' ), + 'embeddable' => true, + ), + ), + ), ), $data ); $this->assertContains( array( @@ -71,6 +79,14 @@ class Settings extends \WC_Unit_Test_Case { 'parent_id' => 'test', 'description' => '', 'sub_groups' => array(), + '_links' => array( + 'item' => array( + array( + 'href' => rest_url( '/wc/v1/settings/sub-test' ), + 'embeddable' => true, + ), + ), + ), ), $data ); } @@ -140,29 +156,39 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 404, $response->get_status() ); // test getting a valid group - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/coupon-data' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/general' ) ); $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); - - $this->check_get_group_response( $data, array( - 'id' => 'coupon-data', - 'label' => 'Coupon Data', - 'parent_id' => '', - 'description' => '', - ) ); - - $this->assertEmpty( $data['sub_groups'] ); + $this->assertContains( array( + 'id' => 'woocommerce_demo_store', + 'label' => 'Store Notice', + 'description' => 'Enable site-wide store notice text', + 'type' => 'checkbox', + 'default' => 'no', + 'value' => 'no', + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v1/settings/general/woocommerce_demo_store' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v1/settings/general' ), + ), + ), + ) + ), $data ); // test getting a valid group with settings attached to it $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); $data = $response->get_data(); - $this->assertEquals( 2, count( $data['settings'] ) ); - $this->assertEquals( 'woocommerce_shop_page_display', $data['settings'][0]['id'] ); - $this->assertEmpty( $data['settings'][0]['value'] ); - $this->assertEquals( 'woocommerce_enable_lightbox', $data['settings'][1]['id'] ); - $this->assertEquals( 'yes', $data['settings'][1]['value'] ); - $this->assertEquals( array( 'sub-test' ), $data['sub_groups'] ); + $this->assertEquals( 2, count( $data ) ); + $this->assertEquals( 'woocommerce_shop_page_display', $data[0]['id'] ); + $this->assertEmpty( $data[0]['value'] ); + $this->assertEquals( 'woocommerce_enable_lightbox', $data[1]['id'] ); + $this->assertEquals( 'yes', $data[1]['value'] ); } /** @@ -255,36 +281,48 @@ class Settings extends \WC_Unit_Test_Case { // test defaults first $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); $data = $response->get_data(); - $this->assertEquals( '', $data['settings'][0]['value'] ); - $this->assertEquals( 'yes', $data['settings'][1]['value'] ); + $this->assertEquals( '', $data[0]['value'] ); + $this->assertEquals( 'yes', $data[1]['value'] ); // test setting both at once - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s', 'test' ) ); + $request = new \WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); $request->set_body_params( array( - 'values' => array( - 'woocommerce_shop_page_display' => 'both', - 'woocommerce_enable_lightbox' => 'no', + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'both', + ), + array( + 'id' => 'woocommerce_enable_lightbox', + 'value' => 'no', + ), ), ) ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); - $this->assertEquals( 'both', $data['settings'][0]['value'] ); + $this->assertEquals( 'both', $data['update'][0]['value'] ); $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); - $this->assertEquals( 'no', $data['settings'][1]['value'] ); + $this->assertEquals( 'no', $data['update'][1]['value'] ); $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); // test updating one, but making sure the other value stays the same - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s', 'test' ) ); + $request = new \WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); $request->set_body_params( array( - 'values' => array( - 'woocommerce_shop_page_display' => 'subcategories', + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'subcategories', + ), ), ) ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); - $this->assertEquals( 'subcategories', $data['settings'][0]['value'] ); - $this->assertEquals( 'no', $data['settings'][1]['value'] ); + $this->assertEquals( 'subcategories', $data['update'][0]['value'] ); $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); + + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); + $data = $response->get_data(); + $this->assertEquals( 'no', $data[1]['value'] ); $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); } @@ -354,10 +392,13 @@ class Settings extends \WC_Unit_Test_Case { public function test_update_settings_without_permission() { wp_set_current_user( 0 ); - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s', 'test' ) ); + $request = new \WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); $request->set_body_params( array( - 'values' => array( - 'woocommerce_shop_page_display' => 'subcategories', + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'subcategories', + ), ), ) ); $response = $this->server->dispatch( $request ); @@ -411,7 +452,7 @@ class Settings extends \WC_Unit_Test_Case { } /** - * Tests our classic setting registeration to make sure settings added for WP-Admin are available over the API. + * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API. * @since 2.7.0 */ public function test_classic_settings() { @@ -420,17 +461,28 @@ class Settings extends \WC_Unit_Test_Case { // Make sure the group is properly registered $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/products' ) ); $data = $response->get_data(); - - $this->assertEquals( 'products', $data['id'] ); + $this->assertTrue( is_array( $data ) ); $this->assertContains( array( - 'id' => 'woocommerce_downloads_require_login', - 'label' => 'Access Restriction', + 'id' => 'woocommerce_downloads_require_login', + 'label' => 'Access Restriction', 'description' => 'Downloads require login', - 'type' => 'checkbox', - 'default' => 'no', - 'tip' => 'This setting does not apply to guest purchases.', - 'value' => 'no', - ), $data['settings'] ); + 'type' => 'checkbox', + 'default' => 'no', + 'tip' => 'This setting does not apply to guest purchases.', + 'value' => 'no', + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v1/settings/products/woocommerce_downloads_require_login' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v1/settings/products' ), + ), + ), + ), + ), $data ); // test get single $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/products/woocommerce_dimension_unit' ) ); @@ -450,17 +502,4 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 'yd', get_option(' woocommerce_dimension_unit' ) ); } - /** - * Ensure valid group data response. - * @since 2.7.0 - * @param array $response - * @param array $expected - */ - protected function check_get_group_response( $response, $expected ) { - $this->assertEquals( $expected['id'], $response['id'] ); - $this->assertEquals( $expected['parent_id'], $response['parent_id'] ); - $this->assertEquals( $expected['label'], $response['label'] ); - $this->assertEquals( $expected['description'], $response['description'] ); - } - } From a53040f1868c0fc897e91bc266c90c6fa1bd16b7 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 8 Jun 2016 15:01:30 -0600 Subject: [PATCH 056/298] Remove namespace from Settings API unit test file. This fails builds on PHP 5.2.x. --- tests/unit-tests/api/settings.php | 69 +++++++++++++++---------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 4cf2ac1104e..390d80c161a 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -1,12 +1,11 @@ server = $wp_rest_server = new \WP_Test_Spy_REST_Server; + $this->server = $wp_rest_server = new WP_Test_Spy_REST_Server; do_action( 'rest_api_init' ); - $this->endpoint = new \WC_Rest_Settings_Controller(); - \WC_Helper_Settings::register(); + $this->endpoint = new WC_Rest_Settings_Controller(); + WC_Helper_Settings::register(); $this->user = $this->factory->user->create( array( 'role' => 'administrator', ) ); @@ -52,7 +51,7 @@ class Settings extends \WC_Unit_Test_Case { public function test_get_groups() { wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings' ) ); $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); @@ -97,7 +96,7 @@ class Settings extends \WC_Unit_Test_Case { public function test_get_groups_without_permission() { wp_set_current_user( 0 ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -106,7 +105,7 @@ class Settings extends \WC_Unit_Test_Case { * @since 2.7.0 */ public function test_get_group_schema() { - $request = new \WP_REST_Request( 'OPTIONS', '/wc/v1/settings' ); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v1/settings' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; @@ -123,7 +122,7 @@ class Settings extends \WC_Unit_Test_Case { * @since 2.7.0 */ public function test_get_setting_schema() { - $request = new \WP_REST_Request( 'OPTIONS', '/wc/v1/settings/test/woocommerce_shop_page_display' ); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v1/settings/test/woocommerce_shop_page_display' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; @@ -146,17 +145,17 @@ class Settings extends \WC_Unit_Test_Case { wp_set_current_user( $this->user ); // test getting a group that does not exist - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/not-real' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/not-real' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting the 'invalid' group - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/invalid' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/invalid' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting a valid group - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/general' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/general' ) ); $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); @@ -182,7 +181,7 @@ class Settings extends \WC_Unit_Test_Case { ), $data ); // test getting a valid group with settings attached to it - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); $data = $response->get_data(); $this->assertEquals( 2, count( $data ) ); $this->assertEquals( 'woocommerce_shop_page_display', $data[0]['id'] ); @@ -198,7 +197,7 @@ class Settings extends \WC_Unit_Test_Case { public function test_get_group_without_permission() { wp_set_current_user( 0 ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/coupon-data' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/coupon-data' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -210,16 +209,16 @@ class Settings extends \WC_Unit_Test_Case { wp_set_current_user( $this->user ); // test defaults first - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_shop_page_display' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_shop_page_display' ) ); $data = $response->get_data(); $this->assertEquals( '', $data['value'] ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); $data = $response->get_data(); $this->assertEquals( 'yes', $data['value'] ); // test updating shop display setting - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); $request->set_body_params( array( 'value' => 'both', ) ); @@ -229,7 +228,7 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 'both', $data['value'] ); $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); $request->set_body_params( array( 'value' => 'subcategories', ) ); @@ -239,7 +238,7 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 'subcategories', $data['value'] ); $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); $request->set_body_params( array( 'value' => '', ) ); @@ -250,7 +249,7 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( '', get_option( 'woocommerce_shop_page_display' ) ); // test updating ligtbox - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); $request->set_body_params( array( 'value' => 'no', ) ); @@ -260,7 +259,7 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 'no', $data['value'] ); $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); $request->set_body_params( array( 'value' => 'yes', ) ); @@ -279,13 +278,13 @@ class Settings extends \WC_Unit_Test_Case { wp_set_current_user( $this->user ); // test defaults first - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); $data = $response->get_data(); $this->assertEquals( '', $data[0]['value'] ); $this->assertEquals( 'yes', $data[1]['value'] ); // test setting both at once - $request = new \WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); + $request = new WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); $request->set_body_params( array( 'update' => array( array( @@ -306,7 +305,7 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); // test updating one, but making sure the other value stays the same - $request = new \WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); + $request = new WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); $request->set_body_params( array( 'update' => array( array( @@ -320,7 +319,7 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 'subcategories', $data['update'][0]['value'] ); $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); $data = $response->get_data(); $this->assertEquals( 'no', $data[1]['value'] ); $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); @@ -334,17 +333,17 @@ class Settings extends \WC_Unit_Test_Case { wp_set_current_user( $this->user ); // test getting an invalid setting from a group that does not exist - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/not-real/woocommerce_enable_lightbox' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/not-real/woocommerce_enable_lightbox' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting an invalid setting from a group that does exist - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/invalid/invalid' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/invalid/invalid' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting a valid setting - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); @@ -364,7 +363,7 @@ class Settings extends \WC_Unit_Test_Case { public function test_get_setting_without_permission() { wp_set_current_user( 0 ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -376,7 +375,7 @@ class Settings extends \WC_Unit_Test_Case { public function test_update_setting_without_permission() { wp_set_current_user( 0 ); - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); $request->set_body_params( array( 'value' => 'yes', ) ); @@ -392,7 +391,7 @@ class Settings extends \WC_Unit_Test_Case { public function test_update_settings_without_permission() { wp_set_current_user( 0 ); - $request = new \WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); + $request = new WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); $request->set_body_params( array( 'update' => array( array( @@ -410,7 +409,7 @@ class Settings extends \WC_Unit_Test_Case { * @since 2.7.0 */ public function test_sanitize_setting() { - $endpoint = new \WC_Rest_Settings_Controller; + $endpoint = new WC_Rest_Settings_Controller; // checkbox $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'checkbox', 'default' => 'yes' ), 'no' ); @@ -459,7 +458,7 @@ class Settings extends \WC_Unit_Test_Case { wp_set_current_user( $this->user ); // Make sure the group is properly registered - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/products' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/products' ) ); $data = $response->get_data(); $this->assertTrue( is_array( $data ) ); $this->assertContains( array( @@ -485,13 +484,13 @@ class Settings extends \WC_Unit_Test_Case { ), $data ); // test get single - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/products/woocommerce_dimension_unit' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/products/woocommerce_dimension_unit' ) ); $data = $response->get_data(); $this->assertEquals( 'cm', $data['default'] ); // test update - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) ); $request->set_body_params( array( 'value' => 'yd', ) ); From 586bf5d842dd53e42026bdcf459f182521fc0a4e Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 08:47:09 -0600 Subject: [PATCH 057/298] Take in options data to be saved as an optional argument, defaulting to $_POST. This allows for reuse of the options field saving mechanism. --- includes/admin/class-wc-admin-settings.php | 14 +++++++++----- includes/admin/wc-admin-functions.php | 5 +++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/includes/admin/class-wc-admin-settings.php b/includes/admin/class-wc-admin-settings.php index 4df6c3fec05..b4d42d8ddb3 100644 --- a/includes/admin/class-wc-admin-settings.php +++ b/includes/admin/class-wc-admin-settings.php @@ -662,10 +662,14 @@ class WC_Admin_Settings { * Loops though the woocommerce options array and outputs each field. * * @param array $options Options array to output + * @param array $data Optional. Data to use for saving. Defaults to $_POST. * @return bool */ - public static function save_fields( $options ) { - if ( empty( $_POST ) ) { + public static function save_fields( $options, $data = null ) { + if ( is_null( $data ) ) { + $data = $_POST; + } + if ( empty( $data ) ) { return false; } @@ -683,17 +687,17 @@ class WC_Admin_Settings { parse_str( $option['id'], $option_name_array ); $option_name = current( array_keys( $option_name_array ) ); $setting_name = key( $option_name_array[ $option_name ] ); - $raw_value = isset( $_POST[ $option_name ][ $setting_name ] ) ? wp_unslash( $_POST[ $option_name ][ $setting_name ] ) : null; + $raw_value = isset( $data[ $option_name ][ $setting_name ] ) ? wp_unslash( $data[ $option_name ][ $setting_name ] ) : null; } else { $option_name = $option['id']; $setting_name = ''; - $raw_value = isset( $_POST[ $option['id'] ] ) ? wp_unslash( $_POST[ $option['id'] ] ) : null; + $raw_value = isset( $data[ $option['id'] ] ) ? wp_unslash( $data[ $option['id'] ] ) : null; } // Format the value based on option type. switch ( $option['type'] ) { case 'checkbox' : - $value = is_null( $raw_value ) ? 'no' : 'yes'; + $value = in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : 'no'; break; case 'textarea' : $value = wp_kses_post( trim( $raw_value ) ); diff --git a/includes/admin/wc-admin-functions.php b/includes/admin/wc-admin-functions.php index 968254b9175..9ec801cd7bc 100644 --- a/includes/admin/wc-admin-functions.php +++ b/includes/admin/wc-admin-functions.php @@ -145,14 +145,15 @@ function woocommerce_admin_fields( $options ) { * Update all settings which are passed. * * @param array $options + * @param array $data */ -function woocommerce_update_options( $options ) { +function woocommerce_update_options( $options, $data = null ) { if ( ! class_exists( 'WC_Admin_Settings' ) ) { include 'class-wc-admin-settings.php'; } - WC_Admin_Settings::save_fields( $options ); + WC_Admin_Settings::save_fields( $options, $data ); } /** From 832df9ab3eead54bac8f0d6fe6edb31fa387f32b Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 08:48:17 -0600 Subject: [PATCH 058/298] =?UTF-8?q?Use=20WC=20Admin=20Settings=E2=80=99s?= =?UTF-8?q?=20get=5Foption()=20in=20REST=20Settings=20controller=20instead?= =?UTF-8?q?=20of=20duplicating=20code.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...stract-wc-rest-settings-api-controller.php | 28 ------------------- .../api/class-wc-rest-settings-controller.php | 4 +-- 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/includes/abstracts/abstract-wc-rest-settings-api-controller.php b/includes/abstracts/abstract-wc-rest-settings-api-controller.php index 1d148dd8487..c13dfe1268a 100644 --- a/includes/abstracts/abstract-wc-rest-settings-api-controller.php +++ b/includes/abstracts/abstract-wc-rest-settings-api-controller.php @@ -108,34 +108,6 @@ class WC_REST_Settings_API_Controller extends WC_REST_Controller { return $value; } - /** - * Get a value from WP's settings API. - * - * @since 2.7.0 - * @param string $setting - * @param string $default - * @return mixed - */ - public function get_value( $setting, $default = '' ) { - if ( strstr( $setting, '[' ) ) { // Array value. - parse_str( $setting, $setting_array ); - $setting = current( array_keys( $setting ) ); - $values = get_option( $setting, '' ); - $key = key( $setting_array[ $setting ] ); - $value = isset( $values[ $key ] ) ? $values[ $key ] : null; - } else { // Single value. - $value = get_option( $setting, null ); - } - - if ( is_array( $value ) ) { - $value = array_map( 'stripslashes', $value ); - } elseif ( ! is_null( $value ) ) { - $value = stripslashes( $value ); - } - - return $value === null ? $default : $value; - } - /** * Filters out bad values from the settings array/filter so we * only return known values via the API. diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index 91bdec0a962..e69cf82501d 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -125,7 +125,7 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { foreach ( $settings as $setting ) { $setting = $this->filter_setting( $setting ); if ( $this->is_setting_type_valid( $setting['type'] ) ) { - $setting['value'] = $this->get_value( $setting['id'] ); + $setting['value'] = WC_Admin_Settings::get_option( $setting['id'] ); $filtered_settings[] = $setting; } } @@ -225,7 +225,7 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { */ public function prepare_item_for_response( $item, $request ) { $data = $this->filter_setting( $item ); - $data['value'] = $this->get_value( $data['id'] ); + $data['value'] = WC_Admin_Settings::get_option( $data['id'] ); $context = empty( $request['context'] ) ? 'view' : $request['context']; $data = $this->add_additional_fields_to_object( $data, $request ); From 1cde74312113c838b774b91ca448e096f4411ba0 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 09:16:30 -0600 Subject: [PATCH 059/298] =?UTF-8?q?Reuse=20WC=20Admin=20Setting=E2=80=99s?= =?UTF-8?q?=20save=5Ffields()=20instead=20of=20duplicating=20code=20for=20?= =?UTF-8?q?sanitizing=20saved=20values.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...stract-wc-rest-settings-api-controller.php | 67 ------------------- .../api/class-wc-rest-settings-controller.php | 10 +-- tests/unit-tests/api/settings.php | 46 ------------- 3 files changed, 5 insertions(+), 118 deletions(-) diff --git a/includes/abstracts/abstract-wc-rest-settings-api-controller.php b/includes/abstracts/abstract-wc-rest-settings-api-controller.php index c13dfe1268a..8d6cd5823b3 100644 --- a/includes/abstracts/abstract-wc-rest-settings-api-controller.php +++ b/includes/abstracts/abstract-wc-rest-settings-api-controller.php @@ -41,73 +41,6 @@ class WC_REST_Settings_API_Controller extends WC_REST_Controller { return true; } - /** - * Cleans a value before setting it. - * - * @since 2.7.0 - * - * @param array $setting WC Setting Array - * @param mixed $raw_value Raw value from PUT request - * @return mixed Sanitized value - */ - public function sanitize_setting_value( $setting, $raw_value ) { - switch ( $setting['type'] ) { - case 'checkbox' : - $default = ( ! empty( $setting['default'] ) ? $setting['default'] : 'no' ); - $value = ( in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : $default ); - break; - case 'email' : - $value = sanitize_email( $raw_value ); - $default = ( ! empty( $setting['default'] ) ? $setting['default'] : '' ); - $value = ( ! empty( $value ) ? $value : $default ); - break; - case 'textarea' : - $value = wp_kses( trim( $raw_value ), - array_merge( - array( - 'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true ) - ), - wp_kses_allowed_html( 'post' ) - ) - ); - break; - case 'multiselect' : - case 'multi_select_countries' : - $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) ); - break; - case 'image_width' : - $value = array(); - if ( isset( $raw_value['width'] ) ) { - $value['width'] = wc_clean( $raw_value['width'] ); - $value['height'] = wc_clean( $raw_value['height'] ); - $value['crop'] = isset( $raw_value['crop'] ) ? 1 : 0; - } else { - $value['width'] = $setting['default']['width']; - $value['height'] = $setting['default']['height']; - $value['crop'] = $setting['default']['crop']; - } - break; - case 'select': - $options = array_keys( $setting['options'] ); - $default = ( empty( $setting['default'] ) ? $options[0] : $setting['default'] ); - $value = in_array( $raw_value, $options ) ? $raw_value : $default; - break; - default : - $value = wc_clean( $raw_value ); - break; - } - - // A couple fields changed in the REST API -- we can just pass these too so old filters still work - $setting['desc'] = ( ! empty( $setting['description'] ) ? $setting['description'] : '' ); - $setting['title'] = ( ! empty( $setting['label'] ) ? $setting['label'] : '' ); - - $value = apply_filters( 'woocommerce_admin_settings_sanitize_option', $value, $setting, $raw_value ); - $value = apply_filters( "woocommerce_admin_settings_sanitize_option_" . $setting['id'], $value, $setting, $raw_value ); - do_action( 'woocommerce_update_option', $setting ); - - return $value; - } - /** * Filters out bad values from the settings array/filter so we * only return known values via the API. diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index e69cf82501d..f591a77cec5 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -206,12 +206,12 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { return $setting; } + $update_data = array(); + $update_data[ $setting['id'] ] = $request['value']; + + WC_Admin_Settings::save_fields( array( $setting ), $update_data ); + $response = $this->prepare_item_for_response( $setting, $request ); - $value = $this->sanitize_setting_value( $setting, $request['value'] ); - - $response->set_data( array_merge( $response->get_data(), compact( 'value' ) ) ); - - update_option( $setting['id'], $value ); return rest_ensure_response( $response ); } diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 390d80c161a..39894569962 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -404,52 +404,6 @@ class Settings extends WC_Unit_Test_Case { $this->assertEquals( 401, $response->get_status() ); } - /** - * Makes sure our sanitize function runs correctly for different types. - * @since 2.7.0 - */ - public function test_sanitize_setting() { - $endpoint = new WC_Rest_Settings_Controller; - - // checkbox - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'checkbox', 'default' => 'yes' ), 'no' ); - $this->assertEquals( 'no', $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'checkbox', 'default' => 'yes' ), 'yes' ); - $this->assertEquals( 'yes', $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'checkbox', 'default' => 'yes' ), 'invalid' ); - $this->assertEquals( 'yes', $value ); - - // email - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email' ), 'test@woo.local' ); - $this->assertEquals( 'test@woo.local', $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email' ), ' admin@woo.local! ' ); - $this->assertEquals( 'admin@woo.local', $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email' ), 'blah' ); - $this->assertEquals( '', $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email', 'default' => 'woo@woo.local' ), 'blah' ); - $this->assertEquals( 'woo@woo.local', $value ); - - // textarea - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'textarea' ), ' blah' ); - $this->assertEquals( 'blah', $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'textarea' ), 'blah' ); - $this->assertEquals( 'blah', $value ); - - // multiselect / multiselect countries - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'multiselect' ), array( 'test', 'assertEquals( array( 'test', '<test' ), $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'multi_select_countries' ), array( 'test', 'assertEquals( array( 'test', '<test' ), $value ); - - // image_width - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'image_width' ), array( 'width' => ' 100%', 'height' => '25px ' ) ); - $this->assertEquals( array( 'width' => '100%', 'height' => '25px', 'crop' => 0 ), $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'image_width' ), array( 'width' => '100%', 'height' => '25px', 'crop' => 'something' ) ); - $this->assertEquals( array( 'width' => '100%', 'height' => '25px', 'crop' => 1 ), $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'image_width', 'default' => array( 'width' => '50px', 'height' => '50px', 'crop' => true ) ), array() ); - $this->assertEquals( array( 'width' => '50px', 'height' => '50px', 'crop' => 1 ), $value ); - } - /** * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API. * @since 2.7.0 From 3747505d837914f9c21b21e7397346a5f02ac6c8 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 10:09:31 -0600 Subject: [PATCH 060/298] Add initial test file for WC_Register_Legacy_Settings, with test for constructor. --- .../settings/register-legacy-settings.php | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/unit-tests/settings/register-legacy-settings.php diff --git a/tests/unit-tests/settings/register-legacy-settings.php b/tests/unit-tests/settings/register-legacy-settings.php new file mode 100644 index 00000000000..fb8801a7438 --- /dev/null +++ b/tests/unit-tests/settings/register-legacy-settings.php @@ -0,0 +1,32 @@ +page = new WC_Settings_General(); + } + + public function test_constructor() { + + $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); + + $this->assertEquals( has_filter( 'woocommerce_settings_groups', array( $legacy_settings, 'register_legacy_group' ) ), 10 ); + $this->assertEquals( has_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $legacy_settings, 'register_legacy_settings' ) ), 10 ); + } + +} \ No newline at end of file From 6c53cfa16796c8f3990543f3847442719e6d3998 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 10:38:30 -0600 Subject: [PATCH 061/298] Add test for register_legacy_group() and coverage annotations. --- .../settings/register-legacy-settings.php | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/unit-tests/settings/register-legacy-settings.php b/tests/unit-tests/settings/register-legacy-settings.php index fb8801a7438..876ba9b1fc2 100644 --- a/tests/unit-tests/settings/register-legacy-settings.php +++ b/tests/unit-tests/settings/register-legacy-settings.php @@ -21,12 +21,37 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { $this->page = new WC_Settings_General(); } + /** + * @covers WC_Register_Legacy_Settings::__construct + */ public function test_constructor() { - $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); $this->assertEquals( has_filter( 'woocommerce_settings_groups', array( $legacy_settings, 'register_legacy_group' ) ), 10 ); $this->assertEquals( has_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $legacy_settings, 'register_legacy_settings' ) ), 10 ); } + /** + * @covers WC_Register_Legacy_Settings::register_legacy_group + */ + public function test_register_legacy_group() { + $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); + + $existing = array( + 'id' => 'existing-id', + 'label' => 'Existing Group', + ); + $initial = array( $existing ); + $expected = array( + $existing, + array( + 'id' => $this->page->get_id(), + 'label' => $this->page->get_label(), + ), + ); + $actual = $legacy_settings->register_legacy_group( $initial ); + + $this->assertEquals( $expected, $actual ); + } + } \ No newline at end of file From 1fc539992c36daba025bc86a3b5e46ae1105376a Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 11:37:35 -0600 Subject: [PATCH 062/298] =?UTF-8?q?Break=20=E2=80=9Clegacy=E2=80=9D=20sett?= =?UTF-8?q?ing=20to=20=E2=80=9Cnew=E2=80=9D=20conversion=20into=20it?= =?UTF-8?q?=E2=80=99s=20own=20method.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../class-wc-register-legacy-settings.php | 60 ++++++++----- .../settings/register-legacy-settings.php | 90 +++++++++++++++++++ 2 files changed, 128 insertions(+), 22 deletions(-) diff --git a/includes/class-wc-register-legacy-settings.php b/includes/class-wc-register-legacy-settings.php index a9d262ac632..76318fd428b 100644 --- a/includes/class-wc-register-legacy-settings.php +++ b/includes/class-wc-register-legacy-settings.php @@ -56,33 +56,49 @@ class WC_Register_Legacy_Settings { foreach ( $legacy_sections as $legacy_section => $legacy_section_label ) { $legacy_settings = $this->page->get_settings( $legacy_section ); foreach ( $legacy_settings as $legacy_setting ) { - if ( ! isset( $legacy_setting['id'] ) ) { - continue; + $new_setting = $this->new_setting_from_legacy( $legacy_setting ); + if ( $new_setting ) { + $settings[] = $new_setting; } - $new_setting = array( - 'id' => $legacy_setting['id'], - 'label' => ( ! empty( $legacy_setting['title'] ) ? $legacy_setting['title'] : '' ), - 'description' => ( ! empty( $legacy_setting['desc'] ) ? $legacy_setting['desc'] : '' ), - 'type' => $legacy_setting['type'], - ); - if ( isset( $legacy_setting['default'] ) ) { - $new_setting['default'] = $legacy_setting['default']; - } - if ( isset( $legacy_setting['options'] ) ) { - $new_setting['options'] = $legacy_setting['options']; - } - if ( isset( $legacy_setting['desc_tip'] ) ) { - if ( true === $legacy_setting['desc_tip'] ) { - $new_setting['tip'] = $legacy_setting['desc']; - } else if ( ! empty( $legacy_setting['desc_tip'] ) ) { - $new_setting['tip'] = $legacy_setting['desc_tip']; - } - } - $settings[] = $new_setting; } } return $settings; } + + /** + * Convert a "legacy" setting (WC_Settings_Page::get_settings()) into the format expected + * for the REST API Settings Controller + * + * @param $legacy_setting Settings array, as produced by a subclass of WC_Settings_Page. + * + * @return array|bool Boolean false if legacy setting has no ID, Array of converted new setting otherwise. + */ + public function new_setting_from_legacy( $legacy_setting ) { + if ( ! isset( $legacy_setting['id'] ) ) { + return false; + } + $new_setting = array( + 'id' => $legacy_setting['id'], + 'label' => ( ! empty( $legacy_setting['title'] ) ? $legacy_setting['title'] : '' ), + 'description' => ( ! empty( $legacy_setting['desc'] ) ? $legacy_setting['desc'] : '' ), + 'type' => $legacy_setting['type'], + ); + if ( isset( $legacy_setting['default'] ) ) { + $new_setting['default'] = $legacy_setting['default']; + } + if ( isset( $legacy_setting['options'] ) ) { + $new_setting['options'] = $legacy_setting['options']; + } + if ( isset( $legacy_setting['desc_tip'] ) ) { + if ( true === $legacy_setting['desc_tip'] ) { + $new_setting['tip'] = $legacy_setting['desc']; + } else if ( ! empty( $legacy_setting['desc_tip'] ) ) { + $new_setting['tip'] = $legacy_setting['desc_tip']; + } + } + + return $new_setting; + } } /** diff --git a/tests/unit-tests/settings/register-legacy-settings.php b/tests/unit-tests/settings/register-legacy-settings.php index 876ba9b1fc2..7bad6e41b59 100644 --- a/tests/unit-tests/settings/register-legacy-settings.php +++ b/tests/unit-tests/settings/register-legacy-settings.php @@ -54,4 +54,94 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { $this->assertEquals( $expected, $actual ); } + public function new_setting_from_legacy_provider() { + return array( + // No "id" case + array( + array( + 'type' => 'some-type-with-no-id', + ), + false, + ), + // All optional properties except 'desc_tip' + array( + array( + 'id' => 'setting-id', + 'type' => 'select', + 'title' => 'Setting Name', + 'desc' => 'Setting Description', + 'default' => 'one', + 'options' => array( 'one', 'two' ), + ), + array( + 'id' => 'setting-id', + 'type' => 'select', + 'label' => 'Setting Name', + 'description' => 'Setting Description', + 'default' => 'one', + 'options' => array( 'one', 'two' ), + ), + ), + // Boolean 'desc_tip' defaulting to 'desc' value + array( + array( + 'id' => 'setting-id', + 'type' => 'select', + 'title' => 'Setting Name', + 'desc' => 'Setting Description', + 'desc_tip' => true, + ), + array( + 'id' => 'setting-id', + 'type' => 'select', + 'label' => 'Setting Name', + 'description' => 'Setting Description', + 'tip' => 'Setting Description', + ), + ), + // String 'desc_tip' + array( + array( + 'id' => 'setting-id', + 'type' => 'select', + 'title' => 'Setting Name', + 'desc' => 'Setting Description', + 'desc_tip' => 'Setting Tip', + ), + array( + 'id' => 'setting-id', + 'type' => 'select', + 'label' => 'Setting Name', + 'description' => 'Setting Description', + 'tip' => 'Setting Tip', + ), + ), + // Empty 'title' and 'desc' + array( + array( + 'id' => 'setting-id', + 'type' => 'select', + ), + array( + 'id' => 'setting-id', + 'type' => 'select', + 'label' => '', + 'description' => '', + ), + ), + ); + } + + /** + * @dataProvider new_setting_from_legacy_provider + * @covers WC_Register_Legacy_Settings::new_setting_from_legacy + */ + public function test_new_setting_from_legacy( $input, $expected ) { + $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); + + $actual = $legacy_settings->new_setting_from_legacy( $input ); + + $this->assertEquals( $expected, $actual ); + } + } \ No newline at end of file From ca15237332b3a8cdf5e020261021cb76e3a65562 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 12:07:02 -0600 Subject: [PATCH 063/298] Add test coverage for register_legacy_settings(). --- .../settings/register-legacy-settings.php | 85 ++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/tests/unit-tests/settings/register-legacy-settings.php b/tests/unit-tests/settings/register-legacy-settings.php index 7bad6e41b59..2fa41ce58c9 100644 --- a/tests/unit-tests/settings/register-legacy-settings.php +++ b/tests/unit-tests/settings/register-legacy-settings.php @@ -18,7 +18,19 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { public function setUp() { parent::setUp(); - $this->page = new WC_Settings_General(); + $mock_page = $this->getMock( 'WC_Settings_General' ); + + $mock_page + ->expects( $this->any() ) + ->method( 'get_id' ) + ->will( $this->returnValue( 'page-id' ) ); + + $mock_page + ->expects( $this->any() ) + ->method( 'get_label' ) + ->will( $this->returnValue( 'Page Label' ) ); + + $this->page = $mock_page; } /** @@ -144,4 +156,75 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { $this->assertEquals( $expected, $actual ); } + /** + * @covers WC_Register_Legacy_Settings::register_legacy_settings + */ + public function test_register_legacy_settings_one_section() { + $this->page + ->expects( $this->any() ) + ->method( 'get_sections' ) + ->will( $this->returnValue( array() ) ); + + $this->page + ->expects( $this->once() ) + ->method( 'get_settings' ) + ->with( $this->equalTo( 0 ) ) + ->will( $this->returnValue( array() ) ); + + $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); + + $expected = array(); + $actual = $legacy_settings->register_legacy_settings( array() ); + + $this->assertEquals( $expected, $actual ); + } + + /** + * @covers WC_Register_Legacy_Settings::register_legacy_settings + */ + public function test_register_legacy_settings() { + $this->page + ->expects( $this->any() ) + ->method( 'get_sections' ) + ->will( $this->returnValue( array() ) ); + + $settings = array( + array( + 'id' => 'setting-1', + 'type' => 'text', + ), + array( + 'type' => 'no-id', + ), + array( + 'id' => 'setting-2', + 'type' => 'textarea', + ), + ); + + $this->page + ->expects( $this->any() ) + ->method( 'get_settings' ) + ->will( $this->returnValue( $settings ) ); + + $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); + + $expected = array( + array( + 'id' => 'setting-1', + 'type' => 'text', + 'label' => '', + 'description' => '', + ), + array( + 'id' => 'setting-2', + 'type' => 'textarea', + 'label' => '', + 'description' => '', + ), + ); + $actual = $legacy_settings->register_legacy_settings( array() ); + + $this->assertEquals( $expected, $actual ); + } } \ No newline at end of file From cf65ff53c5110fdc26a84c1a7383b8f2acf1fe9a Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 14:27:54 -0600 Subject: [PATCH 064/298] Add test coverage for all WP_Error-returning cases in the Settings API. --- tests/unit-tests/api/settings.php | 76 ++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 39894569962..ba4e5dd900f 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -100,6 +100,22 @@ class Settings extends WC_Unit_Test_Case { $this->assertEquals( 401, $response->get_status() ); } + /** + * Test /settings without valid permissions/creds. + * @since 2.7.0 + * @covers WC_Rest_Settings_Groups_Controller::get_items + */ + public function test_get_groups_none_registered() { + wp_set_current_user( $this->user ); + + remove_all_filters( 'woocommerce_settings_groups' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings' ) ); + $this->assertEquals( 500, $response->get_status() ); + + WC_Helper_Settings::register(); + } + /** * Test groups schema. * @since 2.7.0 @@ -144,14 +160,16 @@ class Settings extends WC_Unit_Test_Case { public function test_get_group() { wp_set_current_user( $this->user ); + // test route callback receiving an empty group id + $result = $this->endpoint->get_group_settings( '' ); + $this->assertIsWPError( $result ); + // test getting a group that does not exist $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/not-real' ) ); - $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting the 'invalid' group $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/invalid' ) ); - $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting a valid group @@ -367,6 +385,44 @@ class Settings extends WC_Unit_Test_Case { $this->assertEquals( 401, $response->get_status() ); } + /** + * Tests the GET single setting route handler receiving an empty setting ID. + */ + public function test_get_setting_empty_setting_id() { + $result = $this->endpoint->get_setting( 'test', '' ); + + $this->assertIsWPError( $result ); + } + + /** + * Tests the GET single setting route handler receiving an invalid setting ID. + */ + public function test_get_setting_invalid_setting_id() { + $result = $this->endpoint->get_setting( 'test', 'invalid' ); + + $this->assertIsWPError( $result ); + } + + /** + * Tests the GET single setting route handler encountering an invalid setting type. + */ + public function test_get_setting_invalid_setting_type() { + $controller = $this->getMock( 'WC_Rest_Settings_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) ); + + $controller + ->expects( $this->any() ) + ->method( 'get_group_settings' ) + ->will( $this->returnValue( WC_Helper_Settings::register_test_settings( array() ) ) ); + + $controller + ->expects( $this->any() ) + ->method( 'is_setting_type_valid' ) + ->will( $this->returnValue( false ) ); + + $result = $controller->get_setting( 'test', 'woocommerce_enable_lightbox' ); + + $this->assertIsWPError( $result ); + } /** * Test updating a single setting without valid user permissions. @@ -404,6 +460,22 @@ class Settings extends WC_Unit_Test_Case { $this->assertEquals( 401, $response->get_status() ); } + /** + * Test updating a bad setting ID. + * @since 2.7.0 + * @covers WC_Rest_Settings_Controller::update_item + */ + public function test_update_setting_bad_setting_id() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', '/wc/v1/settings/test/invalid' ); + $request->set_body_params( array( + 'value' => 'test', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + /** * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API. * @since 2.7.0 From 8b0416c4b249b05031b30f91ffc8bdb222e67f44 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 16:11:51 -0600 Subject: [PATCH 065/298] =?UTF-8?q?When=20saving=20settings,=20only=20allo?= =?UTF-8?q?w=20values=20found=20in=20=E2=80=9Coptions=E2=80=9D=20for=20?= =?UTF-8?q?=E2=80=9Cselect=E2=80=9D=20type=20fields.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/admin/class-wc-admin-settings.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/includes/admin/class-wc-admin-settings.php b/includes/admin/class-wc-admin-settings.php index b4d42d8ddb3..2e4d242f26f 100644 --- a/includes/admin/class-wc-admin-settings.php +++ b/includes/admin/class-wc-admin-settings.php @@ -718,6 +718,15 @@ class WC_Admin_Settings { $value['crop'] = $option['default']['crop']; } break; + case 'select': + $allowed_values = empty( $option['options'] ) ? array() : array_keys( $option['options'] ); + if ( empty( $option['default'] ) && empty( $allowed_values ) ) { + $value = null; + break; + } + $default = ( empty( $option['default'] ) ? $allowed_values[0] : $option['default'] ); + $value = in_array( $raw_value, $allowed_values ) ? $raw_value : $default; + break; default : $value = wc_clean( $raw_value ); break; From f56a79c74bbe162b3c88ed65e7a1542ba79db33c Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 14:11:50 -0600 Subject: [PATCH 066/298] Rename WC_Rest_Settings_Controller to WC_Rest_Settings_Options_Controller. --- ...er.php => class-wc-rest-settings-options-controller.php} | 2 +- includes/class-wc-api.php | 4 ++-- tests/unit-tests/api/settings.php | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) rename includes/api/{class-wc-rest-settings-controller.php => class-wc-rest-settings-options-controller.php} (99%) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-options-controller.php similarity index 99% rename from includes/api/class-wc-rest-settings-controller.php rename to includes/api/class-wc-rest-settings-options-controller.php index f591a77cec5..073d4bfa767 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-options-controller.php @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { +class WC_Rest_Settings_Options_Controller extends WC_REST_Settings_API_Controller { /** * WP REST API namespace/version. diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index eb278b6f92c..453dcdcf6a5 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -164,7 +164,7 @@ class WC_API extends WC_Legacy_API { include_once( 'api/class-wc-rest-report-sales-controller.php' ); include_once( 'api/class-wc-rest-report-top-sellers-controller.php' ); include_once( 'api/class-wc-rest-reports-controller.php' ); - include_once( 'api/class-wc-rest-settings-controller.php' ); + include_once( 'api/class-wc-rest-settings-options-controller.php' ); include_once( 'api/class-wc-rest-settings-groups-controller.php' ); include_once( 'api/class-wc-rest-tax-classes-controller.php' ); include_once( 'api/class-wc-rest-taxes-controller.php' ); @@ -194,7 +194,7 @@ class WC_API extends WC_Legacy_API { 'WC_REST_Report_Sales_Controller', 'WC_REST_Report_Top_Sellers_Controller', 'WC_REST_Reports_Controller', - 'WC_Rest_Settings_Controller', + 'WC_Rest_Settings_Options_Controller', 'WC_REST_Settings_Groups_Controller', 'WC_REST_Tax_Classes_Controller', 'WC_REST_Taxes_Controller', diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index ba4e5dd900f..6269aac2381 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -17,7 +17,7 @@ class Settings extends WC_Unit_Test_Case { global $wp_rest_server; $this->server = $wp_rest_server = new WP_Test_Spy_REST_Server; do_action( 'rest_api_init' ); - $this->endpoint = new WC_Rest_Settings_Controller(); + $this->endpoint = new WC_Rest_Settings_Options_Controller(); WC_Helper_Settings::register(); $this->user = $this->factory->user->create( array( 'role' => 'administrator', @@ -407,7 +407,7 @@ class Settings extends WC_Unit_Test_Case { * Tests the GET single setting route handler encountering an invalid setting type. */ public function test_get_setting_invalid_setting_type() { - $controller = $this->getMock( 'WC_Rest_Settings_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) ); + $controller = $this->getMock( 'WC_Rest_Settings_Options_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) ); $controller ->expects( $this->any() ) @@ -463,7 +463,7 @@ class Settings extends WC_Unit_Test_Case { /** * Test updating a bad setting ID. * @since 2.7.0 - * @covers WC_Rest_Settings_Controller::update_item + * @covers WC_Rest_Settings_Options_Controller::update_item */ public function test_update_setting_bad_setting_id() { wp_set_current_user( $this->user ); From 6f36179fe6abf9d0c853e353604f0b1cb22b27cc Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 14:19:15 -0600 Subject: [PATCH 067/298] Rename WC_Rest_Settings_Groups_Controller to WC_Rest_Settings_Controller. --- ...s-controller.php => class-wc-rest-settings-controller.php} | 2 +- includes/class-wc-api.php | 4 ++-- tests/unit-tests/api/settings.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename includes/api/{class-wc-rest-settings-groups-controller.php => class-wc-rest-settings-controller.php} (98%) diff --git a/includes/api/class-wc-rest-settings-groups-controller.php b/includes/api/class-wc-rest-settings-controller.php similarity index 98% rename from includes/api/class-wc-rest-settings-groups-controller.php rename to includes/api/class-wc-rest-settings-controller.php index 1884c028b55..b89191d2e28 100644 --- a/includes/api/class-wc-rest-settings-groups-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Groups_Controller extends WC_REST_Settings_API_Controller { +class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { /** * WP REST API namespace/version. diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 453dcdcf6a5..d10cd0a86f1 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -164,8 +164,8 @@ class WC_API extends WC_Legacy_API { include_once( 'api/class-wc-rest-report-sales-controller.php' ); include_once( 'api/class-wc-rest-report-top-sellers-controller.php' ); include_once( 'api/class-wc-rest-reports-controller.php' ); + include_once( 'api/class-wc-rest-settings-controller.php' ); include_once( 'api/class-wc-rest-settings-options-controller.php' ); - include_once( 'api/class-wc-rest-settings-groups-controller.php' ); include_once( 'api/class-wc-rest-tax-classes-controller.php' ); include_once( 'api/class-wc-rest-taxes-controller.php' ); include_once( 'api/class-wc-rest-webhook-deliveries.php' ); @@ -194,8 +194,8 @@ class WC_API extends WC_Legacy_API { 'WC_REST_Report_Sales_Controller', 'WC_REST_Report_Top_Sellers_Controller', 'WC_REST_Reports_Controller', + 'WC_Rest_Settings_Controller', 'WC_Rest_Settings_Options_Controller', - 'WC_REST_Settings_Groups_Controller', 'WC_REST_Tax_Classes_Controller', 'WC_REST_Taxes_Controller', 'WC_REST_Webhook_Deliveries_Controller', diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 6269aac2381..f9cd9faaf95 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -103,7 +103,7 @@ class Settings extends WC_Unit_Test_Case { /** * Test /settings without valid permissions/creds. * @since 2.7.0 - * @covers WC_Rest_Settings_Groups_Controller::get_items + * @covers WC_Rest_Settings_Controller::get_items */ public function test_get_groups_none_registered() { wp_set_current_user( $this->user ); From b31818e695a932523ce5b1043f0e91b48b9ba787 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 14:47:56 -0600 Subject: [PATCH 068/298] Remove WC_REST_Settings_Controller dependency on WC_REST_Settings_API_Controller. --- .../api/class-wc-rest-settings-controller.php | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index b89191d2e28..560bd125466 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -13,13 +13,20 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { +class WC_Rest_Settings_Controller extends WC_REST_Controller { /** * WP REST API namespace/version. */ protected $namespace = 'wc/v1'; + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'settings'; + /** * Register routes. * @since 2.7.0 @@ -29,7 +36,7 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); @@ -152,6 +159,21 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { ); } + /** + * Makes sure the current user has access to READ the settings APIs. + * + * @since 2.7.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + /** * Get the groups schema, conforming to JSON Schema. * From 9cfe89bbb61cc2df65a21e167bb92879950ed7d7 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 14:48:58 -0600 Subject: [PATCH 069/298] Remove WC_REST_Settings_Options_Controller dependency on WC_REST_Settings_API_Controller. --- ...ss-wc-rest-settings-options-controller.php | 97 ++++++++++++++++++- 1 file changed, 92 insertions(+), 5 deletions(-) diff --git a/includes/api/class-wc-rest-settings-options-controller.php b/includes/api/class-wc-rest-settings-options-controller.php index 073d4bfa767..5086d2107ae 100644 --- a/includes/api/class-wc-rest-settings-options-controller.php +++ b/includes/api/class-wc-rest-settings-options-controller.php @@ -13,13 +13,20 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Options_Controller extends WC_REST_Settings_API_Controller { +class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * WP REST API namespace/version. */ protected $namespace = 'wc/v1'; + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'settings'; + /** * Register routes. * @since 2.7.0 @@ -29,7 +36,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Settings_API_Controlle array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); @@ -38,7 +45,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Settings_API_Controlle array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), @@ -48,12 +55,12 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Settings_API_Controlle array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), @@ -259,6 +266,86 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Settings_API_Controlle return $links; } + /** + * Makes sure the current user has access to READ the settings APIs. + * + * @since 2.7.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Makes sure the current user has access to WRITE the settings APIs. + * + * @since 2.7.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function update_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Filters out bad values from the settings array/filter so we + * only return known values via the API. + * + * @since 2.7.0 + * @param array $setting + * @return array + */ + public function filter_setting( $setting ) { + $setting = array_intersect_key( + $setting, + array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) + ); + + if ( empty( $setting['options'] ) ) { + unset( $setting['options'] ); + } + + return $setting; + } + + /** + * Callback for allowed keys for each setting response. + * + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function allowed_setting_keys( $key ) { + return in_array( $key, array( + 'id', 'label', 'description', 'default', 'tip', + 'placeholder', 'type', 'options', 'value', + ) ); + } + + /** + * Boolean for if a setting type is a valid supported setting type. + * + * @since 2.7.0 + * @param string $type + * @return boolean + */ + public function is_setting_type_valid( $type ) { + return in_array( $type, array( + 'text', 'email', 'number', 'color', 'password', + 'textarea', 'select', 'multiselect', 'radio', 'checkbox', + 'multi_select_countries', 'image_width', + ) ); + } + /** * Get the settings schema, conforming to JSON Schema. * From d8fec21147c86616d701b3692b9461e7219dc7f4 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 14:51:48 -0600 Subject: [PATCH 070/298] Remove now defunct WC_REST_Settings_API_Controller class. --- ...stract-wc-rest-settings-api-controller.php | 93 ------------------- includes/class-wc-api.php | 1 - 2 files changed, 94 deletions(-) delete mode 100644 includes/abstracts/abstract-wc-rest-settings-api-controller.php diff --git a/includes/abstracts/abstract-wc-rest-settings-api-controller.php b/includes/abstracts/abstract-wc-rest-settings-api-controller.php deleted file mode 100644 index 8d6cd5823b3..00000000000 --- a/includes/abstracts/abstract-wc-rest-settings-api-controller.php +++ /dev/null @@ -1,93 +0,0 @@ - rest_authorization_required_code() ) - ); - } - - return true; - } - - /** - * Filters out bad values from the settings array/filter so we - * only return known values via the API. - * - * @since 2.7.0 - * @param array $setting - * @return array - */ - public function filter_setting( $setting ) { - $setting = array_intersect_key( - $setting, - array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) - ); - - if ( empty( $setting['options'] ) ) { - unset( $setting['options'] ); - } - - return $setting; - } - - /** - * Callback for allowed keys for each setting response. - * - * @since 2.7.0 - * @param string $key Key to check - * @return boolean - */ - public function allowed_setting_keys( $key ) { - return in_array( $key, array( - 'id', 'label', 'description', 'default', 'tip', - 'placeholder', 'type', 'options', 'value', - ) ); - } - - /** - * Boolean for if a setting type is a valid supported setting type. - * - * @since 2.7.0 - * @param string $type - * @return boolean - */ - public function is_setting_type_valid( $type ) { - return in_array( $type, array( - 'text', 'email', 'number', 'color', 'password', - 'textarea', 'select', 'multiselect', 'radio', 'checkbox', - 'multi_select_countries', 'image_width', - ) ); - } -} diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index d10cd0a86f1..4e7834367e8 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -143,7 +143,6 @@ class WC_API extends WC_Legacy_API { // Abstract controllers. include_once( 'abstracts/abstract-wc-rest-controller.php' ); include_once( 'abstracts/abstract-wc-rest-posts-controller.php' ); - include_once( 'abstracts/abstract-wc-rest-settings-api-controller.php' ); include_once( 'abstracts/abstract-wc-rest-terms-controller.php' ); include_once( 'abstracts/abstract-wc-settings-api.php' ); From 18c8d12eaa045ca42283f6984a26bf483ade7fd0 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 15:43:03 -0600 Subject: [PATCH 071/298] Move legacy setting API registration hooks into main WC_API class. --- includes/class-wc-api.php | 14 ++++++++++++++ includes/class-wc-register-legacy-settings.php | 13 ------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 4e7834367e8..9f86a3e978b 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -121,6 +121,9 @@ class WC_API extends WC_Legacy_API { // Init REST API routes. add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) ); + + // Register legacy settings to the REST API. + add_action( 'rest_api_init', array( $this, 'register_legacy_settings' ) ); } /** @@ -206,4 +209,15 @@ class WC_API extends WC_Legacy_API { $this->$controller->register_routes(); } } + + /** + * Register legacy settings to the REST API. + * @since 2.7.0 + */ + public function register_legacy_settings() { + $pages = WC_Admin_Settings::get_settings_pages(); + foreach ( $pages as $page ) { + new WC_Register_Legacy_Settings( $page ); + } + } } diff --git a/includes/class-wc-register-legacy-settings.php b/includes/class-wc-register-legacy-settings.php index 76318fd428b..eb32b02df35 100644 --- a/includes/class-wc-register-legacy-settings.php +++ b/includes/class-wc-register-legacy-settings.php @@ -100,16 +100,3 @@ class WC_Register_Legacy_Settings { return $new_setting; } } - -/** - * Register legacy settings to the REST API. - * @since 2.7.0 - */ - function wc_settings_api_register_legacy() { - $pages = WC_Admin_Settings::get_settings_pages(); - foreach ( $pages as $page ) { - new WC_Register_Legacy_Settings( $page ); - } - } - -add_action( 'rest_api_init', 'wc_settings_api_register_legacy' ); From d1eaf3851aa75aa479842570f47f397dcd4e2429 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 15:46:36 -0600 Subject: [PATCH 072/298] Remove now defunct WP API vendor file. --- includes/vendor/wp-api-functions.php | 199 --------------------------- 1 file changed, 199 deletions(-) delete mode 100644 includes/vendor/wp-api-functions.php diff --git a/includes/vendor/wp-api-functions.php b/includes/vendor/wp-api-functions.php deleted file mode 100644 index 90c0713a229..00000000000 --- a/includes/vendor/wp-api-functions.php +++ /dev/null @@ -1,199 +0,0 @@ - null, - 'update_callback' => null, - 'schema' => null, - ); - - $args = wp_parse_args( $args, $defaults ); - - global $wp_rest_additional_fields; - - $object_types = (array) $object_type; - - foreach ( $object_types as $object_type ) { - $wp_rest_additional_fields[ $object_type ][ $attribute ] = $args; - } - } -} - -if ( ! function_exists( 'register_api_field' ) ) { - /** - * Backwards compat shim - */ - function register_api_field( $object_type, $attributes, $args = array() ) { - _deprecated_function( 'register_api_field', 'WPAPI-2.0', 'register_rest_field' ); - register_rest_field( $object_type, $attributes, $args ); - } -} - -if ( ! function_exists( 'rest_validate_request_arg' ) ) { - /** - * Validate a request argument based on details registered to the route. - * - * @param mixed $value - * @param WP_REST_Request $request - * @param string $param - * @return WP_Error|boolean - */ - function rest_validate_request_arg( $value, $request, $param ) { - - $attributes = $request->get_attributes(); - if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { - return true; - } - $args = $attributes['args'][ $param ]; - - if ( ! empty( $args['enum'] ) ) { - if ( ! in_array( $value, $args['enum'] ) ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not one of %s' ), $param, implode( ', ', $args['enum'] ) ) ); - } - } - - if ( 'integer' === $args['type'] && ! is_numeric( $value ) ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not of type %s' ), $param, 'integer' ) ); - } - - if ( 'string' === $args['type'] && ! is_string( $value ) ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not of type %s' ), $param, 'string' ) ); - } - - if ( isset( $args['format'] ) ) { - switch ( $args['format'] ) { - case 'date-time' : - if ( ! rest_parse_date( $value ) ) { - return new WP_Error( 'rest_invalid_date', __( 'The date you provided is invalid.' ) ); - } - break; - - case 'email' : - if ( ! is_email( $value ) ) { - return new WP_Error( 'rest_invalid_email', __( 'The email address you provided is invalid.' ) ); - } - break; - } - } - - if ( in_array( $args['type'], array( 'numeric', 'integer' ) ) && ( isset( $args['minimum'] ) || isset( $args['maximum'] ) ) ) { - if ( isset( $args['minimum'] ) && ! isset( $args['maximum'] ) ) { - if ( ! empty( $args['exclusiveMinimum'] ) && $value <= $args['minimum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be greater than %d (exclusive)' ), $param, $args['minimum'] ) ); - } else if ( empty( $args['exclusiveMinimum'] ) && $value < $args['minimum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be greater than %d (inclusive)' ), $param, $args['minimum'] ) ); - } - } else if ( isset( $args['maximum'] ) && ! isset( $args['minimum'] ) ) { - if ( ! empty( $args['exclusiveMaximum'] ) && $value >= $args['maximum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be less than %d (exclusive)' ), $param, $args['maximum'] ) ); - } else if ( empty( $args['exclusiveMaximum'] ) && $value > $args['maximum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be less than %d (inclusive)' ), $param, $args['maximum'] ) ); - } - } else if ( isset( $args['maximum'] ) && isset( $args['minimum'] ) ) { - if ( ! empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) { - if ( $value >= $args['maximum'] || $value <= $args['minimum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (exclusive) and %d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); - } - } else if ( empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) { - if ( $value >= $args['maximum'] || $value < $args['minimum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (inclusive) and %d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); - } - } else if ( ! empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) { - if ( $value > $args['maximum'] || $value <= $args['minimum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (exclusive) and %d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); - } - } else if ( empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) { - if ( $value > $args['maximum'] || $value < $args['minimum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (inclusive) and %d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); - } - } - } - } - - return true; - } -} - -if ( ! function_exists( 'rest_sanitize_request_arg' ) ) { - /** - * Sanitize a request argument based on details registered to the route. - * - * @param mixed $value - * @param WP_REST_Request $request - * @param string $param - * @return mixed - */ - function rest_sanitize_request_arg( $value, $request, $param ) { - - $attributes = $request->get_attributes(); - if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { - return $value; - } - $args = $attributes['args'][ $param ]; - - if ( 'integer' === $args['type'] ) { - return (int) $value; - } - - if ( isset( $args['format'] ) ) { - switch ( $args['format'] ) { - case 'date-time' : - return sanitize_text_field( $value ); - - case 'email' : - /* - * sanitize_email() validates, which would be unexpected - */ - return sanitize_text_field( $value ); - - case 'uri' : - return esc_url_raw( $value ); - } - } - - return $value; - } - -} From 35f0d77e7d31facf8cba2275358e527e94ab4eea Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 16:01:14 -0600 Subject: [PATCH 073/298] Call register_legacy_settings() directly instead of adding another hook. --- includes/class-wc-api.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 9f86a3e978b..2d69d7fee26 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -121,9 +121,6 @@ class WC_API extends WC_Legacy_API { // Init REST API routes. add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) ); - - // Register legacy settings to the REST API. - add_action( 'rest_api_init', array( $this, 'register_legacy_settings' ) ); } /** @@ -179,6 +176,9 @@ class WC_API extends WC_Legacy_API { * @since 2.6.0 */ public function register_rest_routes() { + // Register legacy settings to the REST API. + $this->register_legacy_settings(); + $controllers = array( 'WC_REST_Coupons_Controller', 'WC_REST_Customer_Downloads_Controller', From 57fd38c1a8fb3aeb7d437349661f35c8e6196bd7 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 19 Jul 2016 11:24:05 -0700 Subject: [PATCH 074/298] Misc cleanup of descriptions and some error strings. --- .../api/class-wc-rest-settings-controller.php | 6 +++-- ...ss-wc-rest-settings-options-controller.php | 19 +++++++++----- .../class-wc-register-legacy-settings.php | 9 ++++--- .../helpers/class-wc-helper-settings.php | 3 +++ tests/unit-tests/api/settings.php | 25 ++++++++++++++++++- .../settings/register-legacy-settings.php | 13 ++++++++-- 6 files changed, 61 insertions(+), 14 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index 560bd125466..467912eb72a 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -29,6 +29,7 @@ class WC_Rest_Settings_Controller extends WC_REST_Controller { /** * Register routes. + * * @since 2.7.0 */ public function register_routes() { @@ -101,6 +102,7 @@ class WC_Rest_Settings_Controller extends WC_REST_Controller { /** * Prepare a report sales object for serialization. * + * @since 2.7.0 * @param array $item Group object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. @@ -194,14 +196,14 @@ class WC_Rest_Settings_Controller extends WC_REST_Controller { ), ), 'label' => array( - 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable translation wrapped label. Meant to be used in interfaces.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'description' => array( - 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable translation wrapped description. Meant to be used in interfaces', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', diff --git a/includes/api/class-wc-rest-settings-options-controller.php b/includes/api/class-wc-rest-settings-options-controller.php index 5086d2107ae..1e3fe20d0b8 100644 --- a/includes/api/class-wc-rest-settings-options-controller.php +++ b/includes/api/class-wc-rest-settings-options-controller.php @@ -29,6 +29,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Register routes. + * * @since 2.7.0 */ public function register_routes() { @@ -69,6 +70,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Return a single setting. + * * @since 2.7.0 * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response @@ -87,6 +89,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Return all settings in a group. + * * @since 2.7.0 * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response @@ -112,19 +115,19 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Get all settings in a group. * + * @since 2.7.0 * @param string $group_id Group ID. - * * @return array|WP_Error */ public function get_group_settings( $group_id ) { if ( empty( $group_id ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); if ( empty( $settings ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } $filtered_settings = array(); @@ -143,9 +146,9 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Get setting data. * + * @since 2.7.0 * @param string $group_id Group ID. * @param string $setting_id Setting ID. - * * @return stdClass|WP_Error */ public function get_setting( $group_id, $setting_id ) { @@ -177,6 +180,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Bulk create, update and delete items. * + * @since 2.7.0 * @param WP_REST_Request $request Full details about the request. * @return array Of WP_Error or WP_REST_Response. */ @@ -202,6 +206,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Update a single setting in a group. + * @since 2.7.0 * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response @@ -226,6 +231,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Prepare a single setting object for response. * + * @since 2.7.0 * @param object $item Setting object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. @@ -248,6 +254,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Prepare links for the request. * + * @since 2.7.0 * @param string $setting_id Setting ID. * @param string $group_id Group ID. * @return array Links for the given setting. @@ -366,14 +373,14 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { ), ), 'label' => array( - 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable translation wrapped label. Meant to be used in interfaces.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'description' => array( - 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable translation wrapped description. Meant to be used in interfaces.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', diff --git a/includes/class-wc-register-legacy-settings.php b/includes/class-wc-register-legacy-settings.php index eb32b02df35..a342c414947 100644 --- a/includes/class-wc-register-legacy-settings.php +++ b/includes/class-wc-register-legacy-settings.php @@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @version 2.7.0 * @since 2.7.0 - * @package WooCommerce/Classes + * @package WooCommerce/Classes * @category Class */ class WC_Register_Legacy_Settings { @@ -19,6 +19,7 @@ class WC_Register_Legacy_Settings { /** * Hooks into the settings API and starts registering our settings registered via legacy hooks/filters. + * * @since 2.7.0 */ public function __construct( $page ) { @@ -29,6 +30,7 @@ class WC_Register_Legacy_Settings { /** * Registers a setting group. + * * @since 2.7.0 * @param array $group * @return array @@ -43,6 +45,7 @@ class WC_Register_Legacy_Settings { /** * Registers the actual settings to the group they came from. + * * @since 2.7.0 * @param array $settings Existing registered settings * @return array @@ -67,10 +70,10 @@ class WC_Register_Legacy_Settings { /** * Convert a "legacy" setting (WC_Settings_Page::get_settings()) into the format expected - * for the REST API Settings Controller + * for the REST API Settings Controller. * + * @since 2.7.0 * @param $legacy_setting Settings array, as produced by a subclass of WC_Settings_Page. - * * @return array|bool Boolean false if legacy setting has no ID, Array of converted new setting otherwise. */ public function new_setting_from_legacy( $legacy_setting ) { diff --git a/tests/framework/helpers/class-wc-helper-settings.php b/tests/framework/helpers/class-wc-helper-settings.php index 2a042bc624b..93495166dee 100644 --- a/tests/framework/helpers/class-wc-helper-settings.php +++ b/tests/framework/helpers/class-wc-helper-settings.php @@ -9,6 +9,7 @@ class WC_Helper_Settings { /** * Hooks in some dummy data for testing the settings REST API. + * * @since 2.7.0 */ public static function register() { @@ -18,6 +19,7 @@ class WC_Helper_Settings { /** * Registers some example setting groups, including invalid ones that should not show up in JSON responses. + * * @since 2.7.0 * @param array $groups * @return array @@ -47,6 +49,7 @@ class WC_Helper_Settings { /** * Registers some example settings. + * * @since 2.7.0 * @param array $settings * @return array diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index f9cd9faaf95..0b64745685b 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -1,7 +1,8 @@ endpoint->get_setting( 'test', '' ); @@ -396,6 +411,8 @@ class Settings extends WC_Unit_Test_Case { /** * Tests the GET single setting route handler receiving an invalid setting ID. + * + * @since 2.7.0 */ public function test_get_setting_invalid_setting_id() { $result = $this->endpoint->get_setting( 'test', 'invalid' ); @@ -405,6 +422,8 @@ class Settings extends WC_Unit_Test_Case { /** * Tests the GET single setting route handler encountering an invalid setting type. + * + * @since 2.7.0 */ public function test_get_setting_invalid_setting_type() { $controller = $this->getMock( 'WC_Rest_Settings_Options_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) ); @@ -426,6 +445,7 @@ class Settings extends WC_Unit_Test_Case { /** * Test updating a single setting without valid user permissions. + * * @since 2.7.0 */ public function test_update_setting_without_permission() { @@ -442,6 +462,7 @@ class Settings extends WC_Unit_Test_Case { /** * Test updating multiple settings without valid user permissions. + * * @since 2.7.0 */ public function test_update_settings_without_permission() { @@ -462,6 +483,7 @@ class Settings extends WC_Unit_Test_Case { /** * Test updating a bad setting ID. + * * @since 2.7.0 * @covers WC_Rest_Settings_Options_Controller::update_item */ @@ -478,6 +500,7 @@ class Settings extends WC_Unit_Test_Case { /** * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API. + * * @since 2.7.0 */ public function test_classic_settings() { diff --git a/tests/unit-tests/settings/register-legacy-settings.php b/tests/unit-tests/settings/register-legacy-settings.php index 2fa41ce58c9..8f94342c174 100644 --- a/tests/unit-tests/settings/register-legacy-settings.php +++ b/tests/unit-tests/settings/register-legacy-settings.php @@ -2,6 +2,7 @@ /** * Settings API Tests + * * @package WooCommerce\Tests\Settings * @since 2.7.0 */ @@ -34,16 +35,18 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { } /** + * @since 2.7.0 * @covers WC_Register_Legacy_Settings::__construct */ public function test_constructor() { $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); - + $this->assertEquals( has_filter( 'woocommerce_settings_groups', array( $legacy_settings, 'register_legacy_group' ) ), 10 ); $this->assertEquals( has_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $legacy_settings, 'register_legacy_settings' ) ), 10 ); } /** + * @since 2.7.0 * @covers WC_Register_Legacy_Settings::register_legacy_group */ public function test_register_legacy_group() { @@ -66,6 +69,9 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { $this->assertEquals( $expected, $actual ); } + /** + * @since 2.7.0 + */ public function new_setting_from_legacy_provider() { return array( // No "id" case @@ -145,6 +151,7 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { } /** + * @since 2.7.0 * @dataProvider new_setting_from_legacy_provider * @covers WC_Register_Legacy_Settings::new_setting_from_legacy */ @@ -157,6 +164,7 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { } /** + * @since 2.7.0 * @covers WC_Register_Legacy_Settings::register_legacy_settings */ public function test_register_legacy_settings_one_section() { @@ -180,6 +188,7 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { } /** + * @since 2.7.0 * @covers WC_Register_Legacy_Settings::register_legacy_settings */ public function test_register_legacy_settings() { @@ -227,4 +236,4 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { $this->assertEquals( $expected, $actual ); } -} \ No newline at end of file +} From ec2c82347f57b91c6e332c236b803f4f230b46c5 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 19 Jul 2016 11:38:18 -0700 Subject: [PATCH 075/298] Move WP-APIs test server code to a vendor directory, make sure it matches the version of the other vendor files. --- tests/bootstrap.php | 5 ++--- .../framework/{ => vendor}/class-wp-test-spy-rest-server.php | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) rename tests/framework/{ => vendor}/class-wp-test-spy-rest-server.php (91%) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 87e65f64053..20ddc8ba5a6 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -115,10 +115,9 @@ class WC_Unit_Tests_Bootstrap { require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-settings.php' ); /** - * WP-API - * @todo to be removed when the wp-api branch is merged. + * WP-API. */ - require_once( $this->tests_dir . '/framework/class-wp-test-spy-rest-server.php' ); + require_once( $this->tests_dir . '/framework/vendor/class-wp-test-spy-rest-server.php' ); } /** diff --git a/tests/framework/class-wp-test-spy-rest-server.php b/tests/framework/vendor/class-wp-test-spy-rest-server.php similarity index 91% rename from tests/framework/class-wp-test-spy-rest-server.php rename to tests/framework/vendor/class-wp-test-spy-rest-server.php index ba485b65a1a..4d08c783bd9 100644 --- a/tests/framework/class-wp-test-spy-rest-server.php +++ b/tests/framework/vendor/class-wp-test-spy-rest-server.php @@ -1,7 +1,6 @@ Date: Thu, 21 Jul 2016 13:20:49 -0700 Subject: [PATCH 076/298] Remove "MySQL" string check on version, which was preventing the MySQL version from displaying on the system status report. Version #s don't seem to include "MySQL" in them anymore so the check would prevent the block from being shown. --- includes/admin/views/html-admin-page-status-report.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/admin/views/html-admin-page-status-report.php b/includes/admin/views/html-admin-page-status-report.php index 60c96f8f8ed..b0822abe302 100644 --- a/includes/admin/views/html-admin-page-status-report.php +++ b/includes/admin/views/html-admin-page-status-report.php @@ -180,7 +180,7 @@ global $wpdb; $ver = mysql_get_server_info(); } - if ( ! empty( $wpdb->is_mysql ) && stristr( $ver, 'MySQL' ) ) : ?> + if ( ! empty( $wpdb->is_mysql ) ) : ?> : @@ -349,7 +349,7 @@ global $wpdb;   - prefix ) > 20 ) { echo ' ' . sprintf( __( '%s - We recommend using a prefix with less than 20 characters. See: %s', 'woocommerce' ), esc_html( $wpdb->prefix ), '' . __( 'How to update your database table prefix', 'woocommerce' ) . '' ) . ''; } else { From 9b2ae1827dd1365b6e8376e4a965d654d8b84682 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Thu, 21 Jul 2016 13:23:11 -0700 Subject: [PATCH 077/298] Remove unneccessary ver variable. We already display using wpdb's db_version --- includes/admin/views/html-admin-page-status-report.php | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/includes/admin/views/html-admin-page-status-report.php b/includes/admin/views/html-admin-page-status-report.php index b0822abe302..4bfde347cd8 100644 --- a/includes/admin/views/html-admin-page-status-report.php +++ b/includes/admin/views/html-admin-page-status-report.php @@ -173,14 +173,7 @@ global $wpdb; ' : '–'; ?> - use_mysqli ) { - $ver = mysqli_get_server_info( $wpdb->dbh ); - } else { - $ver = mysql_get_server_info(); - } - - if ( ! empty( $wpdb->is_mysql ) ) : ?> + is_mysql ) ) : ?> : From de603974d44d99fb5f22e3aa94ad9be0cc6ef4fa Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 25 Jul 2016 10:43:27 -0700 Subject: [PATCH 078/298] Only hide MySQL (when is_mysql is set) if MariaDB is found in the version string. --- .../admin/views/html-admin-page-status-report.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/includes/admin/views/html-admin-page-status-report.php b/includes/admin/views/html-admin-page-status-report.php index 4bfde347cd8..20c88d6763e 100644 --- a/includes/admin/views/html-admin-page-status-report.php +++ b/includes/admin/views/html-admin-page-status-report.php @@ -172,8 +172,15 @@ global $wpdb; ' : '–'; ?> - - is_mysql ) ) : ?> + use_mysqli ) { + $ver = mysqli_get_server_info( $wpdb->dbh ); + } else { + $ver = mysql_get_server_info(); + } + + if ( ! empty( $wpdb->is_mysql ) && ! stristr( $ver, 'MariaDB' ) ) : ?> : From 671dc8168dd67e01fb4e5eded795134f42930642 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 25 Jul 2016 11:19:44 -0700 Subject: [PATCH 079/298] Add new file for creating new unit test files for testing WP-API based WC endpoints. Add WP-API's test-spy-rest-server class to new vendor folder in our test framework. Create a new unit test case class to extend of of. This can also be a future home for new asserts or methods related to the API tests. --- tests/bootstrap.php | 2 + .../class-wc-rest-unit-test-case.php | 33 +++++++++++++++ .../vendor/class-wp-test-spy-rest-server.php | 42 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 tests/framework/class-wc-rest-unit-test-case.php create mode 100644 tests/framework/vendor/class-wp-test-spy-rest-server.php diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 37619b65ce4..771b99f3e37 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -98,10 +98,12 @@ class WC_Unit_Tests_Bootstrap { require_once( $this->tests_dir . '/framework/class-wc-mock-session-handler.php' ); require_once( $this->tests_dir . '/framework/class-wc-mock-wc-data.php' ); require_once( $this->tests_dir . '/framework/class-wc-payment-token-stub.php' ); + require_once( $this->tests_dir . '/framework/vendor/class-wp-test-spy-rest-server.php' ); // test cases require_once( $this->tests_dir . '/framework/class-wc-unit-test-case.php' ); require_once( $this->tests_dir . '/framework/class-wc-api-unit-test-case.php' ); + require_once( $this->tests_dir . '/framework/class-wc-rest-unit-test-case.php' ); // Helpers require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-product.php' ); diff --git a/tests/framework/class-wc-rest-unit-test-case.php b/tests/framework/class-wc-rest-unit-test-case.php new file mode 100644 index 00000000000..1ffde43bd18 --- /dev/null +++ b/tests/framework/class-wc-rest-unit-test-case.php @@ -0,0 +1,33 @@ +server = $wp_rest_server = new WP_Test_Spy_REST_Server; + do_action( 'rest_api_init' ); + } + + /** + * Unset the server. + */ + public function tearDown() { + parent::tearDown(); + global $wp_rest_server; + $wp_rest_server = null; + } + +} diff --git a/tests/framework/vendor/class-wp-test-spy-rest-server.php b/tests/framework/vendor/class-wp-test-spy-rest-server.php new file mode 100644 index 00000000000..c7afcb6cb06 --- /dev/null +++ b/tests/framework/vendor/class-wp-test-spy-rest-server.php @@ -0,0 +1,42 @@ +endpoints; + } + + /** + * Allow calling protected methods from tests + * + * @param string $method Method to call + * @param array $args Arguments to pass to the method + * @return mixed + */ + public function __call( $method, $args ) { + return call_user_func_array( array( $this, $method ), $args ); + } + + /** + * Call dispatch() with the rest_post_dispatch filter + */ + public function dispatch( $request ) { + $result = parent::dispatch( $request ); + $result = rest_ensure_response( $result ); + if ( is_wp_error( $result ) ) { + $result = $this->error_to_response( $result ); + } + return apply_filters( 'rest_post_dispatch', rest_ensure_response( $result ), $this, $request ); + } +} From 3d3b24e39c6677269d00a0eb202e529683c74cd7 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 26 Jul 2016 11:18:58 +0100 Subject: [PATCH 080/298] [2.6] Check taxonomy is set Closes #11526 --- includes/admin/class-wc-admin-taxonomies.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/includes/admin/class-wc-admin-taxonomies.php b/includes/admin/class-wc-admin-taxonomies.php index b8626f57a36..65eee936064 100644 --- a/includes/admin/class-wc-admin-taxonomies.php +++ b/includes/admin/class-wc-admin-taxonomies.php @@ -357,11 +357,9 @@ class WC_Admin_Taxonomies { * @return array */ public function disable_checked_ontop( $args ) { - - if ( 'product_cat' == $args['taxonomy'] ) { + if ( ! empty( $args['taxonomy'] ) && 'product_cat' === $args['taxonomy'] ) { $args['checked_ontop'] = false; } - return $args; } } From 161d31558ba0a6391e098f5e3aa219a3959dff56 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 26 Jul 2016 11:43:54 +0100 Subject: [PATCH 081/298] Shorthand arrays does not work with php 5.3 --- includes/libraries/class-emogrifier.php | 70 ++++++++++++------------- 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/includes/libraries/class-emogrifier.php b/includes/libraries/class-emogrifier.php index 77ee47a09c1..67f65fc5c5a 100644 --- a/includes/libraries/class-emogrifier.php +++ b/includes/libraries/class-emogrifier.php @@ -85,35 +85,35 @@ class Emogrifier /** * @var bool[] */ - private $excludedSelectors = []; + private $excludedSelectors = array(); /** * @var string[] */ - private $unprocessableHtmlTags = ['wbr']; + private $unprocessableHtmlTags = array( 'wbr' ); /** * @var bool[] */ - private $allowedMediaTypes = ['all' => true, 'screen' => true, 'print' => true]; + private $allowedMediaTypes = array( 'all' => true, 'screen' => true, 'print' => true ); /** * @var array[] */ - private $caches = [ - self::CACHE_KEY_CSS => [], - self::CACHE_KEY_SELECTOR => [], - self::CACHE_KEY_XPATH => [], - self::CACHE_KEY_CSS_DECLARATIONS_BLOCK => [], - self::CACHE_KEY_COMBINED_STYLES => [], - ]; + private $caches = array( + self::CACHE_KEY_CSS => array(), + self::CACHE_KEY_SELECTOR => array(), + self::CACHE_KEY_XPATH => array(), + self::CACHE_KEY_CSS_DECLARATIONS_BLOCK => array(), + self::CACHE_KEY_COMBINED_STYLES => array(), + ); /** * the visited nodes with the XPath paths as array keys * * @var \DOMElement[] */ - private $visitedNodes = []; + private $visitedNodes = array(); /** * the styles to apply to the nodes with the XPath paths as array keys for the outer array @@ -121,7 +121,7 @@ class Emogrifier * * @var array[] */ - private $styleAttributesForNodes = []; + private $styleAttributesForNodes = array(); /** * Determines whether the "style" attributes of tags in the the HTML passed to this class should be preserved. @@ -306,7 +306,7 @@ class Emogrifier // break it up into an associative array $oldStyleDeclarations = $this->parseCssDeclarationsBlock($node->getAttribute('style')); } else { - $oldStyleDeclarations = []; + $oldStyleDeclarations = array(); } $newStyleDeclarations = $this->parseCssDeclarationsBlock($cssRule['declarationsBlock']); $node->setAttribute( @@ -345,7 +345,7 @@ class Emogrifier // process the CSS file for selectors and definitions preg_match_all('/(?:^|[\\s^{}]*)([^{]+){([^}]*)}/mis', $css, $matches, PREG_SET_ORDER); - $cssRules = []; + $cssRules = array(); /** @var string[] $cssRule */ foreach ($matches as $key => $cssRule) { $cssDeclaration = trim($cssRule[2]); @@ -361,12 +361,12 @@ class Emogrifier continue; } - $cssRules[] = [ + $cssRules[] = array( 'selector' => trim($selector), 'declarationsBlock' => $cssDeclaration, // keep track of where it appears in the file, since order is important 'line' => $key, - ]; + ); } } @@ -434,18 +434,18 @@ class Emogrifier */ private function clearCache($key) { - $allowedCacheKeys = [ + $allowedCacheKeys = array( self::CACHE_KEY_CSS, self::CACHE_KEY_SELECTOR, self::CACHE_KEY_XPATH, self::CACHE_KEY_CSS_DECLARATIONS_BLOCK, self::CACHE_KEY_COMBINED_STYLES, - ]; + ); if (!in_array($key, $allowedCacheKeys, true)) { throw new \InvalidArgumentException('Invalid cache key: ' . $key, 1391822035); } - $this->caches[$key] = []; + $this->caches[$key] = array(); } /** @@ -455,8 +455,8 @@ class Emogrifier */ private function purgeVisitedNodes() { - $this->visitedNodes = []; - $this->styleAttributesForNodes = []; + $this->visitedNodes = array(); + $this->styleAttributesForNodes = array(); } /** @@ -674,7 +674,7 @@ class Emogrifier return; } - $mediaQueriesRelevantForDocument = []; + $mediaQueriesRelevantForDocument = array(); foreach ($this->extractMediaQueriesFromCss($css) as $mediaQuery) { foreach ($this->parseCssRules($mediaQuery['css']) as $selector) { @@ -698,12 +698,12 @@ class Emogrifier private function extractMediaQueriesFromCss($css) { preg_match_all('#(?@media[^{]*\\{(?(.*?)\\})(\\s*)\\})#s', $css, $mediaQueries); - $result = []; + $result = array(); foreach (array_keys($mediaQueries['css']) as $key) { - $result[] = [ + $result[] = array( 'css' => $mediaQueries['css'][$key], 'query' => $mediaQueries['query'][$key], - ]; + ); } return $result; } @@ -831,10 +831,10 @@ class Emogrifier ); // filter the CSS - $search = [ + $search = array( 'import directives' => '/^\\s*@import\\s[^;]+;/misU', 'remaining media enclosures' => '/^\\s*@media\\s[^{]+{(.*)}\\s*}\\s/misU', - ]; + ); $cleanedCss = preg_replace($search, '', $cssForAllowedMediaTypes); @@ -981,7 +981,7 @@ class Emogrifier $precedence = 0; $value = 100; // ids: worth 100, classes: worth 10, elements: worth 1 - $search = ['\\#','\\.','']; + $search = array( '\\#','\\.','' ); foreach ($search as $s) { if (trim($selector) === '') { @@ -1020,7 +1020,7 @@ class Emogrifier $trimmedLowercaseSelector = trim($lowercasePaddedSelector); $xpathKey = md5($trimmedLowercaseSelector); if (!isset($this->caches[self::CACHE_KEY_XPATH][$xpathKey])) { - $cssSelectorMatches = [ + $cssSelectorMatches = array( 'child' => '/\\s+>\\s+/', 'adjacent sibling' => '/\\s+\\+\\s+/', 'descendant' => '/\\s+/', @@ -1029,8 +1029,8 @@ class Emogrifier 'attribute only' => '/^\\[(\\w+|\\w+\\=[\'"]?\\w+[\'"]?)\\]/', 'attribute' => '/(\\w)\\[(\\w+)\\]/', 'exact attribute' => '/(\\w)\\[(\\w+)\\=[\'"]?(\\w+)[\'"]?\\]/', - ]; - $xPathReplacements = [ + ); + $xPathReplacements = array( 'child' => '/', 'adjacent sibling' => '/following-sibling::*[1]/self::', 'descendant' => '//', @@ -1039,7 +1039,7 @@ class Emogrifier 'attribute only' => '*[@\\1]', 'attribute' => '\\1[@\\2]', 'exact attribute' => '\\1[@\\2="\\3"]', - ]; + ); $roughXpath = '//' . preg_replace($cssSelectorMatches, $xPathReplacements, $trimmedLowercaseSelector); @@ -1230,11 +1230,11 @@ class Emogrifier return $this->caches[self::CACHE_KEY_CSS_DECLARATIONS_BLOCK][$cssDeclarationsBlock]; } - $properties = []; + $properties = array(); $declarations = preg_split('/;(?!base64|charset)/', $cssDeclarationsBlock); foreach ($declarations as $declaration) { - $matches = []; + $matches = array(); if (!preg_match('/^([A-Za-z\\-]+)\\s*:\\s*(.+)$/', trim($declaration), $matches)) { continue; } @@ -1257,7 +1257,7 @@ class Emogrifier */ private function getNodesToExclude(\DOMXPath $xpath) { - $excludedNodes = []; + $excludedNodes = array(); foreach (array_keys($this->excludedSelectors) as $selectorToExclude) { foreach ($xpath->query($this->translateCssToXpath($selectorToExclude)) as $node) { $excludedNodes[] = $node; From 0e1a2d9d044495d7ad550ded40d5f97eb1fcebbb Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 26 Jul 2016 13:37:51 +0100 Subject: [PATCH 082/298] Removed verbose page rule handling in pre_get_posts #11500 --- includes/class-wc-query.php | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/includes/class-wc-query.php b/includes/class-wc-query.php index 77d99a3a4e8..54f98bb218b 100644 --- a/includes/class-wc-query.php +++ b/includes/class-wc-query.php @@ -219,6 +219,22 @@ class WC_Query { } } + /** + * Are we currently on the front page? + * @return boolean + */ + private function is_showing_page_on_front( $q ) { + return $q->is_home() && 'page' === get_option( 'show_on_front' ); + } + + /** + * Is the front page a page we define? + * @return boolean + */ + private function page_on_front_is( $page_id ) { + return absint( get_option( 'page_on_front' ) ) === absint( $page_id ); + } + /** * Hook into pre_get_posts to do the main product query. * @@ -230,21 +246,8 @@ class WC_Query { return; } - // Fix for verbose page rules - if ( $GLOBALS['wp_rewrite']->use_verbose_page_rules && isset( $q->queried_object->ID ) && $q->queried_object->ID === wc_get_page_id( 'shop' ) ) { - $q->set( 'post_type', 'product' ); - $q->set( 'page', '' ); - $q->set( 'pagename', '' ); - - // Fix conditional Functions - $q->is_archive = true; - $q->is_post_type_archive = true; - $q->is_singular = false; - $q->is_page = false; - } - // Fix for endpoints on the homepage - if ( $q->is_home() && 'page' === get_option( 'show_on_front' ) && absint( get_option( 'page_on_front' ) ) !== absint( $q->get( 'page_id' ) ) ) { + if ( $this->is_showing_page_on_front( $q ) && ! $this->page_on_front_is( $q->get( 'page_id' ) ) ) { $_query = wp_parse_args( $q->query ); if ( ! empty( $_query ) && array_intersect( array_keys( $_query ), array_keys( $this->query_vars ) ) ) { $q->is_page = true; @@ -256,7 +259,7 @@ class WC_Query { } // When orderby is set, WordPress shows posts. Get around that here. - if ( $q->is_home() && 'page' === get_option( 'show_on_front' ) && absint( get_option( 'page_on_front' ) ) === wc_get_page_id( 'shop' ) ) { + if ( $this->is_showing_page_on_front( $q ) && $this->page_on_front_is( wc_get_page_id( 'shop' ) ) ) { $_query = wp_parse_args( $q->query ); if ( empty( $_query ) || ! array_diff( array_keys( $_query ), array( 'preview', 'page', 'paged', 'cpage', 'orderby' ) ) ) { $q->is_page = true; @@ -272,8 +275,7 @@ class WC_Query { } // Special check for shops with the product archive on front - if ( $q->is_page() && 'page' === get_option( 'show_on_front' ) && absint( $q->get( 'page_id' ) ) === wc_get_page_id( 'shop' ) ) { - + if ( $this->is_showing_page_on_front( $q ) && absint( $q->get( 'page_id' ) ) === wc_get_page_id( 'shop' ) ) { // This is a front-page shop $q->set( 'post_type', 'product' ); $q->set( 'page_id', '' ); From 479708c78aac533a2c06ad52a9be38b961fecf05 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 26 Jul 2016 13:37:56 +0100 Subject: [PATCH 083/298] Readme --- readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.txt b/readme.txt index 10536b95619..f444d00d4db 100644 --- a/readme.txt +++ b/readme.txt @@ -161,6 +161,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc = 2.7.0 = * Respect stock status and prevent the "out of stock threshold" setting affecting existing in-stock products. * Added Nigerian Provinces to i18n/state. +* Improved handling of shop page rewrite rules to allow subpages. [See changelog for all versions](https://raw.githubusercontent.com/woothemes/woocommerce/master/CHANGELOG.txt). From 3f2ee5a39645f3aa24e1ace8fa86f502d45e2466 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 26 Jul 2016 13:39:31 +0100 Subject: [PATCH 084/298] Rewrite rule improvements Closes #11500 Extra rules are needed to support subpages, but the previous method was very greedy and affected other URIs. To improve this, loop over shop subpages and add rules specific to those to avoid 404s. Also flushes permalinks when a subpage of shop is saved so these rules are correctly generated. --- includes/wc-core-functions.php | 57 +++++++++++++++++++++++++++------- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/includes/wc-core-functions.php b/includes/wc-core-functions.php index 6b8168572ad..93fba552936 100644 --- a/includes/wc-core-functions.php +++ b/includes/wc-core-functions.php @@ -765,16 +765,38 @@ function wc_get_log_file_path( $handle ) { } /** - * Init for our rewrite rule fixes. + * Recursively get page children. + * @param int $page_id + * @return int[] */ -function wc_fix_rewrite_rules_init() { - $permalinks = get_option( 'woocommerce_permalinks' ); +function wc_get_page_children( $page_id ) { + $page_ids = get_posts( array( + 'post_parent' => $page_id, + 'post_type' => 'page', + 'numberposts' => -1, + 'post_status' => 'any', + 'fields' => 'ids', + ) ); - if ( ! empty( $permalinks['use_verbose_page_rules'] ) ) { - $GLOBALS['wp_rewrite']->use_verbose_page_rules = true; + if ( ! empty( $page_ids ) ) { + foreach ( $page_ids as $page_id ) { + $page_ids = array_merge( $page_ids, wc_get_page_children( $page_id ) ); + } + } + + return $page_ids; +} + +/** + * Flushes rewrite rules when the shop page (or it's children) gets saved. + */ +function flush_rewrite_rules_on_shop_page_save( $post_id ) { + $shop_page_id = wc_get_page_id( 'shop' ); + if ( $shop_page_id === $post_id || in_array( $post_id, wc_get_page_children( $shop_page_id ) ) ) { + flush_rewrite_rules(); } } -add_action( 'init', 'wc_fix_rewrite_rules_init' ); +add_action( 'save_post', 'flush_rewrite_rules_on_shop_page_save' ); /** * Various rewrite rule fixes. @@ -792,17 +814,30 @@ function wc_fix_rewrite_rules( $rules ) { // Fix the rewrite rules when the product permalink have %product_cat% flag. if ( preg_match( '`/(.+)(/%product_cat%)`' , $product_permalink, $matches ) ) { foreach ( $rules as $rule => $rewrite ) { - if ( preg_match( '`^' . preg_quote( $matches[1], '`' ) . '/\(`', $rule ) && preg_match( '/^(index\.php\?product_cat)(?!(.*product))/', $rewrite ) ) { unset( $rules[ $rule ] ); } } } - // If the shop page is used as the base, we need to enable verbose rewrite rules or sub pages will 404. - if ( ! empty( $permalinks['use_verbose_page_rules'] ) ) { - $page_rewrite_rules = $wp_rewrite->page_rewrite_rules(); - $rules = array_merge( $page_rewrite_rules, $rules ); + // If the shop page is used as the base, we need to handle shop page subpages to avoid 404s. + if ( ! empty( $permalinks['use_verbose_page_rules'] ) && ( $shop_page_id = wc_get_page_id( 'shop' ) ) ) { + $page_rewrite_rules = array(); + $subpages = wc_get_page_children( $shop_page_id ); + + // Subpage rules + foreach ( $subpages as $subpage ) { + $uri = get_page_uri( $subpage ); + $page_rewrite_rules[ $uri . '/?$' ] = 'index.php?pagename=' . $uri; + $wp_generated_rewrite_rules = $wp_rewrite->generate_rewrite_rules( $uri, EP_PAGES, true, true, false, false ); + foreach ( $wp_generated_rewrite_rules as $key => $value ) { + $wp_generated_rewrite_rules[ $key ] = $value . '&pagename=' . $uri; + } + $page_rewrite_rules = array_merge( $page_rewrite_rules, $wp_generated_rewrite_rules ); + } + + // Merge with rules + $rules = array_merge( $page_rewrite_rules, $rules ); } return $rules; From 6c956879d9659e085a8cb89663148230f74a6642 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 26 Jul 2016 13:41:26 +0100 Subject: [PATCH 085/298] more emogrifier tweaks --- includes/libraries/class-emogrifier.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/libraries/class-emogrifier.php b/includes/libraries/class-emogrifier.php index 67f65fc5c5a..e3014d6e1f9 100644 --- a/includes/libraries/class-emogrifier.php +++ b/includes/libraries/class-emogrifier.php @@ -370,7 +370,7 @@ class Emogrifier } } - usort($cssRules, [$this, 'sortBySelectorPrecedence']); + usort($cssRules, array( $this, 'sortBySelectorPrecedence' ) ); $this->caches[self::CACHE_KEY_CSS][$cssKey] = $cssRules; } @@ -1169,7 +1169,7 @@ class Emogrifier */ private function parseNth(array $match) { - if (in_array(strtolower($match[2]), ['even','odd'], true)) { + if (in_array(strtolower($match[2]), array( 'even','odd' ), true)) { // we have "even" or "odd" $index = strtolower($match[2]) === 'even' ? 0 : 1; return [self::MULTIPLIER => 2, self::INDEX => $index]; From 624f3c2eb1c5c7b96bc7776cf3c41ef170607f36 Mon Sep 17 00:00:00 2001 From: Nicola Mustone Date: Tue, 26 Jul 2016 14:49:11 +0200 Subject: [PATCH 086/298] typo --- includes/admin/class-wc-admin-setup-wizard.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/admin/class-wc-admin-setup-wizard.php b/includes/admin/class-wc-admin-setup-wizard.php index be15b1adebf..cf5beea800a 100644 --- a/includes/admin/class-wc-admin-setup-wizard.php +++ b/includes/admin/class-wc-admin-setup-wizard.php @@ -483,7 +483,7 @@ class WC_Admin_Setup_Wizard { -

    ', '' ); ?>

    +

    ', '' ); ?>

    Date: Tue, 26 Jul 2016 14:50:31 +0200 Subject: [PATCH 087/298] typo 2 --- includes/admin/class-wc-admin-setup-wizard.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/admin/class-wc-admin-setup-wizard.php b/includes/admin/class-wc-admin-setup-wizard.php index cf5beea800a..b4f8f289e4b 100644 --- a/includes/admin/class-wc-admin-setup-wizard.php +++ b/includes/admin/class-wc-admin-setup-wizard.php @@ -606,13 +606,13 @@ class WC_Admin_Setup_Wizard { ), 'bacs' => array( 'name' => __( 'Bank Transfer (BACS) Payments', 'woocommerce' ), - 'description' => __( 'An simple offline gateway that lets you accept BACS payment.', 'woocommerce' ), + 'description' => __( 'A simple offline gateway that lets you accept BACS payment.', 'woocommerce' ), 'image' => '', 'class' => '', ), 'cod' => array( 'name' => __( 'Cash on Delivery', 'woocommerce' ), - 'description' => __( 'An simple offline gateway that lets you accept cash on delivery.', 'woocommerce' ), + 'description' => __( 'A simple offline gateway that lets you accept cash on delivery.', 'woocommerce' ), 'image' => '', 'class' => '', ) From 2dede356d3a0370c92c3b3be38a02201dc93a998 Mon Sep 17 00:00:00 2001 From: Enrico Deleo Date: Tue, 26 Jul 2016 15:15:09 +0200 Subject: [PATCH 088/298] remove a line item if quantity is zero --- includes/api/class-wc-rest-orders-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/api/class-wc-rest-orders-controller.php b/includes/api/class-wc-rest-orders-controller.php index ebd363612f2..4400c1de08c 100644 --- a/includes/api/class-wc-rest-orders-controller.php +++ b/includes/api/class-wc-rest-orders-controller.php @@ -1019,7 +1019,7 @@ class WC_REST_Orders_Controller extends WC_REST_Posts_Controller { // Create item. if ( is_null( $item['id'] ) ) { $this->set_item( $order, $line_type, $item, 'create' ); - } elseif ( $this->item_is_null( $item ) ) { + } elseif ( $this->item_is_null( $item ) || 0 === $item['quantity'] ) { // Delete item. wc_delete_order_item( $item['id'] ); } else { From e799b1e234c6abab45748db7ec737812ae55c1a5 Mon Sep 17 00:00:00 2001 From: Nicola Mustone Date: Tue, 26 Jul 2016 15:46:50 +0200 Subject: [PATCH 089/298] reduce number of strings --- .../admin/settings/class-wc-settings-accounts.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/includes/admin/settings/class-wc-settings-accounts.php b/includes/admin/settings/class-wc-settings-accounts.php index 5d8fe90b1ea..ece3e3f4e15 100644 --- a/includes/admin/settings/class-wc-settings-accounts.php +++ b/includes/admin/settings/class-wc-settings-accounts.php @@ -111,7 +111,7 @@ class WC_Settings_Accounts extends WC_Settings_Page { array( 'title' => __( 'Orders', 'woocommerce' ), - 'desc' => __( 'Endpoint for the My Account → Orders page', 'woocommerce' ), + 'desc' => sprintf( __( 'Endpoint for the My Account → %s page', 'woocommerce' ), __( 'Orders', 'woocommerce' ) ), 'id' => 'woocommerce_myaccount_orders_endpoint', 'type' => 'text', 'default' => 'orders', @@ -120,7 +120,7 @@ class WC_Settings_Accounts extends WC_Settings_Page { array( 'title' => __( 'View Order', 'woocommerce' ), - 'desc' => __( 'Endpoint for the My Account → View Order page', 'woocommerce' ), + 'desc' => sprintf( __( 'Endpoint for the My Account → %s page', 'woocommerce' ), __( 'View Order', 'woocommerce' ) ), 'id' => 'woocommerce_myaccount_view_order_endpoint', 'type' => 'text', 'default' => 'view-order', @@ -129,7 +129,7 @@ class WC_Settings_Accounts extends WC_Settings_Page { array( 'title' => __( 'Downloads', 'woocommerce' ), - 'desc' => __( 'Endpoint for the My Account → Downloads page', 'woocommerce' ), + 'desc' => sprintf( __( 'Endpoint for the My Account → %s page', 'woocommerce' ), __( 'Downloads', 'woocommerce' ) ), 'id' => 'woocommerce_myaccount_downloads_endpoint', 'type' => 'text', 'default' => 'downloads', @@ -138,7 +138,7 @@ class WC_Settings_Accounts extends WC_Settings_Page { array( 'title' => __( 'Edit Account', 'woocommerce' ), - 'desc' => __( 'Endpoint for the My Account → Edit Account page', 'woocommerce' ), + 'desc' => sprintf( __( 'Endpoint for the My Account → %s page', 'woocommerce' ), __( 'Edit Account', 'woocommerce' ) ), 'id' => 'woocommerce_myaccount_edit_account_endpoint', 'type' => 'text', 'default' => 'edit-account', @@ -147,7 +147,7 @@ class WC_Settings_Accounts extends WC_Settings_Page { array( 'title' => __( 'Addresses', 'woocommerce' ), - 'desc' => __( 'Endpoint for the My Account → Addresses page', 'woocommerce' ), + 'desc' => sprintf( __( 'Endpoint for the My Account → %s page', 'woocommerce' ), __( 'Addresses', 'woocommerce' ) ), 'id' => 'woocommerce_myaccount_edit_address_endpoint', 'type' => 'text', 'default' => 'edit-address', @@ -156,7 +156,7 @@ class WC_Settings_Accounts extends WC_Settings_Page { array( 'title' => __( 'Payment Methods', 'woocommerce' ), - 'desc' => __( 'Endpoint for the My Account → Payment Methods page', 'woocommerce' ), + 'desc' => sprintf( __( 'Endpoint for the My Account → %s page', 'woocommerce' ), __( 'Payment Methods', 'woocommerce' ), 'id' => 'woocommerce_myaccount_payment_methods_endpoint', 'type' => 'text', 'default' => 'payment-methods', @@ -165,7 +165,7 @@ class WC_Settings_Accounts extends WC_Settings_Page { array( 'title' => __( 'Lost Password', 'woocommerce' ), - 'desc' => __( 'Endpoint for the My Account → Lost Password page', 'woocommerce' ), + 'desc' => sprintf( __( 'Endpoint for the My Account → %s page', 'woocommerce' ), __( 'Lost Password', 'woocommerce' ) ), 'id' => 'woocommerce_myaccount_lost_password_endpoint', 'type' => 'text', 'default' => 'lost-password', From 5613985882450ba0c8d24598d91b07937fd862f5 Mon Sep 17 00:00:00 2001 From: Nicola Mustone Date: Tue, 26 Jul 2016 15:47:04 +0200 Subject: [PATCH 090/298] Capitalise all the things --- .../abstracts/abstract-wc-rest-posts-controller.php | 8 ++++---- includes/api/class-wc-rest-customers-controller.php | 8 ++++---- .../api/class-wc-rest-order-notes-controller.php | 12 ++++++------ .../class-wc-rest-product-categories-controller.php | 2 +- .../api/class-wc-rest-product-reviews-controller.php | 6 +++--- includes/api/class-wc-rest-products-controller.php | 2 +- includes/api/class-wc-rest-taxes-controller.php | 10 +++++----- includes/api/class-wc-rest-webhook-deliveries.php | 6 +++--- includes/api/class-wc-rest-webhooks-controller.php | 2 +- 9 files changed, 28 insertions(+), 28 deletions(-) diff --git a/includes/abstracts/abstract-wc-rest-posts-controller.php b/includes/abstracts/abstract-wc-rest-posts-controller.php index 7cd58da1695..6b634c0bf49 100644 --- a/includes/abstracts/abstract-wc-rest-posts-controller.php +++ b/includes/abstracts/abstract-wc-rest-posts-controller.php @@ -152,7 +152,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $post = get_post( $id ); if ( empty( $id ) || empty( $post->ID ) || ! in_array( $post->post_type, $this->get_post_types() ) ) { - return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'Invalid id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_invalid_{$this->post_type}_id", __( 'Invalid ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $data = $this->prepare_item_for_response( $post, $request ); @@ -622,7 +622,7 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { 'validate_callback' => 'rest_validate_request_arg', ); $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific ids.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), 'type' => 'array', 'default' => array(), 'sanitize_callback' => 'wp_parse_id_list', @@ -663,13 +663,13 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { $post_type_obj = get_post_type_object( $this->post_type ); if ( isset( $post_type_obj->hierarchical ) && $post_type_obj->hierarchical ) { $params['parent'] = array( - 'description' => __( 'Limit result set to those of particular parent ids.', 'woocommerce' ), + 'description' => __( 'Limit result set to those of particular parent IDs.', 'woocommerce' ), 'type' => 'array', 'sanitize_callback' => 'wp_parse_id_list', 'default' => array(), ); $params['parent_exclude'] = array( - 'description' => __( 'Limit result set to all items except those of a particular parent id.', 'woocommerce' ), + 'description' => __( 'Limit result set to all items except those of a particular parent ID.', 'woocommerce' ), 'type' => 'array', 'sanitize_callback' => 'wp_parse_id_list', 'default' => array(), diff --git a/includes/api/class-wc-rest-customers-controller.php b/includes/api/class-wc-rest-customers-controller.php index 2a93efc17ae..71e9fb273a2 100644 --- a/includes/api/class-wc-rest-customers-controller.php +++ b/includes/api/class-wc-rest-customers-controller.php @@ -353,7 +353,7 @@ class WC_REST_Customers_Controller extends WC_REST_Controller { $customer = get_userdata( $id ); if ( empty( $id ) || empty( $customer->ID ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $customer = $this->prepare_item_for_response( $customer, $request ); @@ -373,7 +373,7 @@ class WC_REST_Customers_Controller extends WC_REST_Controller { $customer = get_userdata( $id ); if ( ! $customer ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 400 ) ); } if ( ! empty( $request['email'] ) && email_exists( $request['email'] ) && $request['email'] !== $customer->user_email ) { @@ -837,13 +837,13 @@ class WC_REST_Customers_Controller extends WC_REST_Controller { $params['context']['default'] = 'view'; $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific ids.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), 'type' => 'array', 'default' => array(), 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'description' => __( 'Limit result set to specific IDs.', 'woocommerce' ), 'type' => 'array', 'default' => array(), 'sanitize_callback' => 'wp_parse_id_list', diff --git a/includes/api/class-wc-rest-order-notes-controller.php b/includes/api/class-wc-rest-order-notes-controller.php index 3ef25f6b3c8..6c162f19aa2 100644 --- a/includes/api/class-wc-rest-order-notes-controller.php +++ b/includes/api/class-wc-rest-order-notes-controller.php @@ -161,7 +161,7 @@ class WC_REST_Order_Notes_Controller extends WC_REST_Controller { $order = get_post( (int) $request['order_id'] ); if ( empty( $order->post_type ) || $this->post_type !== $order->post_type ) { - return new WP_Error( 'woocommerce_rest_{$this->post_type}_invalid_id', __( 'Invalid order id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_{$this->post_type}_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $args = array( @@ -200,7 +200,7 @@ class WC_REST_Order_Notes_Controller extends WC_REST_Controller { $order = get_post( (int) $request['order_id'] ); if ( empty( $order->post_type ) || $this->post_type !== $order->post_type ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $order = wc_get_order( $order ); @@ -244,13 +244,13 @@ class WC_REST_Order_Notes_Controller extends WC_REST_Controller { $order = get_post( (int) $request['order_id'] ); if ( empty( $order->post_type ) || $this->post_type !== $order->post_type ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $note = get_comment( $id ); if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->ID ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $order_note = $this->prepare_item_for_response( $note, $request ); @@ -277,13 +277,13 @@ class WC_REST_Order_Notes_Controller extends WC_REST_Controller { $order = get_post( (int) $request['order_id'] ); if ( empty( $order->post_type ) || $this->post_type !== $order->post_type ) { - return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_order_invalid_id', __( 'Invalid order ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $note = get_comment( $id ); if ( empty( $id ) || empty( $note ) || intval( $note->comment_post_ID ) !== intval( $order->ID ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $request->set_param( 'context', 'edit' ); diff --git a/includes/api/class-wc-rest-product-categories-controller.php b/includes/api/class-wc-rest-product-categories-controller.php index c4f5269d069..75e02de6863 100644 --- a/includes/api/class-wc-rest-product-categories-controller.php +++ b/includes/api/class-wc-rest-product-categories-controller.php @@ -182,7 +182,7 @@ class WC_REST_Product_Categories_Controller extends WC_REST_Terms_Controller { ), ), 'parent' => array( - 'description' => __( 'The id for the parent of the resource.', 'woocommerce' ), + 'description' => __( 'The ID for the parent of the resource.', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), diff --git a/includes/api/class-wc-rest-product-reviews-controller.php b/includes/api/class-wc-rest-product-reviews-controller.php index 5aa17d914dd..5c7f900bd5e 100644 --- a/includes/api/class-wc-rest-product-reviews-controller.php +++ b/includes/api/class-wc-rest-product-reviews-controller.php @@ -103,7 +103,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $product = get_post( (int) $request['product_id'] ); if ( empty( $product->post_type ) || 'product' !== $product->post_type ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $reviews = get_approved_comments( $product->ID ); @@ -128,13 +128,13 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $product = get_post( (int) $request['product_id'] ); if ( empty( $product->post_type ) || 'product' !== $product->post_type ) { - return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $review = get_comment( $id ); if ( empty( $id ) || empty( $review ) || intval( $review->comment_post_ID ) !== intval( $product->ID ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $delivery = $this->prepare_item_for_response( $review, $request ); diff --git a/includes/api/class-wc-rest-products-controller.php b/includes/api/class-wc-rest-products-controller.php index 3bded5e0649..084430e5d3e 100644 --- a/includes/api/class-wc-rest-products-controller.php +++ b/includes/api/class-wc-rest-products-controller.php @@ -1732,7 +1732,7 @@ class WC_REST_Products_Controller extends WC_REST_Posts_Controller { $post = get_post( $id ); if ( empty( $id ) || empty( $post->ID ) || ! in_array( $post->post_type, $this->get_post_types() ) ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid post id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid post ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $supports_trash = EMPTY_TRASH_DAYS > 0; diff --git a/includes/api/class-wc-rest-taxes-controller.php b/includes/api/class-wc-rest-taxes-controller.php index 48526422176..321b6fab1c0 100644 --- a/includes/api/class-wc-rest-taxes-controller.php +++ b/includes/api/class-wc-rest-taxes-controller.php @@ -389,7 +389,7 @@ class WC_REST_Taxes_Controller extends WC_REST_Controller { $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax_obj ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $tax = $this->prepare_item_for_response( $tax_obj, $request ); @@ -409,7 +409,7 @@ class WC_REST_Taxes_Controller extends WC_REST_Controller { $tax_obj = WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax_obj ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $tax = $this->create_or_update_tax( $request, $tax_obj ); @@ -452,7 +452,7 @@ class WC_REST_Taxes_Controller extends WC_REST_Controller { $tax = WC_Tax::_get_tax_rate( $id, OBJECT ); if ( empty( $id ) || empty( $tax ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 400 ) ); } $request->set_param( 'context', 'edit' ); @@ -647,13 +647,13 @@ class WC_REST_Taxes_Controller extends WC_REST_Controller { $params['context']['default'] = 'view'; $params['exclude'] = array( - 'description' => __( 'Ensure result set excludes specific ids.', 'woocommerce' ), + 'description' => __( 'Ensure result set excludes specific IDs.', 'woocommerce' ), 'type' => 'array', 'default' => array(), 'sanitize_callback' => 'wp_parse_id_list', ); $params['include'] = array( - 'description' => __( 'Limit result set to specific ids.', 'woocommerce' ), + 'description' => __( 'Limit result set to specific IDs.', 'woocommerce' ), 'type' => 'array', 'default' => array(), 'sanitize_callback' => 'wp_parse_id_list', diff --git a/includes/api/class-wc-rest-webhook-deliveries.php b/includes/api/class-wc-rest-webhook-deliveries.php index 255ec0ad7f2..f11400d6b64 100644 --- a/includes/api/class-wc-rest-webhook-deliveries.php +++ b/includes/api/class-wc-rest-webhook-deliveries.php @@ -103,7 +103,7 @@ class WC_REST_Webhook_Deliveries_Controller extends WC_REST_Controller { $webhook = new WC_Webhook( (int) $request['webhook_id'] ); if ( empty( $webhook->post_data->post_type ) || 'shop_webhook' !== $webhook->post_data->post_type ) { - return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $logs = $webhook->get_delivery_logs(); @@ -129,13 +129,13 @@ class WC_REST_Webhook_Deliveries_Controller extends WC_REST_Controller { $webhook = new WC_Webhook( (int) $request['webhook_id'] ); if ( empty( $webhook->post_data->post_type ) || 'shop_webhook' !== $webhook->post_data->post_type ) { - return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_webhook_invalid_id', __( 'Invalid webhook ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $log = $webhook->get_delivery_log( $id ); if ( empty( $id ) || empty( $log ) ) { - return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $delivery = $this->prepare_item_for_response( (object) $log, $request ); diff --git a/includes/api/class-wc-rest-webhooks-controller.php b/includes/api/class-wc-rest-webhooks-controller.php index 9b3920c1310..1d98c036230 100644 --- a/includes/api/class-wc-rest-webhooks-controller.php +++ b/includes/api/class-wc-rest-webhooks-controller.php @@ -302,7 +302,7 @@ class WC_REST_Webhooks_Controller extends WC_REST_Posts_Controller { $post = get_post( $id ); if ( empty( $id ) || empty( $post->ID ) || $this->post_type !== $post->post_type ) { - return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid post id.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( "woocommerce_rest_{$this->post_type}_invalid_id", __( 'Invalid post ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $request->set_param( 'context', 'edit' ); From 0aed3bd8b8104b933a99bc6bbddca8ee97dc0d78 Mon Sep 17 00:00:00 2001 From: Nicola Mustone Date: Tue, 26 Jul 2016 16:13:09 +0200 Subject: [PATCH 091/298] missing ) --- includes/admin/settings/class-wc-settings-accounts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/admin/settings/class-wc-settings-accounts.php b/includes/admin/settings/class-wc-settings-accounts.php index ece3e3f4e15..e5e5e6b81fc 100644 --- a/includes/admin/settings/class-wc-settings-accounts.php +++ b/includes/admin/settings/class-wc-settings-accounts.php @@ -156,7 +156,7 @@ class WC_Settings_Accounts extends WC_Settings_Page { array( 'title' => __( 'Payment Methods', 'woocommerce' ), - 'desc' => sprintf( __( 'Endpoint for the My Account → %s page', 'woocommerce' ), __( 'Payment Methods', 'woocommerce' ), + 'desc' => sprintf( __( 'Endpoint for the My Account → %s page', 'woocommerce' ), __( 'Payment Methods', 'woocommerce' ) ), 'id' => 'woocommerce_myaccount_payment_methods_endpoint', 'type' => 'text', 'default' => 'payment-methods', From b5fa1e5756548e989297ffc3fe79540de7d581c0 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 26 Jul 2016 15:19:11 +0100 Subject: [PATCH 092/298] More arrays --- includes/libraries/class-emogrifier.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/includes/libraries/class-emogrifier.php b/includes/libraries/class-emogrifier.php index e3014d6e1f9..e0466a3f1e4 100644 --- a/includes/libraries/class-emogrifier.php +++ b/includes/libraries/class-emogrifier.php @@ -569,7 +569,7 @@ class Emogrifier // we don't try to call removeChild on a nonexistent child node /** @var \DOMNode $node */ foreach ($nodesWithStyleDisplayNone as $node) { - if ($node->parentNode && is_callable([$node->parentNode, 'removeChild'])) { + if ($node->parentNode && is_callable( array( $node->parentNode, 'removeChild' ) ) ) { $node->parentNode->removeChild($node); } } @@ -838,7 +838,7 @@ class Emogrifier $cleanedCss = preg_replace($search, '', $cssForAllowedMediaTypes); - return ['css' => $cleanedCss, 'media' => $media]; + return array( 'css' => $cleanedCss, 'media' => $media ); } /** @@ -1045,12 +1045,12 @@ class Emogrifier $xpathWithIdAttributeMatchers = preg_replace_callback( self::ID_ATTRIBUTE_MATCHER, - [$this, 'matchIdAttributes'], + array( $this, 'matchIdAttributes' ), $roughXpath ); $xpathWithIdAttributeAndClassMatchers = preg_replace_callback( self::CLASS_ATTRIBUTE_MATCHER, - [$this, 'matchClassAttributes'], + array( $this, 'matchClassAttributes' ), $xpathWithIdAttributeMatchers ); @@ -1058,12 +1058,12 @@ class Emogrifier // When we required PHP 5.3, we could do this with closures. $xpathWithIdAttributeAndClassMatchers = preg_replace_callback( '/([^\\/]+):nth-child\\(\\s*(odd|even|[+\\-]?\\d|[+\\-]?\\d?n(\\s*[+\\-]\\s*\\d)?)\\s*\\)/i', - [$this, 'translateNthChild'], + array( $this, 'translateNthChild' ), $xpathWithIdAttributeAndClassMatchers ); $finalXpath = preg_replace_callback( '/([^\\/]+):nth-of-type\\(\s*(odd|even|[+\\-]?\\d|[+\\-]?\\d?n(\\s*[+\\-]\\s*\\d)?)\\s*\\)/i', - [$this, 'translateNthOfType'], + array( $this, 'translateNthOfType' ), $xpathWithIdAttributeAndClassMatchers ); @@ -1193,7 +1193,7 @@ class Emogrifier if ($multiplier === '') { $multiplier = 1; } elseif ($multiplier === '0') { - return [self::INDEX => $index]; + return array( self::INDEX => $index ); } else { $multiplier = (int) $multiplier; } @@ -1202,7 +1202,7 @@ class Emogrifier $index += abs($multiplier); } - return [self::MULTIPLIER => $multiplier, self::INDEX => $index]; + return array( self::MULTIPLIER => $multiplier, self::INDEX => $index ); } /** From b09b12f3afdfab8341ad228e0e4c355e50187d1c Mon Sep 17 00:00:00 2001 From: Enrico Deleo Date: Tue, 26 Jul 2016 16:27:21 +0200 Subject: [PATCH 093/298] converting shortsyntax array to legacy array() for PHP < 5.4 --- includes/libraries/class-emogrifier.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/libraries/class-emogrifier.php b/includes/libraries/class-emogrifier.php index 77ee47a09c1..b085ab278b7 100644 --- a/includes/libraries/class-emogrifier.php +++ b/includes/libraries/class-emogrifier.php @@ -569,7 +569,7 @@ class Emogrifier // we don't try to call removeChild on a nonexistent child node /** @var \DOMNode $node */ foreach ($nodesWithStyleDisplayNone as $node) { - if ($node->parentNode && is_callable([$node->parentNode, 'removeChild'])) { + if ( $node->parentNode && is_callable( array($node->parentNode, 'removeChild') ) ) { $node->parentNode->removeChild($node); } } From b56abded633f953f76a9bf28fde1f4f22edbc152 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 26 Jul 2016 15:52:14 +0100 Subject: [PATCH 094/298] Another emogrifier.php array --- includes/libraries/class-emogrifier.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/libraries/class-emogrifier.php b/includes/libraries/class-emogrifier.php index e0466a3f1e4..edef10b86f8 100644 --- a/includes/libraries/class-emogrifier.php +++ b/includes/libraries/class-emogrifier.php @@ -1172,12 +1172,12 @@ class Emogrifier if (in_array(strtolower($match[2]), array( 'even','odd' ), true)) { // we have "even" or "odd" $index = strtolower($match[2]) === 'even' ? 0 : 1; - return [self::MULTIPLIER => 2, self::INDEX => $index]; + return array( self::MULTIPLIER => 2, self::INDEX => $index ); } if (stripos($match[2], 'n') === false) { // if there is a multiplier $index = (int) str_replace(' ', '', $match[2]); - return [self::INDEX => $index]; + return array( self::INDEX => $index ); } if (isset($match[3])) { From 05539282fb71e4bb21227ea7e4777cef4e082c43 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 26 Jul 2016 16:34:17 +0100 Subject: [PATCH 095/298] 5.2 compat --- includes/libraries/class-emogrifier.php | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/includes/libraries/class-emogrifier.php b/includes/libraries/class-emogrifier.php index edef10b86f8..fec70553caf 100644 --- a/includes/libraries/class-emogrifier.php +++ b/includes/libraries/class-emogrifier.php @@ -203,12 +203,12 @@ class Emogrifier * * @return string * - * @throws \BadMethodCallException + * @throws BadMethodCallException */ public function emogrify() { if ($this->html === '') { - throw new \BadMethodCallException('Please set some HTML first before calling emogrify.', 1390393096); + throw new BadMethodCallException('Please set some HTML first before calling emogrify.', 1390393096); } $xmlDocument = $this->createXmlDocument(); @@ -225,12 +225,12 @@ class Emogrifier * * @return string * - * @throws \BadMethodCallException + * @throws BadMethodCallException */ public function emogrifyBodyContent() { if ($this->html === '') { - throw new \BadMethodCallException('Please set some HTML first before calling emogrify.', 1390393096); + throw new BadMethodCallException('Please set some HTML first before calling emogrify.', 1390393096); } $xmlDocument = $this->createXmlDocument(); @@ -575,6 +575,10 @@ class Emogrifier } } + private function normalizeStyleAttributes_callback( $m ) { + return strtolower( $m[0] ); + } + /** * Normalizes the value of the "style" attribute and saves it. * @@ -586,9 +590,7 @@ class Emogrifier { $normalizedOriginalStyle = preg_replace_callback( '/[A-z\\-]+(?=\\:)/S', - function (array $m) { - return strtolower($m[0]); - }, + array( $this, 'normalizeStyleAttributes_callback' ), $node->getAttribute('style') ); @@ -867,7 +869,7 @@ class Emogrifier * * @return string the unified HTML * - * @throws \BadMethodCallException + * @throws BadMethodCallException */ private function getUnifiedHtml() { From f84d2e59545d6c96dddc73fbc878c50528bdb879 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 26 Jul 2016 16:50:23 +0100 Subject: [PATCH 096/298] 5.2 changes --- includes/libraries/class-emogrifier.php | 125 ++++++++++++------------ 1 file changed, 63 insertions(+), 62 deletions(-) diff --git a/includes/libraries/class-emogrifier.php b/includes/libraries/class-emogrifier.php index fec70553caf..357ee24f772 100644 --- a/includes/libraries/class-emogrifier.php +++ b/includes/libraries/class-emogrifier.php @@ -111,7 +111,7 @@ class Emogrifier /** * the visited nodes with the XPath paths as array keys * - * @var \DOMElement[] + * @var DoMElement[] */ private $visitedNodes = array(); @@ -236,7 +236,7 @@ class Emogrifier $xmlDocument = $this->createXmlDocument(); $this->process($xmlDocument); - $innerDocument = new \DOMDocument(); + $innerDocument = new DoMDocument(); foreach ($xmlDocument->documentElement->getElementsByTagName('body')->item(0)->childNodes as $childNode) { $innerDocument->appendChild($innerDocument->importNode($childNode, true)); } @@ -249,13 +249,13 @@ class Emogrifier * * This method places the CSS inline. * - * @param \DOMDocument $xmlDocument + * @param DoMDocument $xmlDocument * * @return void */ - protected function process(\DOMDocument $xmlDocument) + protected function process(DoMDocument $xmlDocument) { - $xpath = new \DOMXPath($xmlDocument); + $xpath = new DoMXPath($xmlDocument); $this->clearAllCaches(); // Before be begin processing the CSS file, parse the document and normalize all existing CSS attributes. @@ -266,7 +266,7 @@ class Emogrifier $nodesWithStyleAttributes = $xpath->query('//*[@style]'); if ($nodesWithStyleAttributes !== false) { - /** @var \DOMElement $node */ + /** @var DoMElement $node */ foreach ($nodesWithStyleAttributes as $node) { if ($this->isInlineStyleAttributesParsingEnabled) { $this->normalizeStyleAttributes($node); @@ -295,7 +295,7 @@ class Emogrifier continue; } - /** @var \DOMElement $node */ + /** @var DoMElement $node */ foreach ($nodesMatchingCssSelectors as $node) { if (in_array($node, $excludedNodes, true)) { continue; @@ -442,7 +442,7 @@ class Emogrifier self::CACHE_KEY_COMBINED_STYLES, ); if (!in_array($key, $allowedCacheKeys, true)) { - throw new \InvalidArgumentException('Invalid cache key: ' . $key, 1391822035); + throw new InvalidArgumentException('Invalid cache key: ' . $key, 1391822035); } $this->caches[$key] = array(); @@ -552,11 +552,11 @@ class Emogrifier * not attribute values. Consequently, we need to translate() the letters that would be in 'NONE' ("NOE") * to lowercase. * - * @param \DOMXPath $xpath + * @param DoMXPath $xpath * * @return void */ - private function removeInvisibleNodes(\DOMXPath $xpath) + private function removeInvisibleNodes(DoMXPath $xpath) { $nodesWithStyleDisplayNone = $xpath->query( '//*[contains(translate(translate(@style," ",""),"NOE","noe"),"display:none")]' @@ -567,7 +567,7 @@ class Emogrifier // The checks on parentNode and is_callable below ensure that if we've deleted the parent node, // we don't try to call removeChild on a nonexistent child node - /** @var \DOMNode $node */ + /** @var DoMNode $node */ foreach ($nodesWithStyleDisplayNone as $node) { if ($node->parentNode && is_callable( array( $node->parentNode, 'removeChild' ) ) ) { $node->parentNode->removeChild($node); @@ -582,11 +582,11 @@ class Emogrifier /** * Normalizes the value of the "style" attribute and saves it. * - * @param \DOMElement $node + * @param DoMElement $node * * @return void */ - private function normalizeStyleAttributes(\DOMElement $node) + private function normalizeStyleAttributes(DoMElement $node) { $normalizedOriginalStyle = preg_replace_callback( '/[A-z\\-]+(?=\\:)/S', @@ -664,13 +664,13 @@ class Emogrifier /** * Applies $css to $xmlDocument, limited to the media queries that actually apply to the document. * - * @param \DOMDocument $xmlDocument the document to match against - * @param \DOMXPath $xpath + * @param DoMDocument $xmlDocument the document to match against + * @param DoMXPath $xpath * @param string $css a string of CSS * * @return void */ - private function copyCssWithMediaToStyleNode(\DOMDocument $xmlDocument, \DOMXPath $xpath, $css) + private function copyCssWithMediaToStyleNode(DoMDocument $xmlDocument, DoMXPath $xpath, $css) { if ($css === '') { return; @@ -713,12 +713,12 @@ class Emogrifier /** * Checks whether there is at least one matching element for $cssSelector. * - * @param \DOMXPath $xpath + * @param DoMXPath $xpath * @param string $cssSelector * * @return bool */ - private function existsMatchForCssSelector(\DOMXPath $xpath, $cssSelector) + private function existsMatchForCssSelector(DoMXPath $xpath, $cssSelector) { $nodesMatchingSelector = $xpath->query($this->translateCssToXpath($cssSelector)); @@ -728,11 +728,11 @@ class Emogrifier /** * Returns CSS content. * - * @param \DOMXPath $xpath + * @param DoMXPath $xpath * * @return string */ - private function getCssFromAllStyleNodes(\DOMXPath $xpath) + private function getCssFromAllStyleNodes(DoMXPath $xpath) { $styleNodes = $xpath->query('//style'); @@ -741,7 +741,7 @@ class Emogrifier } $css = ''; - /** @var \DOMNode $styleNode */ + /** @var DoMNode $styleNode */ foreach ($styleNodes as $styleNode) { $css .= "\n\n" . $styleNode->nodeValue; $styleNode->parentNode->removeChild($styleNode); @@ -757,12 +757,12 @@ class Emogrifier * * @see https://github.com/jjriv/emogrifier/issues/103 * - * @param \DOMDocument $document + * @param DoMDocument $document * @param string $css * * @return void */ - protected function addStyleElementToDocument(\DOMDocument $document, $css) + protected function addStyleElementToDocument(DoMDocument $document, $css) { $styleElement = $document->createElement('style', $css); $styleAttribute = $document->createAttribute('type'); @@ -776,11 +776,11 @@ class Emogrifier /** * Returns the existing or creates a new head element in $document. * - * @param \DOMDocument $document + * @param DoMDocument $document * - * @return \DOMNode the head element + * @return DoMNode the head element */ - private function getOrCreateHeadElement(\DOMDocument $document) + private function getOrCreateHeadElement(DoMDocument $document) { $head = $document->getElementsByTagName('head')->item(0); @@ -793,15 +793,19 @@ class Emogrifier return $head; } + private function splitCssAndMediaQuery_callback() { + + } + /** * Splits input CSS code to an array where: * - * - key "css" will be contains clean CSS code - * - key "media" will be contains all valuable media queries + * - key "css" will be contains clean CSS code. + * - key "media" will be contains all valuable media queries. * * Example: * - * The CSS code + * The CSS code. * * "@import "file.css"; h1 { color:red; } @media { h1 {}} @media tv { h1 {}}" * @@ -811,46 +815,41 @@ class Emogrifier * "media" => "@media { h1 {}}" * * @param string $css - * - * @return string[] + * @return array */ - private function splitCssAndMediaQuery($css) - { - $cssWithoutComments = preg_replace('/\\/\\*.*\\*\\//sU', '', $css); - - $mediaTypesExpression = ''; - if (!empty($this->allowedMediaTypes)) { - $mediaTypesExpression = '|' . implode('|', array_keys($this->allowedMediaTypes)); - } - - $media = ''; - $cssForAllowedMediaTypes = preg_replace_callback( - '#@media\\s+(?:only\\s)?(?:[\\s{\\(]' . $mediaTypesExpression . ')\\s?[^{]+{.*}\\s*}\\s*#misU', - function ($matches) use (&$media) { - $media .= $matches[0]; - }, - $cssWithoutComments - ); - + private function splitCssAndMediaQuery($css) { + $css = preg_replace_callback( '#@media\\s+(?:only\\s)?(?:[\\s{\(]|screen|all)\\s?[^{]+{.*}\\s*}\\s*#misU', array( $this, '_media_concat' ), $css ); // filter the CSS $search = array( - 'import directives' => '/^\\s*@import\\s[^;]+;/misU', - 'remaining media enclosures' => '/^\\s*@media\\s[^{]+{(.*)}\\s*}\\s/misU', + // get rid of css comment code + '/\\/\\*.*\\*\\//sU', + // strip out any import directives + '/^\\s*@import\\s[^;]+;/misU', + // strip remains media enclosures + '/^\\s*@media\\s[^{]+{(.*)}\\s*}\\s/misU', ); + $replace = array( + '', + '', + '', + ); + // clean CSS before output + $css = preg_replace($search, $replace, $css); + return array('css' => $css, 'media' => self::$_media); + } - $cleanedCss = preg_replace($search, '', $cssForAllowedMediaTypes); - - return array( 'css' => $cleanedCss, 'media' => $media ); + private function _media_concat( $matches ) { + self::$_media .= $matches[0]; } /** * Creates a DOMDocument instance with the current HTML. * - * @return \DOMDocument + * @return DoMDocument */ private function createXmlDocument() { - $xmlDocument = new \DOMDocument; + $xmlDocument = new DoMDocument; $xmlDocument->encoding = 'UTF-8'; $xmlDocument->strictErrorChecking = false; $xmlDocument->formatOutput = true; @@ -1000,6 +999,10 @@ class Emogrifier return $this->caches[self::CACHE_KEY_SELECTOR][$selectorKey]; } + private function translateCssToXpath_callback( $matches ) { + return strtolower($matches[0]); + } + /** * Maps a CSS selector to an XPath query string. * @@ -1014,9 +1017,7 @@ class Emogrifier $paddedSelector = ' ' . $cssSelector . ' '; $lowercasePaddedSelector = preg_replace_callback( '/\\s+\\w+\\s+/', - function (array $matches) { - return strtolower($matches[0]); - }, + array( $this, 'translateCssToXpath_callback' ), $paddedSelector ); $trimmedLowercaseSelector = trim($lowercasePaddedSelector); @@ -1253,11 +1254,11 @@ class Emogrifier /** * Find the nodes that are not to be emogrified. * - * @param \DOMXPath $xpath + * @param DoMXPath $xpath * - * @return \DOMElement[] + * @return DoMElement[] */ - private function getNodesToExclude(\DOMXPath $xpath) + private function getNodesToExclude(DoMXPath $xpath) { $excludedNodes = array(); foreach (array_keys($this->excludedSelectors) as $selectorToExclude) { From 374b1ff8770c9d2c54f226efdc94029bea124288 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 26 Jul 2016 17:03:16 +0100 Subject: [PATCH 097/298] missing _media --- includes/libraries/class-emogrifier.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/libraries/class-emogrifier.php b/includes/libraries/class-emogrifier.php index 357ee24f772..abd0404b492 100644 --- a/includes/libraries/class-emogrifier.php +++ b/includes/libraries/class-emogrifier.php @@ -151,6 +151,8 @@ class Emogrifier */ private $shouldKeepInvisibleNodes = true; + public static $_media = ''; + /** * The constructor. * @@ -211,6 +213,7 @@ class Emogrifier throw new BadMethodCallException('Please set some HTML first before calling emogrify.', 1390393096); } + self::$_media = ''; // reset $xmlDocument = $this->createXmlDocument(); $this->process($xmlDocument); From 8c46a74cb9938be73b94d04045d2d2e7432589e1 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Thu, 3 Mar 2016 12:07:20 -0800 Subject: [PATCH 098/298] Settings API Doc - To be removed later. --- settings-api.MD | 192 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 settings-api.MD diff --git a/settings-api.MD b/settings-api.MD new file mode 100644 index 00000000000..1fb4237cccc --- /dev/null +++ b/settings-api.MD @@ -0,0 +1,192 @@ +# Settings API Proposal + +The idea of this proposal is to handle custom settings for both WooCommerce > Settings pages and settings panels for "metaboxes" (product data, coupon data). + +All settings are registered with PHP filters. Not through the API. The API is only for retrieving settings and updating them. + +## GET /settings/sections + +Dedicated settings sections/pages (for screens currently under WooCommerce > Settings) +For example we might have 'General', 'Products', 'Tax', 'Shipping', 'Checkout', 'Accounts', 'Emails', and 'API'. Adding a new page to this area should automatically create a new tab in the UI. + +Metaboxes (Coupon Data or Product Data for example) are also considered sections, and will be listed by this endpoint. They won't be automatically displayed anywhere. + +Here is how they would be registered: + + // Default WooCommerce Setting Sections + apply_filters( 'woocommerce_settings_sections', array( + array( + 'id' => 'general', // ID (required) + 'type' => 'page', // page or metabox + 'label' => __( 'General', 'woocommerce' ), // human readable label (required) + 'description' => '', // human readable description (optional) + ), + array( + 'id' => 'products', + 'type' => 'page', // page or metabox + 'label' => __( 'Products', 'woocommerce' ), + 'description' => '', + ), + ..... + ) ); + +To add a new top level tab/page to WooCommerce > Settings + + add_filter( 'woocommerce_settings_sections', function( $pages ) { + $pages[] = array( + 'id' => 'bookings', + 'type' => 'page', + 'label' => __( 'Bookings', 'woocommerce-bookings' ), + 'description' => __( 'Bookings settings.', 'woocommerce-bookings' ), + ); + return $pages; + } ); + +The actual endpoint would return a JSON object like so: + + [ + { + "id": "general", + "type": "page", + "label": "General", + "description": "" + }, + { + "id": "products", + "type": "page", + "label": "Products", + "description": "" + }, + { + "id": "coupon-data", + "type": "metabox", + "label": "Coupon Data", + "description": "" + } + ] + +There should be a filter for this endpoint (?type=page) to get only sections of a specific type. + +![](https://cldup.com/HHAZ-JBOxU.thumb.png) + +## GET /settings/sections/$section/ + +Lists all settings "groups" on a specific page. + +On the 'Products' page this would be 'General', 'Display', 'Inventory', and 'Downloadable Products'. + +Metaboxes won't need to use this. + +![](https://cldup.com/qXlfpvItr6-3000x3000.png) + +Here is how you would register groups: + + // products would be replaced with whatever page ID you want to register for. These filters automatically exist after registering a page + add_filter( 'woocommerce_settings_groups_products', function( $groups ) { + $groups[] = array( + 'id' => 'general', + 'label' => __( 'General', 'woocommerce' ), // human readable label (required) + 'description' => '', // human readable description (optional) + ); + $groups[] = array( + 'id' => 'display', + 'label' => __( 'Display', 'woocommerce' ), + 'description' => '', + ); + $groups[] = array( + 'id' => 'inventory', + 'label' => __( 'Inventory', 'woocommerce' ), + 'description' => '', + ); + return $groups; + } ); + +To retrive the groups for the 'products' page: + +GET /settings/sections/products + + { + "label": "Products", + "description": "", + "groups": [ + { + "id": "general", + "label": "General", + "description": "" + }, + { + "id": "display", + "label": "Display", + "description": "" + } + ] + } + + +## /settings/$identifer + +Gets the actual settings to be displayed in a specific area. You can load settings for a specific group, or for a specific metabox. + +GET /settings/page:products:general would return settings for Settings > Products > General. +GET /settings/metabox:coupons would return settings for Coupons > Add New Coupon > Coupon Data metabox. + +To register settings: + + // The filter (page_products_general) should match the identifer for the area we are loading settings for. + apply_filters( 'woocommerce_settings_page_products_general', array( + array( + 'label' => __( 'Measurements', 'woocommerce' ), + 'type' => 'title', + 'id' => 'product_measurement_options' + ), + array( + 'label' => __( 'Weight Unit', 'woocommerce' ), + 'description' => __( 'This controls what unit you will define weights in.', 'woocommerce' ), + 'id' => 'woocommerce_weight_unit', + 'default' => 'kg', + 'type' => 'select', + 'options' => array( + 'kg' => __( 'kg', 'woocommerce' ), + 'g' => __( 'g', 'woocommerce' ), + 'lbs' => __( 'lbs', 'woocommerce' ), + 'oz' => __( 'oz', 'woocommerce' ), + ), + ) + ) ); + +Settings response: + + [ + { + "label": "Measurements", + "type": "title", + "id": "product_measurement_options" + }, + { + "label": "Weight Unit", + "description": "This controls what unit you will define weights in.", + "id": "woocommerce_weight_unit", + "default": "kg", + "type": "select", + "options": { + "kg": "kg", + "g": "g", + "lbs": "lbs", + "oz": "oz" + } + } + ] + +We should different form input types for 'type', text, textarea, select, radio, checkbox, ... + +## GET /settings/$identifer/$setting + +Get data for an individual setting. + +## PUT /settings/$identifer/$setting + +Update a setting by passing a new 'value' in the body. A success response will be returned. + +## PUT /settings/$identifer + +Update multiple settings at the same time with key => value pairs. A success response will be returned. From a9bb98887362739bab11074c7e5b02d515a7bec4 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 7 Mar 2016 08:46:58 -0800 Subject: [PATCH 099/298] Initial /settings API controller and /settings/locations route. Loads the WP-API and registers our namespace temporarily until WP-API is loaded by WC core. --- includes/api/wc-rest-settings-controller.php | 90 +++++++++ includes/class-wc-api.php | 3 + includes/vendor/wp-api-functions.php | 199 +++++++++++++++++++ tests/unit-tests/api/settings.php | 11 + 4 files changed, 303 insertions(+) create mode 100644 includes/api/wc-rest-settings-controller.php create mode 100644 includes/vendor/wp-api-functions.php create mode 100644 tests/unit-tests/api/settings.php diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php new file mode 100644 index 00000000000..c9a70867875 --- /dev/null +++ b/includes/api/wc-rest-settings-controller.php @@ -0,0 +1,90 @@ +rest_base . '/locations', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_locations' ), + 'permission_callback' => array( $this, 'permissions_check' ), + 'args' => $this->get_locations_params(), + ), + 'schema' => array( $this, 'get_locations_schema' ), + ) ); + + } + + /** + * Makes sure the current user has access to the settings APIs. + * @since 2.7.0 + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function permissions_check( $request ) { + return true; + } + + /* + |-------------------------------------------------------------------------- + | /settings/locations + |-------------------------------------------------------------------------- + | Returns a list of "settings" locations so all settings for a particular page + | or location can be properly loaded. + */ + + /** + * Get all settings locations. + * @since 2.7.0 + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_locations( $request ) { + $response = rest_ensure_response( array() ); + return $response; + } + + /** + * Get supported query parameters for locations. + * @since 2.7.0 + * @return array + */ + public function get_locations_params() { + $query_params = parent::get_collection_params(); + $query_params['context']['default'] = 'view'; + return $query_params; + } + + /** + * Get the locations chema, conforming to JSON Schema + * @since 2.7.0 + * @return array + */ + public function get_locations_schema() { + + } + +} diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 59af72ee530..81d21796a86 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -144,6 +144,7 @@ class WC_API extends WC_Legacy_API { include_once( 'abstracts/abstract-wc-rest-controller.php' ); include_once( 'abstracts/abstract-wc-rest-posts-controller.php' ); include_once( 'abstracts/abstract-wc-rest-terms-controller.php' ); + include_once( 'abstracts/abstract-wc-settings-api.php' ); // REST API controllers. include_once( 'api/class-wc-rest-coupons-controller.php' ); @@ -162,6 +163,7 @@ class WC_API extends WC_Legacy_API { include_once( 'api/class-wc-rest-report-sales-controller.php' ); include_once( 'api/class-wc-rest-report-top-sellers-controller.php' ); include_once( 'api/class-wc-rest-reports-controller.php' ); + include_once( 'api/wc-rest-settings-controller.php' ); include_once( 'api/class-wc-rest-tax-classes-controller.php' ); include_once( 'api/class-wc-rest-taxes-controller.php' ); include_once( 'api/class-wc-rest-webhook-deliveries.php' ); @@ -190,6 +192,7 @@ class WC_API extends WC_Legacy_API { 'WC_REST_Report_Sales_Controller', 'WC_REST_Report_Top_Sellers_Controller', 'WC_REST_Reports_Controller', + 'WC_Rest_Settings_Controller', 'WC_REST_Tax_Classes_Controller', 'WC_REST_Taxes_Controller', 'WC_REST_Webhook_Deliveries_Controller', diff --git a/includes/vendor/wp-api-functions.php b/includes/vendor/wp-api-functions.php new file mode 100644 index 00000000000..90c0713a229 --- /dev/null +++ b/includes/vendor/wp-api-functions.php @@ -0,0 +1,199 @@ + null, + 'update_callback' => null, + 'schema' => null, + ); + + $args = wp_parse_args( $args, $defaults ); + + global $wp_rest_additional_fields; + + $object_types = (array) $object_type; + + foreach ( $object_types as $object_type ) { + $wp_rest_additional_fields[ $object_type ][ $attribute ] = $args; + } + } +} + +if ( ! function_exists( 'register_api_field' ) ) { + /** + * Backwards compat shim + */ + function register_api_field( $object_type, $attributes, $args = array() ) { + _deprecated_function( 'register_api_field', 'WPAPI-2.0', 'register_rest_field' ); + register_rest_field( $object_type, $attributes, $args ); + } +} + +if ( ! function_exists( 'rest_validate_request_arg' ) ) { + /** + * Validate a request argument based on details registered to the route. + * + * @param mixed $value + * @param WP_REST_Request $request + * @param string $param + * @return WP_Error|boolean + */ + function rest_validate_request_arg( $value, $request, $param ) { + + $attributes = $request->get_attributes(); + if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { + return true; + } + $args = $attributes['args'][ $param ]; + + if ( ! empty( $args['enum'] ) ) { + if ( ! in_array( $value, $args['enum'] ) ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not one of %s' ), $param, implode( ', ', $args['enum'] ) ) ); + } + } + + if ( 'integer' === $args['type'] && ! is_numeric( $value ) ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not of type %s' ), $param, 'integer' ) ); + } + + if ( 'string' === $args['type'] && ! is_string( $value ) ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not of type %s' ), $param, 'string' ) ); + } + + if ( isset( $args['format'] ) ) { + switch ( $args['format'] ) { + case 'date-time' : + if ( ! rest_parse_date( $value ) ) { + return new WP_Error( 'rest_invalid_date', __( 'The date you provided is invalid.' ) ); + } + break; + + case 'email' : + if ( ! is_email( $value ) ) { + return new WP_Error( 'rest_invalid_email', __( 'The email address you provided is invalid.' ) ); + } + break; + } + } + + if ( in_array( $args['type'], array( 'numeric', 'integer' ) ) && ( isset( $args['minimum'] ) || isset( $args['maximum'] ) ) ) { + if ( isset( $args['minimum'] ) && ! isset( $args['maximum'] ) ) { + if ( ! empty( $args['exclusiveMinimum'] ) && $value <= $args['minimum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be greater than %d (exclusive)' ), $param, $args['minimum'] ) ); + } else if ( empty( $args['exclusiveMinimum'] ) && $value < $args['minimum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be greater than %d (inclusive)' ), $param, $args['minimum'] ) ); + } + } else if ( isset( $args['maximum'] ) && ! isset( $args['minimum'] ) ) { + if ( ! empty( $args['exclusiveMaximum'] ) && $value >= $args['maximum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be less than %d (exclusive)' ), $param, $args['maximum'] ) ); + } else if ( empty( $args['exclusiveMaximum'] ) && $value > $args['maximum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be less than %d (inclusive)' ), $param, $args['maximum'] ) ); + } + } else if ( isset( $args['maximum'] ) && isset( $args['minimum'] ) ) { + if ( ! empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) { + if ( $value >= $args['maximum'] || $value <= $args['minimum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (exclusive) and %d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); + } + } else if ( empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) { + if ( $value >= $args['maximum'] || $value < $args['minimum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (inclusive) and %d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); + } + } else if ( ! empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) { + if ( $value > $args['maximum'] || $value <= $args['minimum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (exclusive) and %d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); + } + } else if ( empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) { + if ( $value > $args['maximum'] || $value < $args['minimum'] ) { + return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (inclusive) and %d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); + } + } + } + } + + return true; + } +} + +if ( ! function_exists( 'rest_sanitize_request_arg' ) ) { + /** + * Sanitize a request argument based on details registered to the route. + * + * @param mixed $value + * @param WP_REST_Request $request + * @param string $param + * @return mixed + */ + function rest_sanitize_request_arg( $value, $request, $param ) { + + $attributes = $request->get_attributes(); + if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { + return $value; + } + $args = $attributes['args'][ $param ]; + + if ( 'integer' === $args['type'] ) { + return (int) $value; + } + + if ( isset( $args['format'] ) ) { + switch ( $args['format'] ) { + case 'date-time' : + return sanitize_text_field( $value ); + + case 'email' : + /* + * sanitize_email() validates, which would be unexpected + */ + return sanitize_text_field( $value ); + + case 'uri' : + return esc_url_raw( $value ); + } + } + + return $value; + } + +} diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php new file mode 100644 index 00000000000..86c44b50e74 --- /dev/null +++ b/tests/unit-tests/api/settings.php @@ -0,0 +1,11 @@ + Date: Mon, 7 Mar 2016 10:24:03 -0800 Subject: [PATCH 100/298] Make /settings/locations work properly. Add skeleton for tests and add register_routes test. --- includes/api/wc-rest-settings-controller.php | 63 +++++++++++++++++-- tests/bootstrap.php | 7 +++ ...class-wp-test-rest-controller-testcase.php | 45 +++++++++++++ .../class-wp-test-spy-rest-server.php | 38 +++++++++++ tests/unit-tests/api/settings.php | 59 ++++++++++++++++- 5 files changed, 206 insertions(+), 6 deletions(-) create mode 100644 tests/framework/class-wp-test-rest-controller-testcase.php create mode 100644 tests/framework/class-wp-test-spy-rest-server.php diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index c9a70867875..7503aff3c19 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -63,28 +63,83 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @return WP_Error|WP_REST_Response */ public function get_locations( $request ) { - $response = rest_ensure_response( array() ); + $locations = apply_filters( 'woocommerce_settings_locations', array() ); + $defaults = array( + 'id' => null, + 'type' => 'page', + 'label' => null, + 'description' => '', + ); + $filtered_locations = array(); + foreach ( $locations as $location ) { + $location = wp_parse_args( $location, $defaults ); + $location_valid = true; + if ( is_null( $location['id'] ) || is_null( $location['label'] ) || is_null( $location['type'] ) ) { // id, label, and type are required fields + $location_valid = false; + } else if ( ! empty( $request['type'] ) ) { + if ( in_array( $request['type'], $this->get_location_types() ) && $request['type'] !== $location['type'] ) { + $location_valid = false; + } + } + + if ( $location_valid ) { + $filtered_locations[] = array_intersect_key( + $location, + array_flip( array_filter( array_keys( $location ), array( $this, 'filter_location_keys' ) ) ) + ); + } + } + $response = rest_ensure_response( $filtered_locations ); return $response; } + /** + * Callback for Allowed keys for each location response. + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function filter_location_keys( $key ) { + return in_array( $key, array( 'id', 'type', 'label', 'description' ) ); + } + /** * Get supported query parameters for locations. * @since 2.7.0 * @return array */ public function get_locations_params() { - $query_params = parent::get_collection_params(); - $query_params['context']['default'] = 'view'; + $query_params = array(); + + $query_params['type'] = array( + 'description' => __( 'Limit result set to setting locations of a specific type.', 'woocommerce' ), + 'type' => 'string' + ); + return $query_params; } /** - * Get the locations chema, conforming to JSON Schema + * Get the locations chema, conforming to JSON Schema. * @since 2.7.0 * @return array */ public function get_locations_schema() { + /*$schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'locations', + 'type' => 'object', + 'properties' => + );*/ + } + /** + * Returns a list of allowed setting location types. + * @since 2.7.0 + * @return array + */ + protected function get_location_types() { + return apply_filters( 'woocommerce_settings_location_types', array( 'page', 'metabox', 'shipping-zone' ) ); } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 37619b65ce4..3ce081fe8f2 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -112,6 +112,13 @@ class WC_Unit_Tests_Bootstrap { require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-order.php' ); require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-shipping-zones.php' ); require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-payment-token.php' ); + + /** + * WP-API + * @todo to be removed when the wp-api branch is merged. + */ + require_once( $this->tests_dir . '/framework/class-wp-test-rest-controller-testcase.php' ); + require_once( $this->tests_dir . '/framework/class-wp-test-spy-rest-server.php' ); } /** diff --git a/tests/framework/class-wp-test-rest-controller-testcase.php b/tests/framework/class-wp-test-rest-controller-testcase.php new file mode 100644 index 00000000000..f733017873b --- /dev/null +++ b/tests/framework/class-wp-test-rest-controller-testcase.php @@ -0,0 +1,45 @@ +server = $wp_rest_server = new WP_Test_Spy_REST_Server; + do_action( 'rest_api_init' ); + } + + public function tearDown() { + parent::tearDown(); + + /** @var WP_REST_Server $wp_rest_server */ + global $wp_rest_server; + $wp_rest_server = null; + } + + abstract public function test_register_routes(); + + abstract public function test_context_param(); + + abstract public function test_get_items(); + + abstract public function test_get_item(); + + abstract public function test_create_item(); + + abstract public function test_update_item(); + + abstract public function test_delete_item(); + + abstract public function test_prepare_item(); + + abstract public function test_get_item_schema(); + +} diff --git a/tests/framework/class-wp-test-spy-rest-server.php b/tests/framework/class-wp-test-spy-rest-server.php new file mode 100644 index 00000000000..ba485b65a1a --- /dev/null +++ b/tests/framework/class-wp-test-spy-rest-server.php @@ -0,0 +1,38 @@ +endpoints; + } + + /** + * Allow calling protected methods from tests + * + * @param string $method Method to call + * @param array $args Arguments to pass to the method + * @return mixed + */ + public function __call( $method, $args ) { + return call_user_func_array( array( $this, $method ), $args ); + } + + /** + * Call dispatch() with the rest_post_dispatch filter + */ + public function dispatch( $request ) { + $result = parent::dispatch( $request ); + $result = rest_ensure_response( $result ); + if ( is_wp_error( $result ) ) { + $result = $this->error_to_response( $result ); + } + return apply_filters( 'rest_post_dispatch', rest_ensure_response( $result ), $this, $request ); + } +} diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 86c44b50e74..d7fc08516c9 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -4,8 +4,63 @@ namespace WooCommerce\Tests\API; /** * Settings API Tests * @package WooCommerce\Tests\API - * @since 2.x.0 + * @since 2.7.0 */ -class Settings extends \WC_API_Unit_Test_Case { +class Settings extends \WP_Test_REST_Controller_Testcase { + + public function setUp() { + parent::setUp(); + $this->endpoint = new \WC_Rest_Settings_Controller(); + } + + /** + * Test route registration. + * @since 2.7.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v1/settings/locations', $routes ); + } + + /** + * Test normal /settings/locations response. + * @since 2.7.0 + */ + public function test_get_items() { + + } + + /** + * Test /settings/locations without valid permissions/creds. + * @since 2.7.0 + */ + public function test_get_locations_without_permission() { + + } + + /** + * Test /settings/locations correctly filters out bad values. + * Handles required fields and bogus fields. + * @since 2.7.0 + */ + public function test_get_locations_filters_values() { + + } + + /** + * Test /settings/locations with type. + * @since 2.7.0 + */ + public function test_get_locations_with_type() { + + } + + public function test_context_param() { } + public function test_get_item() { } + public function test_create_item() { } + public function test_update_item() { } + public function test_delete_item() { } + public function test_prepare_item() { } + public function test_get_item_schema() { } } From 658841822790af5bad3452a677d627c3c4dce8ec Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 7 Mar 2016 10:46:52 -0800 Subject: [PATCH 101/298] API Docs for our endpoints this far. --- .../README.md | 70 ++----------------- settings-api-docs/locations.md | 38 ++++++++++ 2 files changed, 44 insertions(+), 64 deletions(-) rename settings-api.MD => settings-api-docs/README.md (60%) create mode 100644 settings-api-docs/locations.md diff --git a/settings-api.MD b/settings-api-docs/README.md similarity index 60% rename from settings-api.MD rename to settings-api-docs/README.md index 1fb4237cccc..126d7d918a5 100644 --- a/settings-api.MD +++ b/settings-api-docs/README.md @@ -1,73 +1,15 @@ # Settings API Proposal -The idea of this proposal is to handle custom settings for both WooCommerce > Settings pages and settings panels for "metaboxes" (product data, coupon data). +The Settings API is a set of WP-API endpoints that return information about WooCommerce settings. Settings can also be updated with the API. -All settings are registered with PHP filters. Not through the API. The API is only for retrieving settings and updating them. +The API should be capable of handling settings in many different contexts including pages (WooCommerce > Settings), "metaboxes" (product data, coupon data), shipping zones, and be extendable to other contexts in the future. -## GET /settings/sections +All settings are registered with PHP filters. Not through the REST API. The REST API is only for retrieving settings and updating them. -Dedicated settings sections/pages (for screens currently under WooCommerce > Settings) -For example we might have 'General', 'Products', 'Tax', 'Shipping', 'Checkout', 'Accounts', 'Emails', and 'API'. Adding a new page to this area should automatically create a new tab in the UI. +## Locations +[locations.md](locations.md) -Metaboxes (Coupon Data or Product Data for example) are also considered sections, and will be listed by this endpoint. They won't be automatically displayed anywhere. - -Here is how they would be registered: - - // Default WooCommerce Setting Sections - apply_filters( 'woocommerce_settings_sections', array( - array( - 'id' => 'general', // ID (required) - 'type' => 'page', // page or metabox - 'label' => __( 'General', 'woocommerce' ), // human readable label (required) - 'description' => '', // human readable description (optional) - ), - array( - 'id' => 'products', - 'type' => 'page', // page or metabox - 'label' => __( 'Products', 'woocommerce' ), - 'description' => '', - ), - ..... - ) ); - -To add a new top level tab/page to WooCommerce > Settings - - add_filter( 'woocommerce_settings_sections', function( $pages ) { - $pages[] = array( - 'id' => 'bookings', - 'type' => 'page', - 'label' => __( 'Bookings', 'woocommerce-bookings' ), - 'description' => __( 'Bookings settings.', 'woocommerce-bookings' ), - ); - return $pages; - } ); - -The actual endpoint would return a JSON object like so: - - [ - { - "id": "general", - "type": "page", - "label": "General", - "description": "" - }, - { - "id": "products", - "type": "page", - "label": "Products", - "description": "" - }, - { - "id": "coupon-data", - "type": "metabox", - "label": "Coupon Data", - "description": "" - } - ] - -There should be a filter for this endpoint (?type=page) to get only sections of a specific type. - -![](https://cldup.com/HHAZ-JBOxU.thumb.png) +# The below sections are being moved to their own doc files as the API gets fleshed out. ## GET /settings/sections/$section/ diff --git a/settings-api-docs/locations.md b/settings-api-docs/locations.md new file mode 100644 index 00000000000..dcc1ab22eed --- /dev/null +++ b/settings-api-docs/locations.md @@ -0,0 +1,38 @@ +Settings can be grouped together by location. + +A location is just a grouping of settings that all share a common 'location' key. +This is so you can pull all settings meant to be displayed together in a particular area. + +Example: + +In wp-admin there is a "Coupon Data" box on the "Add New Coupon" page. +The coupon data box is considered location and would be represented like so: + + { + "id": "coupon-data", + "type": "metabox", + "label": "Coupon Data", + "description": "" + } + + +There are 4 fields that make up a location: + +* _id_: A unique identifier that can be used to link settings together. id is an alphanumeric string that should contain no spaces. Required. +* _type_: Context for where the settings in this location are going to be displayed. Right now core accepts 'page' for settings pages (pages currently under WooCommerce > Settings), 'metabox' (for metabox grouped settings like Coupon Data - this name is subject to change as this API develops), and 'shipping-zone' for settings associated with shipping zone settings. Required, defaults to 'page'. +* _label_: A human readable label. This is a translated string that can be used in the UI. Optional. +* _description_: A human readable description. This is a translated string that can be used in the UI. Optional. + +Any other fields passed will be stripped out before the JSON response is sent back to the client. + +Locations can be registered with the `woocommerce_settings_locations` filter: + + add_filter( 'woocommerce_settings_locations', function( $locations ) { + $locations[] = array( + 'id' => 'test-extension', + 'type' => 'page', + 'label' => __( 'Test Extension', 'woocommerce-test-extension' ), + 'description' => __( 'My awesome test settings.', 'woocommerce-test-extension' ), + ); + return $locations; + } ); From 5ee4b5d4dd26db6d756e48eee5332806125fa542 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 7 Mar 2016 12:44:07 -0800 Subject: [PATCH 102/298] Add the ability to get data on a single location. --- includes/api/wc-rest-settings-controller.php | 112 ++++++++++++++++--- settings-api-docs/locations.md | 22 +++- tests/unit-tests/api/settings.php | 32 +++++- 3 files changed, 147 insertions(+), 19 deletions(-) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index 7503aff3c19..4090be82e3a 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -33,14 +33,22 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_locations_params(), ), - 'schema' => array( $this, 'get_locations_schema' ), + 'schema' => array( $this, 'get_location_schema' ), ) ); + register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/locations/(?P[\w-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_location' ), + 'permission_callback' => array( $this, 'permissions_check' ), + ), + 'schema' => array( $this, 'get_location_schema' ), + ) ); } /** * Makes sure the current user has access to the settings APIs. - * @since 2.7.0 + * @since 2.7.0 * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ @@ -58,8 +66,8 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { /** * Get all settings locations. - * @since 2.7.0 - * @param WP_REST_Request $request Full details about the request. + * @since 2.7.0 + * @param WP_REST_Request $request Full details about the request. * @return WP_Error|WP_REST_Response */ public function get_locations( $request ) { @@ -93,9 +101,39 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return $response; } + /** + * Return a single setting location. + * @since 2.7.0 + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_location( $request ) { + $locations = apply_filters( 'woocommerce_settings_locations', array() ); + if ( empty( $locations ) ) { + return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); + } + + $index_key = $this->get_array_key_from_location_id( $locations, $request['location'] ); + if ( is_null( $index_key ) || empty( $locations[ $index_key ] ) ) { + return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); + } + + $location = $locations[ $index_key ]; + if ( is_null( $location['id'] ) || is_null( $location['label'] ) || is_null( $location['type'] ) ) { + return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); + } + + $filtered_location = array_intersect_key( + $location, + array_flip( array_filter( array_keys( $location ), array( $this, 'filter_location_keys' ) ) ) + ); + + return $filtered_location; + } + /** * Callback for Allowed keys for each location response. - * @since 2.7.0 + * @since 2.7.0 * @param string $key Key to check * @return boolean */ @@ -105,7 +143,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { /** * Get supported query parameters for locations. - * @since 2.7.0 + * @since 2.7.0 * @return array */ public function get_locations_params() { @@ -121,25 +159,73 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { /** * Get the locations chema, conforming to JSON Schema. - * @since 2.7.0 + * @since 2.7.0 * @return array */ - public function get_locations_schema() { - /*$schema = array( + public function get_location_schema() { + $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'locations', + 'title' => 'settings-locations', 'type' => 'object', - 'properties' => - );*/ + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier that can be used to link settings together.' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'type' => array( + 'description' => __( 'Context for where the settings in this location are going to be displayed.' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'label' => array( + 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'description' => array( + 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); } /** * Returns a list of allowed setting location types. - * @since 2.7.0 + * @todo move this? + * @since 2.7.0 * @return array */ protected function get_location_types() { return apply_filters( 'woocommerce_settings_location_types', array( 'page', 'metabox', 'shipping-zone' ) ); } + /** + * Returns the array key for a specific location ID so it can be pulled out of the 'locations' array. + * @todo move this? + * @param array $locations woocommerce_settings_locations + * @param string $id Location ID to get an array key index for + * @return integer|null + */ + protected function get_array_key_from_location_id( $locations, $id ) { + foreach ( $locations as $key => $location ) { + if ( $id === $location['id'] ) { + return $key; + } + } + return null; + } + } diff --git a/settings-api-docs/locations.md b/settings-api-docs/locations.md index dcc1ab22eed..2f01ccaf396 100644 --- a/settings-api-docs/locations.md +++ b/settings-api-docs/locations.md @@ -1,3 +1,7 @@ +# Locations + +## Basic Info + Settings can be grouped together by location. A location is just a grouping of settings that all share a common 'location' key. @@ -18,13 +22,15 @@ The coupon data box is considered location and would be represented like so: There are 4 fields that make up a location: -* _id_: A unique identifier that can be used to link settings together. id is an alphanumeric string that should contain no spaces. Required. -* _type_: Context for where the settings in this location are going to be displayed. Right now core accepts 'page' for settings pages (pages currently under WooCommerce > Settings), 'metabox' (for metabox grouped settings like Coupon Data - this name is subject to change as this API develops), and 'shipping-zone' for settings associated with shipping zone settings. Required, defaults to 'page'. +* _id_: A unique identifier that can be used to link settings together. Alphanumeric string that contains no spaces. Required. +* _type_: Context for where the settings in this location are going to be displayed. Right now core accepts 'page' for settings pages (pages currently under WooCommerce > Settings), 'metabox' (for metabox grouped settings like Coupon Data - this name is subject to change as this API develops), and 'shipping-zone' for settings associated with shipping zone settings. Alphanumeric string that contains no spaces. Required, defaults to 'page'. * _label_: A human readable label. This is a translated string that can be used in the UI. Optional. * _description_: A human readable description. This is a translated string that can be used in the UI. Optional. Any other fields passed will be stripped out before the JSON response is sent back to the client. +## Registering a Location + Locations can be registered with the `woocommerce_settings_locations` filter: add_filter( 'woocommerce_settings_locations', function( $locations ) { @@ -36,3 +42,15 @@ Locations can be registered with the `woocommerce_settings_locations` filter: ); return $locations; } ); + + +## Endpoints + +### GET /settings/locations + +Returns a list of all locations supported by WC. +There is an optional ?type parameter that allows you to return only locations for a specific context (like all page locations). + +### GET /settings/locations/$id + +Returns information on a single location. \ No newline at end of file diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index d7fc08516c9..34e4f1f5477 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -23,10 +23,10 @@ class Settings extends \WP_Test_REST_Controller_Testcase { } /** - * Test normal /settings/locations response. + * Test getting all locations. * @since 2.7.0 */ - public function test_get_items() { + public function test_get_locations() { } @@ -55,12 +55,36 @@ class Settings extends \WP_Test_REST_Controller_Testcase { } - public function test_context_param() { } + /** + * Test /settings/locations schema. + * @since 2.7.0 + */ + public function test_get_item_schema() { + + } + + /** + * Test getting a single location item. + * @since 2.7.0 + */ + public function test_get_location() { + + } + + /** + * Test getting a single location item. + * @since 2.7.0 + */ + public function test_get_location_without_permission() { + + } + + public function test_get_items() { } public function test_get_item() { } + public function test_context_param() { } public function test_create_item() { } public function test_update_item() { } public function test_delete_item() { } public function test_prepare_item() { } - public function test_get_item_schema() { } } From 21b66f94ffc46dc2003ff07845a7f16db8ab48dd Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 7 Mar 2016 13:46:40 -0800 Subject: [PATCH 103/298] More setting location tests. --- includes/api/wc-rest-settings-controller.php | 26 ++++-- tests/bootstrap.php | 1 + .../helpers/class-wc-helper-settings.php | 46 ++++++++++ tests/unit-tests/api/settings.php | 91 ++++++++++++++++++- 4 files changed, 154 insertions(+), 10 deletions(-) create mode 100644 tests/framework/helpers/class-wc-helper-settings.php diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index 4090be82e3a..11c2c4d9c76 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -72,12 +72,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { */ public function get_locations( $request ) { $locations = apply_filters( 'woocommerce_settings_locations', array() ); - $defaults = array( - 'id' => null, - 'type' => 'page', - 'label' => null, - 'description' => '', - ); + $defaults = $this->get_location_defaults(); $filtered_locations = array(); foreach ( $locations as $location ) { $location = wp_parse_args( $location, $defaults ); @@ -119,6 +114,8 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { } $location = $locations[ $index_key ]; + $defaults = $this->get_location_defaults(); + $location = wp_parse_args( $location, $defaults ); if ( is_null( $location['id'] ) || is_null( $location['label'] ) || is_null( $location['type'] ) ) { return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); } @@ -212,6 +209,21 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return apply_filters( 'woocommerce_settings_location_types', array( 'page', 'metabox', 'shipping-zone' ) ); } + /** + * Returns default settings for the various locations. null means the field is required. + * @todo move this? + * @since 2.7.0 + * @return array + */ + protected function get_location_defaults() { + return array( + 'id' => null, + 'type' => 'page', + 'label' => null, + 'description' => '', + ); + } + /** * Returns the array key for a specific location ID so it can be pulled out of the 'locations' array. * @todo move this? @@ -221,7 +233,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { */ protected function get_array_key_from_location_id( $locations, $id ) { foreach ( $locations as $key => $location ) { - if ( $id === $location['id'] ) { + if ( ! empty( $location['id'] ) && $id === $location['id'] ) { return $key; } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 3ce081fe8f2..8e5864f2c3c 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -112,6 +112,7 @@ class WC_Unit_Tests_Bootstrap { require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-order.php' ); require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-shipping-zones.php' ); require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-payment-token.php' ); + require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-settings.php' ); /** * WP-API diff --git a/tests/framework/helpers/class-wc-helper-settings.php b/tests/framework/helpers/class-wc-helper-settings.php new file mode 100644 index 00000000000..4f3634948ff --- /dev/null +++ b/tests/framework/helpers/class-wc-helper-settings.php @@ -0,0 +1,46 @@ + 'test', + 'type' => 'page', + 'bad' => 'value', + 'label' => __( 'Test Extension', 'woocommerce' ), + 'description' => __( 'My awesome test settings.', 'woocommerce' ), + ); + $locations[] = array( + 'id' => 'coupon-data', + 'type' => 'metabox', + 'label' => __( 'Coupon Data', 'woocommerce' ), + ); + $locations[] = array( + 'label' => __( 'Invalid', 'woocommerce' ), + ); + $locations[] = array( + 'id' => 'invalid', + ); + return $locations; + } + +} diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 34e4f1f5477..44083f562de 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -11,6 +11,7 @@ class Settings extends \WP_Test_REST_Controller_Testcase { public function setUp() { parent::setUp(); $this->endpoint = new \WC_Rest_Settings_Controller(); + \WC_Helper_Settings::register(); } /** @@ -27,7 +28,25 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_locations() { + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); + $data = $response->get_data(); + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 2, count( $data ) ); + + $this->check_get_location_response( $data[0], array( + 'id' => 'test', + 'type' => 'page', + 'label' => 'Test Extension', + 'description' => 'My awesome test settings.', + ) ); + + $this->check_get_location_response( $data[1], array( + 'id' => 'coupon-data', + 'type' => 'metabox', + 'label' => 'Coupon Data', + 'description' => '', + ) ); } /** @@ -43,8 +62,12 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * Handles required fields and bogus fields. * @since 2.7.0 */ - public function test_get_locations_filters_values() { + public function test_get_locations_correctly_filters_values() { + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); + $data = $response->get_data(); + $this->assertEquals( 'test', $data[0]['id'] ); + $this->assertArrayNotHasKey( 'bad', $data[0] ); } /** @@ -52,15 +75,42 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_locations_with_type() { + $request = new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ); + $request->set_param( 'type', 'not-a-real-type' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 2, count( $data ) ); // all results + $request = new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ); + $request->set_param( 'type', 'page' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 1, count( $data ) ); + + $this->check_get_location_response( $data[0], array( + 'id' => 'test', + 'type' => 'page', + 'label' => 'Test Extension', + 'description' => 'My awesome test settings.', + ) ); } /** * Test /settings/locations schema. * @since 2.7.0 */ - public function test_get_item_schema() { - + public function test_get_location_schema() { + $request = new \WP_REST_Request( 'OPTIONS', '/wc/v1/settings/locations' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 4, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'type', $properties ); + $this->assertArrayHasKey( 'label', $properties ); + $this->assertArrayHasKey( 'description', $properties ); } /** @@ -68,7 +118,28 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_location() { + // test getting a location that does not exist + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/not-real' ) ); + $data = $response->get_data(); + $this->assertEquals( 404, $response->get_status() ); + // test getting the 'invalid' location + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/invalid' ) ); + $data = $response->get_data(); + $this->assertEquals( 404, $response->get_status() ); + + // test getting a valid location + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/coupon-data' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->check_get_location_response( $data, array( + 'id' => 'coupon-data', + 'type' => 'metabox', + 'label' => 'Coupon Data', + 'description' => '', + ) ); } /** @@ -86,5 +157,19 @@ class Settings extends \WP_Test_REST_Controller_Testcase { public function test_update_item() { } public function test_delete_item() { } public function test_prepare_item() { } + public function test_get_item_schema() { } + + /** + * Ensure valid location data response. + * @since 2.7.0 + * @param array $response + * @param array $expected + */ + protected function check_get_location_response( $response, $expected ) { + $this->assertEquals( $expected['id'], $response['id'] ); + $this->assertEquals( $expected['type'], $response['type'] ); + $this->assertEquals( $expected['label'], $response['label'] ); + $this->assertEquals( $expected['description'], $response['description'] ); + } } From 19d3bc4737b7c0e2c7b2da356328ac46a685838a Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 7 Mar 2016 13:54:28 -0800 Subject: [PATCH 104/298] Add a permissions check to the locations endpoints and fill out the tests for them. --- includes/api/wc-rest-settings-controller.php | 4 ++++ tests/unit-tests/api/settings.php | 17 +++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index 11c2c4d9c76..ae322bd30bb 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -53,6 +53,10 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @return WP_Error|boolean */ public function permissions_check( $request ) { + if ( ! current_user_can( 'manage_options' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; } diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 44083f562de..15380336b99 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -12,6 +12,9 @@ class Settings extends \WP_Test_REST_Controller_Testcase { parent::setUp(); $this->endpoint = new \WC_Rest_Settings_Controller(); \WC_Helper_Settings::register(); + $this->user = $this->factory->user->create( array( + 'role' => 'administrator', + ) ); } /** @@ -28,6 +31,8 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_locations() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); $data = $response->get_data(); @@ -54,7 +59,10 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_locations_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); + $this->assertEquals( 401, $response->get_status() ); } /** @@ -63,6 +71,8 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_locations_correctly_filters_values() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); $data = $response->get_data(); @@ -75,6 +85,8 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_locations_with_type() { + wp_set_current_user( $this->user ); + $request = new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ); $request->set_param( 'type', 'not-a-real-type' ); $response = $this->server->dispatch( $request ); @@ -118,6 +130,8 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_location() { + wp_set_current_user( $this->user ); + // test getting a location that does not exist $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/not-real' ) ); $data = $response->get_data(); @@ -147,7 +161,10 @@ class Settings extends \WP_Test_REST_Controller_Testcase { * @since 2.7.0 */ public function test_get_location_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/coupon-data' ) ); + $this->assertEquals( 401, $response->get_status() ); } public function test_get_items() { } From 12aa11d5be7ef3090a2c2fa7d385ce54a14a8066 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 21 Mar 2016 11:29:27 -0700 Subject: [PATCH 105/298] Misc cleanup. --- includes/api/wc-rest-settings-controller.php | 3 +- tests/bootstrap.php | 1 - ...class-wp-test-rest-controller-testcase.php | 45 ------------------- tests/unit-tests/api/settings.php | 28 +++++++----- 4 files changed, 20 insertions(+), 57 deletions(-) delete mode 100644 tests/framework/class-wp-test-rest-controller-testcase.php diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index ae322bd30bb..b3bbc8bd3ff 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -129,7 +129,8 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { array_flip( array_filter( array_keys( $location ), array( $this, 'filter_location_keys' ) ) ) ); - return $filtered_location; + $response = rest_ensure_response( $filtered_location ); + return $response; } /** diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 8e5864f2c3c..87e65f64053 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -118,7 +118,6 @@ class WC_Unit_Tests_Bootstrap { * WP-API * @todo to be removed when the wp-api branch is merged. */ - require_once( $this->tests_dir . '/framework/class-wp-test-rest-controller-testcase.php' ); require_once( $this->tests_dir . '/framework/class-wp-test-spy-rest-server.php' ); } diff --git a/tests/framework/class-wp-test-rest-controller-testcase.php b/tests/framework/class-wp-test-rest-controller-testcase.php deleted file mode 100644 index f733017873b..00000000000 --- a/tests/framework/class-wp-test-rest-controller-testcase.php +++ /dev/null @@ -1,45 +0,0 @@ -server = $wp_rest_server = new WP_Test_Spy_REST_Server; - do_action( 'rest_api_init' ); - } - - public function tearDown() { - parent::tearDown(); - - /** @var WP_REST_Server $wp_rest_server */ - global $wp_rest_server; - $wp_rest_server = null; - } - - abstract public function test_register_routes(); - - abstract public function test_context_param(); - - abstract public function test_get_items(); - - abstract public function test_get_item(); - - abstract public function test_create_item(); - - abstract public function test_update_item(); - - abstract public function test_delete_item(); - - abstract public function test_prepare_item(); - - abstract public function test_get_item_schema(); - -} diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 15380336b99..eacf0c4be0f 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -6,10 +6,18 @@ namespace WooCommerce\Tests\API; * @package WooCommerce\Tests\API * @since 2.7.0 */ -class Settings extends \WP_Test_REST_Controller_Testcase { +class Settings extends \WC_Unit_Test_Case { + protected $server; + + /** + * Setup our test server, endpoints, and user info. + */ public function setUp() { parent::setUp(); + global $wp_rest_server; + $this->server = $wp_rest_server = new \WP_Test_Spy_REST_Server; + do_action( 'rest_api_init' ); $this->endpoint = new \WC_Rest_Settings_Controller(); \WC_Helper_Settings::register(); $this->user = $this->factory->user->create( array( @@ -17,6 +25,15 @@ class Settings extends \WP_Test_REST_Controller_Testcase { ) ); } + /** + * Unset the server. + */ + public function tearDown() { + parent::tearDown(); + global $wp_rest_server; + $wp_rest_server = null; + } + /** * Test route registration. * @since 2.7.0 @@ -167,15 +184,6 @@ class Settings extends \WP_Test_REST_Controller_Testcase { $this->assertEquals( 401, $response->get_status() ); } - public function test_get_items() { } - public function test_get_item() { } - public function test_context_param() { } - public function test_create_item() { } - public function test_update_item() { } - public function test_delete_item() { } - public function test_prepare_item() { } - public function test_get_item_schema() { } - /** * Ensure valid location data response. * @since 2.7.0 From b8a45f031c992561d8ec8e25047a89ec226a62d8 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 21 Mar 2016 13:38:22 -0700 Subject: [PATCH 106/298] Add group info to the single locations endpoint & update our docs --- includes/api/wc-rest-settings-controller.php | 14 ++++- settings-api-docs/README.md | 57 +------------------ settings-api-docs/groups.md | 58 ++++++++++++++++++++ settings-api-docs/locations.md | 4 +- 4 files changed, 75 insertions(+), 58 deletions(-) create mode 100644 settings-api-docs/groups.md diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index b3bbc8bd3ff..f4988d01da3 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -54,7 +54,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { */ public function permissions_check( $request ) { if ( ! current_user_can( 'manage_options' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + // return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -124,6 +124,16 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); } + if ( 'page' === $location['type'] ) { + $location['groups'] = array(); + $groups = apply_filters( 'woocommerce_settings_groups_' . $location['id'], array() ); + if ( ! empty( $groups ) ) { + foreach ( $groups as $group ) { + $location['groups'][] = array( 'id' => $group['id'], 'label' => $group['label'], 'description' => $group['description'] ); + } + } + } + $filtered_location = array_intersect_key( $location, array_flip( array_filter( array_keys( $location ), array( $this, 'filter_location_keys' ) ) ) @@ -140,7 +150,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @return boolean */ public function filter_location_keys( $key ) { - return in_array( $key, array( 'id', 'type', 'label', 'description' ) ); + return in_array( $key, array( 'id', 'type', 'label', 'description', 'groups' ) ); } /** diff --git a/settings-api-docs/README.md b/settings-api-docs/README.md index 126d7d918a5..c5d06efa821 100644 --- a/settings-api-docs/README.md +++ b/settings-api-docs/README.md @@ -9,61 +9,10 @@ All settings are registered with PHP filters. Not through the REST API. The REST ## Locations [locations.md](locations.md) -# The below sections are being moved to their own doc files as the API gets fleshed out. - -## GET /settings/sections/$section/ - -Lists all settings "groups" on a specific page. - -On the 'Products' page this would be 'General', 'Display', 'Inventory', and 'Downloadable Products'. - -Metaboxes won't need to use this. - -![](https://cldup.com/qXlfpvItr6-3000x3000.png) - -Here is how you would register groups: - - // products would be replaced with whatever page ID you want to register for. These filters automatically exist after registering a page - add_filter( 'woocommerce_settings_groups_products', function( $groups ) { - $groups[] = array( - 'id' => 'general', - 'label' => __( 'General', 'woocommerce' ), // human readable label (required) - 'description' => '', // human readable description (optional) - ); - $groups[] = array( - 'id' => 'display', - 'label' => __( 'Display', 'woocommerce' ), - 'description' => '', - ); - $groups[] = array( - 'id' => 'inventory', - 'label' => __( 'Inventory', 'woocommerce' ), - 'description' => '', - ); - return $groups; - } ); - -To retrive the groups for the 'products' page: - -GET /settings/sections/products - - { - "label": "Products", - "description": "", - "groups": [ - { - "id": "general", - "label": "General", - "description": "" - }, - { - "id": "display", - "label": "Display", - "description": "" - } - ] - } +## Groups +[groups.md](groups.md) +# The below sections are being moved to their own doc files (and may change) as the API gets fleshed out. ## /settings/$identifer diff --git a/settings-api-docs/groups.md b/settings-api-docs/groups.md new file mode 100644 index 00000000000..60ddf19d7fd --- /dev/null +++ b/settings-api-docs/groups.md @@ -0,0 +1,58 @@ +# Groups + +## Basic Info + +Groups are settings thats are grouped together on setting pages _only_ (type=page). That means setting locations like metaboxes don't have groups. + +For example, a location would be the 'Products' page. +The products page would ave the following groups: 'General', 'Display', 'Inventory', and 'Downloadable Products'. + +![](https://cldup.com/qXlfpvItr6-3000x3000.png) + + { + "id": "general", + "label": "General", + "description": "" + } + +There are 3 fields that make up a group: + +* _id_: A unique identifier that can be used to link settings together. The identifiers for groups only need to be unique on a specific page, so you can have a 'general' group under 'Products' and a 'general' group under Shipping. Alphanumeric string that contains no spaces. Required. +* _label_: A human readable label. This is a translated string that can be used in the UI. Required. +* _description_: A human readable description. This is a translated string that can be used in the UI. Optional. + +Any other fields passed will be stripped out before the JSON response is sent back to the client. + +## Registering a group + +Groups can be registered with the `woocommerce_settings_groups_{$location_id}` filter: + + add_filter( 'woocommerce_settings_groups_products', function( $groups ) { + $groups[] = array( + 'id' => 'extra-settings', + 'label' => __( 'Extras', 'woocommerce-test-extension' ), + 'description' => '', + ); + return $groups; + } ); + + +## Endpoints + +There are no separate endpoints for groups. You can access a list of groups for a specific page/location by calling that location's endpoint. + +### GET /settings/locations/$id + + { + "id": "test", + "type": "page", + "label": "Test Extension", + "description": "My awesome test settings.", + "groups": [ + { + "id": "general", + "label": "General", + "description": "" + } + ] + } \ No newline at end of file diff --git a/settings-api-docs/locations.md b/settings-api-docs/locations.md index 2f01ccaf396..a65f425ceb1 100644 --- a/settings-api-docs/locations.md +++ b/settings-api-docs/locations.md @@ -22,9 +22,9 @@ The coupon data box is considered location and would be represented like so: There are 4 fields that make up a location: -* _id_: A unique identifier that can be used to link settings together. Alphanumeric string that contains no spaces. Required. +* _id_: A unique identifier that can be used to link settings together. This shoud be a unique (for the whole system) value. Prefixing with your plugin slug is recommended for non-core changes. Alphanumeric string that contains no spaces. Required. * _type_: Context for where the settings in this location are going to be displayed. Right now core accepts 'page' for settings pages (pages currently under WooCommerce > Settings), 'metabox' (for metabox grouped settings like Coupon Data - this name is subject to change as this API develops), and 'shipping-zone' for settings associated with shipping zone settings. Alphanumeric string that contains no spaces. Required, defaults to 'page'. -* _label_: A human readable label. This is a translated string that can be used in the UI. Optional. +* _label_: A human readable label. This is a translated string that can be used in the UI. Required. * _description_: A human readable description. This is a translated string that can be used in the UI. Optional. Any other fields passed will be stripped out before the JSON response is sent back to the client. From 8fee6bd3b902c64e5da252ce77c16fba9f99b70a Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 21 Mar 2016 14:45:08 -0700 Subject: [PATCH 107/298] Add a test for settings groups, make sure any bad keys/values are filtered out, update docs. --- includes/api/wc-rest-settings-controller.php | 19 +++++++-- settings-api-docs/locations.md | 7 +++- .../helpers/class-wc-helper-settings.php | 25 ++++++++++++ tests/unit-tests/api/settings.php | 40 ++++++++++++++----- 4 files changed, 75 insertions(+), 16 deletions(-) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index f4988d01da3..1baf4b8a9a7 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -54,7 +54,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { */ public function permissions_check( $request ) { if ( ! current_user_can( 'manage_options' ) ) { - // return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -129,7 +129,10 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { $groups = apply_filters( 'woocommerce_settings_groups_' . $location['id'], array() ); if ( ! empty( $groups ) ) { foreach ( $groups as $group ) { - $location['groups'][] = array( 'id' => $group['id'], 'label' => $group['label'], 'description' => $group['description'] ); + $location['groups'][] = array_intersect_key( + $group, + array_flip( array_filter( array_keys( $group ), array( $this, 'filter_group_keys' ) ) ) + ); } } } @@ -144,7 +147,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { } /** - * Callback for Allowed keys for each location response. + * Callback for allowed keys for each location response. * @since 2.7.0 * @param string $key Key to check * @return boolean @@ -153,6 +156,16 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return in_array( $key, array( 'id', 'type', 'label', 'description', 'groups' ) ); } + /** + * Callback for allowed keys for each group. + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function filter_group_keys( $key ) { + return in_array( $key, array( 'id', 'label', 'description' ) ); + } + /** * Get supported query parameters for locations. * @since 2.7.0 diff --git a/settings-api-docs/locations.md b/settings-api-docs/locations.md index a65f425ceb1..287727402b1 100644 --- a/settings-api-docs/locations.md +++ b/settings-api-docs/locations.md @@ -20,7 +20,7 @@ The coupon data box is considered location and would be represented like so: } -There are 4 fields that make up a location: +There are 4 fields that make up all locations: * _id_: A unique identifier that can be used to link settings together. This shoud be a unique (for the whole system) value. Prefixing with your plugin slug is recommended for non-core changes. Alphanumeric string that contains no spaces. Required. * _type_: Context for where the settings in this location are going to be displayed. Right now core accepts 'page' for settings pages (pages currently under WooCommerce > Settings), 'metabox' (for metabox grouped settings like Coupon Data - this name is subject to change as this API develops), and 'shipping-zone' for settings associated with shipping zone settings. Alphanumeric string that contains no spaces. Required, defaults to 'page'. @@ -29,6 +29,9 @@ There are 4 fields that make up a location: Any other fields passed will be stripped out before the JSON response is sent back to the client. +Locations with type 'page' can also have an associated set of 'groups' which are sub sections/pages. See [groups.md](groups.md). +Pages will return an array of groups in their response. + ## Registering a Location Locations can be registered with the `woocommerce_settings_locations` filter: @@ -53,4 +56,4 @@ There is an optional ?type parameter that allows you to return only locations fo ### GET /settings/locations/$id -Returns information on a single location. \ No newline at end of file +Returns information on a single location + any associated groups. \ No newline at end of file diff --git a/tests/framework/helpers/class-wc-helper-settings.php b/tests/framework/helpers/class-wc-helper-settings.php index 4f3634948ff..af69df7590f 100644 --- a/tests/framework/helpers/class-wc-helper-settings.php +++ b/tests/framework/helpers/class-wc-helper-settings.php @@ -13,6 +13,7 @@ class WC_Helper_Settings { */ public static function register() { add_filter( 'woocommerce_settings_locations', array( 'WC_Helper_Settings', 'register_locations' ) ); + add_filter( 'woocommerce_settings_groups_test', array( 'WC_Helper_Settings', 'register_test_groups' ) ); } /** @@ -29,6 +30,12 @@ class WC_Helper_Settings { 'label' => __( 'Test Extension', 'woocommerce' ), 'description' => __( 'My awesome test settings.', 'woocommerce' ), ); + $locations[] = array( + 'id' => 'test-2', + 'type' => 'page', + 'label' => __( 'Test Extension', 'woocommerce' ), + 'description' => '', + ); $locations[] = array( 'id' => 'coupon-data', 'type' => 'metabox', @@ -43,4 +50,22 @@ class WC_Helper_Settings { return $locations; } + /** + * Registers some example groups for the 'test' page. + * @since 2.7.0 + * @param array $groups + * @return array + */ + public static function register_test_groups( $groups ) { + $groups[] = array( + 'id' => 'general', + 'label' => __( 'General', 'woocommerce' ), + ); + $groups[] = array( + 'id' => 'inventory', + 'label' => __( 'Inventory', 'woocommerce' ), + ); + return $groups; + } + } diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index eacf0c4be0f..93f1b6e7573 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -54,7 +54,7 @@ class Settings extends \WC_Unit_Test_Case { $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $data ) ); + $this->assertEquals( 3, count( $data ) ); $this->check_get_location_response( $data[0], array( 'id' => 'test', @@ -63,7 +63,7 @@ class Settings extends \WC_Unit_Test_Case { 'description' => 'My awesome test settings.', ) ); - $this->check_get_location_response( $data[1], array( + $this->check_get_location_response( $data[2], array( 'id' => 'coupon-data', 'type' => 'metabox', 'label' => 'Coupon Data', @@ -108,7 +108,7 @@ class Settings extends \WC_Unit_Test_Case { $request->set_param( 'type', 'not-a-real-type' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); - $this->assertEquals( 2, count( $data ) ); // all results + $this->assertEquals( 3, count( $data ) ); // all results $request = new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ); $request->set_param( 'type', 'page' ); @@ -116,14 +116,7 @@ class Settings extends \WC_Unit_Test_Case { $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 1, count( $data ) ); - - $this->check_get_location_response( $data[0], array( - 'id' => 'test', - 'type' => 'page', - 'label' => 'Test Extension', - 'description' => 'My awesome test settings.', - ) ); + $this->assertEquals( 2, count( $data ) ); } /** @@ -184,6 +177,31 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 401, $response->get_status() ); } + /** + * Test settings groups (for pages) + * @since 2.7.0 + */ + public function test_settings_groups() { + wp_set_current_user( $this->user ); + + // test getting a non page location + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/coupon-data' ) ); + $data = $response->get_data(); + $this->assertArrayNotHasKey( 'groups', $data ); + + // test getting a page with no groups + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/test-2' ) ); + $data = $response->get_data(); + $this->assertArrayHasKey( 'groups', $data ); + $this->assertEmpty( $data['groups'] ); + + // test getting a page with groups + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/test' ) ); + $data = $response->get_data(); + $this->assertArrayHasKey( 'groups', $data ); + $this->assertEquals( 2, count( $data['groups'] ) ); + } + /** * Ensure valid location data response. * @since 2.7.0 From 46028e0151034dc23efcd99d804d05620bf9a1e7 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 23 Mar 2016 12:36:59 -0700 Subject: [PATCH 108/298] Refactor down to two concepts - settings groups and settings. Fix up tests, and start working on returning actual settings and their values. --- includes/api/wc-rest-settings-controller.php | 336 +++++++++++------- .../helpers/class-wc-helper-settings.php | 74 ++-- tests/unit-tests/api/settings.php | 110 ++---- 3 files changed, 284 insertions(+), 236 deletions(-) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index 1baf4b8a9a7..dc10932ad89 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -26,23 +26,31 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @since 2.7.0 */ public function register_routes() { - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/locations', array( + register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_locations' ), + 'callback' => array( $this, 'get_groups' ), 'permission_callback' => array( $this, 'permissions_check' ), - 'args' => $this->get_locations_params(), ), - 'schema' => array( $this, 'get_location_schema' ), + 'schema' => array( $this, 'group_schema' ), ) ); - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/locations/(?P[\w-]+)', array( + register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_location' ), + 'callback' => array( $this, 'get_group' ), 'permission_callback' => array( $this, 'permissions_check' ), ), - 'schema' => array( $this, 'get_location_schema' ), + 'schema' => array( $this, 'group_schema' ), + ) ); + // @todo change this to support settings with array keys / multiple values? + register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_setting' ), + 'permission_callback' => array( $this, 'permissions_check' ), + ), + 'schema' => array( $this, 'setting_schema' ), ) ); } @@ -54,7 +62,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { */ public function permissions_check( $request ) { if ( ! current_user_can( 'manage_options' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + //return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -62,135 +70,112 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { /* |-------------------------------------------------------------------------- - | /settings/locations + | /settings |-------------------------------------------------------------------------- - | Returns a list of "settings" locations so all settings for a particular page - | or location can be properly loaded. + | Returns a list of "settings" groups so all settings for a particular page + | or section can be properly loaded. */ /** - * Get all settings locations. + * Get all settings groups. * @since 2.7.0 - * @param WP_REST_Request $request Full details about the request. + * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function get_locations( $request ) { - $locations = apply_filters( 'woocommerce_settings_locations', array() ); - $defaults = $this->get_location_defaults(); - $filtered_locations = array(); - foreach ( $locations as $location ) { - $location = wp_parse_args( $location, $defaults ); - $location_valid = true; - if ( is_null( $location['id'] ) || is_null( $location['label'] ) || is_null( $location['type'] ) ) { // id, label, and type are required fields - $location_valid = false; - } else if ( ! empty( $request['type'] ) ) { - if ( in_array( $request['type'], $this->get_location_types() ) && $request['type'] !== $location['type'] ) { - $location_valid = false; - } - } + public function get_groups( $request ) { + $groups = apply_filters( 'woocommerce_settings_groups', array() ); + if ( empty( $groups ) ) { + return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); + } - if ( $location_valid ) { - $filtered_locations[] = array_intersect_key( - $location, - array_flip( array_filter( array_keys( $location ), array( $this, 'filter_location_keys' ) ) ) - ); + $defaults = $this->group_defaults(); + $filtered_groups = array(); + foreach ( $groups as $group ) { + $group = wp_parse_args( $group, $defaults ); + if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { + $filtered_groups[] = $this->filter_group( $group ); } } - $response = rest_ensure_response( $filtered_locations ); + + $response = rest_ensure_response( $filtered_groups ); return $response; } /** - * Return a single setting location. + * Return a single setting group and its settings. * @since 2.7.0 - * @param WP_REST_Request $request Full details about the request. + * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function get_location( $request ) { - $locations = apply_filters( 'woocommerce_settings_locations', array() ); - if ( empty( $locations ) ) { - return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); + public function get_group( $request ) { + $groups = apply_filters( 'woocommerce_settings_groups', array() ); + if ( empty( $groups ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } - $index_key = $this->get_array_key_from_location_id( $locations, $request['location'] ); - if ( is_null( $index_key ) || empty( $locations[ $index_key ] ) ) { - return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); + $index_key = array_keys( wp_list_pluck( $groups, 'id' ), $request['group'] ); + if ( empty( $index_key ) || empty( $groups[ $index_key[0] ] ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.' ), array( 'status' => 404 ) ); } - $location = $locations[ $index_key ]; - $defaults = $this->get_location_defaults(); - $location = wp_parse_args( $location, $defaults ); - if ( is_null( $location['id'] ) || is_null( $location['label'] ) || is_null( $location['type'] ) ) { - return new WP_Error( 'rest_setting_location_invalid_id', __( 'Invalid location id.' ), array( 'status' => 404 ) ); + $group = wp_parse_args( $groups[ $index_key[0] ], $this->group_defaults() ); + if ( is_null( $group['id'] ) || is_null( $group['label'] ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.' ), array( 'status' => 404 ) ); } - if ( 'page' === $location['type'] ) { - $location['groups'] = array(); - $groups = apply_filters( 'woocommerce_settings_groups_' . $location['id'], array() ); - if ( ! empty( $groups ) ) { - foreach ( $groups as $group ) { - $location['groups'][] = array_intersect_key( - $group, - array_flip( array_filter( array_keys( $group ), array( $this, 'filter_group_keys' ) ) ) - ); + $filtered_group = $this->filter_group( $group ); + $filtered_group['settings'] = array(); + $settings = apply_filters( 'woocommerce_settings_' . $group['id'], array() ); + if ( ! empty( $settings ) ) { + foreach ( $settings as $setting ) { + $setting = $this->filter_setting( $setting ); + $setting['value'] = $this->get_value( $setting['id'] ); + if ( $this->is_valid_type( $setting['type'] ) ) { + $filtered_group['settings'][] = $setting; } } } - $filtered_location = array_intersect_key( - $location, - array_flip( array_filter( array_keys( $location ), array( $this, 'filter_location_keys' ) ) ) - ); - - $response = rest_ensure_response( $filtered_location ); - return $response; + return rest_ensure_response( $filtered_group ); } /** - * Callback for allowed keys for each location response. + * Return a single setting. * @since 2.7.0 - * @param string $key Key to check - * @return boolean + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response */ - public function filter_location_keys( $key ) { - return in_array( $key, array( 'id', 'type', 'label', 'description', 'groups' ) ); + public function get_setting( $request ) { + if ( empty( $request['group'] ) || empty( $request['setting'] ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.' ), array( 'status' => 404 ) ); + } + + $settings = apply_filters( 'woocommerce_settings_' . $request['group'], array() ); + $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $request['setting'] ); + + if ( empty( $array_key ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.' ), array( 'status' => 404 ) ); + } + + $setting = $this->filter_setting( $settings[ $array_key[0] ] ); + $setting['value'] = $this->get_value( $setting['id'] ); + + if ( ! $this->is_valid_type( $setting['type'] ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.' ), array( 'status' => 404 ) ); + } + + return rest_ensure_response( $setting ); } /** - * Callback for allowed keys for each group. - * @since 2.7.0 - * @param string $key Key to check - * @return boolean - */ - public function filter_group_keys( $key ) { - return in_array( $key, array( 'id', 'label', 'description' ) ); - } - - /** - * Get supported query parameters for locations. + * Get the groups schema, conforming to JSON Schema. * @since 2.7.0 * @return array */ - public function get_locations_params() { - $query_params = array(); - - $query_params['type'] = array( - 'description' => __( 'Limit result set to setting locations of a specific type.', 'woocommerce' ), - 'type' => 'string' - ); - - return $query_params; - } - - /** - * Get the locations chema, conforming to JSON Schema. - * @since 2.7.0 - * @return array - */ - public function get_location_schema() { + public function group_schema() { $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'settings-locations', + 'title' => 'settings-group', 'type' => 'object', 'properties' => array( 'id' => array( @@ -200,13 +185,6 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { 'sanitize_callback' => 'sanitize_title', ), ), - 'type' => array( - 'description' => __( 'Context for where the settings in this location are going to be displayed.' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), 'label' => array( 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.' ), 'type' => 'string', @@ -221,6 +199,13 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { 'sanitize_callback' => 'sanitize_text_field', ), ), + 'parent_id' => array( + 'description' => __( 'ID of parent grouping.' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), ), ); @@ -228,44 +213,137 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { } /** - * Returns a list of allowed setting location types. - * @todo move this? + * Get a value from WP's settings API. * @since 2.7.0 - * @return array + * @param string $setting + * @param string $default + * @return mixed */ - protected function get_location_types() { - return apply_filters( 'woocommerce_settings_location_types', array( 'page', 'metabox', 'shipping-zone' ) ); + public function get_value( $setting, $default = '' ) { + if ( strstr( $setting, '[' ) ) { // Array value + parse_str( $setting, $setting_array ); + $setting = current( array_keys( $setting ) ); + $values = get_option( $setting, '' ); + $key = key( $setting_array[ $setting ] ); + if ( isset( $values[ $key ] ) ) { + $value = $values[ $key ]; + } else { + $value = null; + } + } else { // Single value + $value = get_option( $setting, null ); + } + + if ( is_array( $setting ) ) { + $value = array_map( 'stripslashes', $value ); + } elseif ( ! is_null( $value ) ) { + $value = stripslashes( $value ); + } + + return $value === null ? $default : $value; } /** - * Returns default settings for the various locations. null means the field is required. - * @todo move this? - * @since 2.7.0 + * Filters out bad values from the groups array/filter so we + * only return known values via the API. + * @since 2.7.0 + * @param array $group * @return array */ - protected function get_location_defaults() { - return array( - 'id' => null, - 'type' => 'page', - 'label' => null, - 'description' => '', + public function filter_group( $group ) { + return array_intersect_key( + $group, + array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) ); } /** - * Returns the array key for a specific location ID so it can be pulled out of the 'locations' array. - * @todo move this? - * @param array $locations woocommerce_settings_locations - * @param string $id Location ID to get an array key index for - * @return integer|null + * Filters out bad values from the settings array/filter so we + * only return known values via the API. + * @since 2.7.0 + * @param array $setting + * @return array */ - protected function get_array_key_from_location_id( $locations, $id ) { - foreach ( $locations as $key => $location ) { - if ( ! empty( $location['id'] ) && $id === $location['id'] ) { - return $key; - } + public function filter_setting( $setting ) { + $setting = array_intersect_key( + $setting, + array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) + ); + + if ( empty( $setting['options'] ) ) { + unset( $setting['options'] ); } - return null; + + return $setting; + } + + /** + * Callback for allowed keys for each group response. + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function allowed_group_keys( $key ) { + return in_array( $key, array( 'id', 'label', 'description', 'parent_id' ) ); + } + + /** + * Callback for allowed keys for each setting response. + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function allowed_setting_keys( $key ) { + return in_array( $key, array( + 'id', 'label', 'description', 'default', 'tip', + 'placeholder', 'type', 'options', 'value', + ) ); + } + + /** + * Boolean for if a setting type is a valid supported setting type. + * @since 2.7.0 + * @param string $type + * @return boolean + */ + public function is_valid_type( $type ) { + return in_array( $type, array( + 'text', 'email', 'number', 'color', 'password', + 'textarea', 'select', 'multiselect', 'radio', 'checkbox', + ) ); + } + + /** + * Returns default settings for groups. null means the field is required. + * @since 2.7.0 + * @return array + */ + protected function group_defaults() { + return array( + 'id' => null, + 'label' => null, + 'description' => '', + 'parent_id' => '', + ); + } + + /** + * Returns default settings for settings. null means the field is required. + * @since 2.7.0 + * @return array + */ + protected function setting_defaults() { + return array( + 'id' => null, + 'label' => null, + 'type' => null, + 'description' => '', + 'tip' => '', + 'placeholder' => '', + 'default' => '', + 'options' => array(), + 'value' => '', + ); } } diff --git a/tests/framework/helpers/class-wc-helper-settings.php b/tests/framework/helpers/class-wc-helper-settings.php index af69df7590f..c55e86909e5 100644 --- a/tests/framework/helpers/class-wc-helper-settings.php +++ b/tests/framework/helpers/class-wc-helper-settings.php @@ -12,60 +12,74 @@ class WC_Helper_Settings { * @since 2.7.0 */ public static function register() { - add_filter( 'woocommerce_settings_locations', array( 'WC_Helper_Settings', 'register_locations' ) ); - add_filter( 'woocommerce_settings_groups_test', array( 'WC_Helper_Settings', 'register_test_groups' ) ); + add_filter( 'woocommerce_settings_groups', array( 'WC_Helper_Settings', 'register_groups' ) ); + add_filter( 'woocommerce_settings_test', array( 'WC_Helper_Settings', 'register_test_settings' ) ); } /** - * Registers some example locations, including invalid ones that should not show up in JSON responses. + * Registers some example setting groups, including invalid ones that should not show up in JSON responses. * @since 2.7.0 - * @param array $locations + * @param array $groups * @return array */ - public static function register_locations( $locations ) { - $locations[] = array( + public static function register_groups( $groups ) { + $groups[] = array( 'id' => 'test', 'type' => 'page', 'bad' => 'value', 'label' => __( 'Test Extension', 'woocommerce' ), 'description' => __( 'My awesome test settings.', 'woocommerce' ), ); - $locations[] = array( + $groups[] = array( 'id' => 'test-2', 'type' => 'page', 'label' => __( 'Test Extension', 'woocommerce' ), 'description' => '', ); - $locations[] = array( + $groups[] = array( 'id' => 'coupon-data', 'type' => 'metabox', 'label' => __( 'Coupon Data', 'woocommerce' ), ); - $locations[] = array( - 'label' => __( 'Invalid', 'woocommerce' ), - ); - $locations[] = array( + $groups[] = array( 'id' => 'invalid', ); - return $locations; - } - - /** - * Registers some example groups for the 'test' page. - * @since 2.7.0 - * @param array $groups - * @return array - */ - public static function register_test_groups( $groups ) { - $groups[] = array( - 'id' => 'general', - 'label' => __( 'General', 'woocommerce' ), - ); - $groups[] = array( - 'id' => 'inventory', - 'label' => __( 'Inventory', 'woocommerce' ), - ); return $groups; } + /** + * Registers some example settings. + * @since 2.7.0 + * @param array $settings + * @return array + */ + public static function register_settings( $settings ) { + $settings[] = array( + 'id' => 'catalog_options', + 'label' => __( 'Shop & Product Pages', 'woocommerce' ), + 'type' => 'title', + ); + $settings[] = array( + 'id' => 'woocommerce_shop_page_display', + 'label' => __( 'Shop Page Display', 'woocommerce' ), + 'description' => __( 'This controls what is shown on the product archive.', 'woocommerce' ), + 'default' => '', + 'type' => 'select', + 'options' => array( + '' => __( 'Show products', 'woocommerce' ), + 'subcategories' => __( 'Show categories & subcategories', 'woocommerce' ), + 'both' => __( 'Show both', 'woocommerce' ), + ), + ); + $settings[] = array( + 'id' => 'woocommerce_enable_lightbox', + 'label' => __( 'Product Image Gallery', 'woocommerce' ), + 'description' => __( 'Enable Lightbox for product images', 'woocommerce' ), + 'default' => 'yes', + 'tip' => __( 'Product gallery images will open in a lightbox.', 'woocommerce' ), + 'type' => 'checkbox', + ); + return $settings; + } + } diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 93f1b6e7573..bad7176f07e 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -40,57 +40,58 @@ class Settings extends \WC_Unit_Test_Case { */ public function test_register_routes() { $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v1/settings/locations', $routes ); + $this->assertArrayHasKey( '/wc/v1/settings', $routes ); + // @todo test others } /** - * Test getting all locations. + * Test getting all groups. * @since 2.7.0 */ - public function test_get_locations() { + public function test_get_groups() { wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings' ) ); $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); $this->assertEquals( 3, count( $data ) ); - $this->check_get_location_response( $data[0], array( + $this->check_get_group_response( $data[0], array( 'id' => 'test', - 'type' => 'page', 'label' => 'Test Extension', + 'parent_id' => '', 'description' => 'My awesome test settings.', ) ); - $this->check_get_location_response( $data[2], array( + $this->check_get_group_response( $data[2], array( 'id' => 'coupon-data', - 'type' => 'metabox', 'label' => 'Coupon Data', + 'parent_id' => '', 'description' => '', ) ); } /** - * Test /settings/locations without valid permissions/creds. + * Test /settings without valid permissions/creds. * @since 2.7.0 */ - public function test_get_locations_without_permission() { + public function test_get_groups_without_permission() { wp_set_current_user( 0 ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings' ) ); $this->assertEquals( 401, $response->get_status() ); } /** - * Test /settings/locations correctly filters out bad values. + * Test /settings/ correctly filters out bad values. * Handles required fields and bogus fields. * @since 2.7.0 */ - public function test_get_locations_correctly_filters_values() { + public function test_get_groups_correctly_filters_values() { wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings' ) ); $data = $response->get_data(); $this->assertEquals( 'test', $data[0]['id'] ); @@ -98,119 +99,74 @@ class Settings extends \WC_Unit_Test_Case { } /** - * Test /settings/locations with type. + * Test /settings schema. * @since 2.7.0 */ - public function test_get_locations_with_type() { - wp_set_current_user( $this->user ); - - $request = new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ); - $request->set_param( 'type', 'not-a-real-type' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - $this->assertEquals( 3, count( $data ) ); // all results - - $request = new \WP_REST_Request( 'GET', '/wc/v1/settings/locations' ); - $request->set_param( 'type', 'page' ); - $response = $this->server->dispatch( $request ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 2, count( $data ) ); - } - - /** - * Test /settings/locations schema. - * @since 2.7.0 - */ - public function test_get_location_schema() { - $request = new \WP_REST_Request( 'OPTIONS', '/wc/v1/settings/locations' ); + public function test_get_group_schema() { + $request = new \WP_REST_Request( 'OPTIONS', '/wc/v1/settings' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; $this->assertEquals( 4, count( $properties ) ); $this->assertArrayHasKey( 'id', $properties ); - $this->assertArrayHasKey( 'type', $properties ); + $this->assertArrayHasKey( 'parent_id', $properties ); $this->assertArrayHasKey( 'label', $properties ); $this->assertArrayHasKey( 'description', $properties ); } /** - * Test getting a single location item. + * Test getting a single group. * @since 2.7.0 */ - public function test_get_location() { + public function test_get_group() { wp_set_current_user( $this->user ); // test getting a location that does not exist - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/not-real' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/not-real' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting the 'invalid' location - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/invalid' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/invalid' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting a valid location - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/coupon-data' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/coupon-data' ) ); $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); - $this->check_get_location_response( $data, array( + $this->check_get_group_response( $data, array( 'id' => 'coupon-data', - 'type' => 'metabox', 'label' => 'Coupon Data', + 'parent_id' => '', 'description' => '', ) ); + + // @todo make sure settings are set correctly } /** - * Test getting a single location item. + * Test getting a single group without permission. * @since 2.7.0 */ - public function test_get_location_without_permission() { + public function test_get_group_without_permission() { wp_set_current_user( 0 ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/coupon-data' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/coupon-data' ) ); $this->assertEquals( 401, $response->get_status() ); } - /** - * Test settings groups (for pages) - * @since 2.7.0 - */ - public function test_settings_groups() { - wp_set_current_user( $this->user ); - - // test getting a non page location - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/coupon-data' ) ); - $data = $response->get_data(); - $this->assertArrayNotHasKey( 'groups', $data ); - - // test getting a page with no groups - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/test-2' ) ); - $data = $response->get_data(); - $this->assertArrayHasKey( 'groups', $data ); - $this->assertEmpty( $data['groups'] ); - - // test getting a page with groups - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/locations/test' ) ); - $data = $response->get_data(); - $this->assertArrayHasKey( 'groups', $data ); - $this->assertEquals( 2, count( $data['groups'] ) ); - } - /** * Ensure valid location data response. * @since 2.7.0 * @param array $response * @param array $expected */ - protected function check_get_location_response( $response, $expected ) { + protected function check_get_group_response( $response, $expected ) { $this->assertEquals( $expected['id'], $response['id'] ); - $this->assertEquals( $expected['type'], $response['type'] ); + $this->assertEquals( $expected['parent_id'], $response['parent_id'] ); $this->assertEquals( $expected['label'], $response['label'] ); $this->assertEquals( $expected['description'], $response['description'] ); } From 5de870bb08187b09af2c4bc15f3d4a1c081e5584 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Thu, 24 Mar 2016 14:01:22 -0700 Subject: [PATCH 109/298] Wrap up settings endpoints for updating, finish tests. --- includes/api/wc-rest-settings-controller.php | 300 ++++++++++++++---- .../helpers/class-wc-helper-settings.php | 10 +- tests/unit-tests/api/settings.php | 284 ++++++++++++++++- 3 files changed, 528 insertions(+), 66 deletions(-) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index dc10932ad89..d1bc059fe28 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -34,22 +34,32 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { ), 'schema' => array( $this, 'group_schema' ), ) ); - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_group' ), 'permission_callback' => array( $this, 'permissions_check' ), ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_settings' ), + 'permission_callback' => array( $this, 'permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), 'schema' => array( $this, 'group_schema' ), ) ); - // @todo change this to support settings with array keys / multiple values? register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_setting' ), 'permission_callback' => array( $this, 'permissions_check' ), ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_setting' ), + 'permission_callback' => array( $this, 'permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), 'schema' => array( $this, 'setting_schema' ), ) ); } @@ -62,20 +72,15 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { */ public function permissions_check( $request ) { if ( ! current_user_can( 'manage_options' ) ) { - //return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot access settings.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( + 'woocommerce_rest_cannot_view', + __( 'Sorry, you cannot access settings.', 'woocommerce' ), + array( 'status' => rest_authorization_required_code() ) + ); } - return true; } - /* - |-------------------------------------------------------------------------- - | /settings - |-------------------------------------------------------------------------- - | Returns a list of "settings" groups so all settings for a particular page - | or section can be properly loaded. - */ - /** * Get all settings groups. * @since 2.7.0 @@ -108,35 +113,11 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @return WP_Error|WP_REST_Response */ public function get_group( $request ) { - $groups = apply_filters( 'woocommerce_settings_groups', array() ); - if ( empty( $groups ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + $group = $this->_get_group_from_request( $request ); + if ( is_wp_error( $group ) ) { + return $group; } - - $index_key = array_keys( wp_list_pluck( $groups, 'id' ), $request['group'] ); - if ( empty( $index_key ) || empty( $groups[ $index_key[0] ] ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.' ), array( 'status' => 404 ) ); - } - - $group = wp_parse_args( $groups[ $index_key[0] ], $this->group_defaults() ); - if ( is_null( $group['id'] ) || is_null( $group['label'] ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.' ), array( 'status' => 404 ) ); - } - - $filtered_group = $this->filter_group( $group ); - $filtered_group['settings'] = array(); - $settings = apply_filters( 'woocommerce_settings_' . $group['id'], array() ); - if ( ! empty( $settings ) ) { - foreach ( $settings as $setting ) { - $setting = $this->filter_setting( $setting ); - $setting['value'] = $this->get_value( $setting['id'] ); - if ( $this->is_valid_type( $setting['type'] ) ) { - $filtered_group['settings'][] = $setting; - } - } - } - - return rest_ensure_response( $filtered_group ); + return rest_ensure_response( $group ); } /** @@ -146,25 +127,171 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @return WP_Error|WP_REST_Response */ public function get_setting( $request ) { + $setting = $this->_get_setting_from_request( $request ); + if ( is_wp_error( $setting ) ) { + return $setting; + } + return rest_ensure_response( $setting ); + } + + /** + * Update a single setting. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function update_setting( $request ) { + $setting = $this->_get_setting_from_request( $request ); + if ( is_wp_error( $setting ) ) { + return $setting; + } + + $value = $setting['value'] = $this->sanitize_setting_value( $setting, $request['value'] ); + update_option( $setting['id'], $value ); + + return rest_ensure_response( $setting ); + } + + /** + * Update a multiple settings at once. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function update_settings( $request ) { + $group = $this->_get_group_from_request( $request ); + if ( is_wp_error( $group ) ) { + return $group; + } + + foreach ( $group['settings'] as $array_key => $setting ) { + if ( isset( $request['values'][ $setting['id'] ] ) ) { + $value = $this->sanitize_setting_value( $setting, $request['values'][ $setting['id'] ] ); + $group['settings'][ $array_key ]['value'] = $value; + update_option( $setting['id'], $value ); + } + } + + return rest_ensure_response( $group ); + } + + /** + * Cleans a value before setting it. + * @since 2.7.0 + * @param array $setting WC Setting Array + * @param mixed $raw_value Raw value from PUT request + * @return mixed Sanitized value + */ + public function sanitize_setting_value( $setting, $raw_value ) { + switch ( $setting['type'] ) { + case 'checkbox' : + $default = ( ! empty( $setting['default'] ) ? $setting['default'] : 'no' ); + $value = ( in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : $default ); + break; + case 'email' : + $value = sanitize_email( $raw_value ); + $default = ( ! empty( $setting['default'] ) ? $setting['default'] : '' ); + $value = ( ! empty( $value ) ? $value : $default ); + break; + case 'textarea' : + $value = wp_kses_post( trim( $raw_value ) ); + break; + case 'multiselect' : + case 'multi_select_countries' : + $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) ); + break; + case 'image_width' : + $value = array(); + if ( isset( $raw_value['width'] ) ) { + $value['width'] = wc_clean( $raw_value['width'] ); + $value['height'] = wc_clean( $raw_value['height'] ); + $value['crop'] = isset( $raw_value['crop'] ) ? 1 : 0; + } else { + $value['width'] = $setting['default']['width']; + $value['height'] = $setting['default']['height']; + $value['crop'] = $setting['default']['crop']; + } + break; + default : + $value = wc_clean( $raw_value ); + break; + } + + // A couple fields changed in the REST API -- we can just pass these too so old filters still work + $setting['desc'] = ( ! empty( $setting['description'] ) ? $setting['description'] : '' ); + $setting['title'] = ( ! empty( $setting['label'] ) ? $setting['label'] : '' ); + + $value = apply_filters( 'woocommerce_admin_settings_sanitize_option', $value, $setting, $raw_value ); + $value = apply_filters( "woocommerce_admin_settings_sanitize_option_" . $setting['id'], $value, $setting, $raw_value ); + do_action( 'woocommerce_update_option', $setting ); + + return $value; + } + + /** + * Takes a valid request and returns back the corresponding setting array. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|array + */ + private function _get_setting_from_request( $request ) { if ( empty( $request['group'] ) || empty( $request['setting'] ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } $settings = apply_filters( 'woocommerce_settings_' . $request['group'], array() ); $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $request['setting'] ); if ( empty( $array_key ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } $setting = $this->filter_setting( $settings[ $array_key[0] ] ); $setting['value'] = $this->get_value( $setting['id'] ); if ( ! $this->is_valid_type( $setting['type'] ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } - return rest_ensure_response( $setting ); + return $setting; + } + + /** + * Takes a valid request and returns back the corresponding group array. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|array + */ + private function _get_group_from_request( $request ) { + $groups = apply_filters( 'woocommerce_settings_groups', array() ); + if ( empty( $groups ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $index_key = array_keys( wp_list_pluck( $groups, 'id' ), $request['group'] ); + if ( empty( $index_key ) || empty( $groups[ $index_key[0] ] ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $group = wp_parse_args( $groups[ $index_key[0] ], $this->group_defaults() ); + if ( is_null( $group['id'] ) || is_null( $group['label'] ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $filtered_group = $this->filter_group( $group ); + $filtered_group['settings'] = array(); + $settings = apply_filters( 'woocommerce_settings_' . $group['id'], array() ); + if ( ! empty( $settings ) ) { + foreach ( $settings as $setting ) { + $setting = $this->filter_setting( $setting ); + $setting['value'] = $this->get_value( $setting['id'] ); + if ( $this->is_valid_type( $setting['type'] ) ) { + $filtered_group['settings'][] = $setting; + } + } + } + + return $filtered_group; } /** @@ -179,30 +306,30 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { 'type' => 'object', 'properties' => array( 'id' => array( - 'description' => __( 'A unique identifier that can be used to link settings together.' ), + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_title', ), ), - 'label' => array( - 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.' ), + 'label' => array( + 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.', 'woocommerce' ), 'type' => 'string', - 'arg_options' => array( + 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), - 'description' => array( - 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.' ), + 'description' => array( + 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.', 'woocommerce' ), 'type' => 'string', - 'arg_options' => array( + 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'parent_id' => array( - 'description' => __( 'ID of parent grouping.' ), + 'description' => __( 'ID of parent grouping.', 'woocommerce' ), 'type' => 'string', - 'arg_options' => array( + 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), @@ -212,6 +339,73 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return $this->add_additional_fields_schema( $schema ); } + /** + * Get the settings schema, conforming to JSON Schema. + * @since 2.7.0 + * @return array + */ + public function setting_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'settings', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier for the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'label' => array( + 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'description' => array( + 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'default' => array( + 'description' => __( 'Default value for the setting.', 'woocommerce' ), + 'type' => 'mixed', + ), + 'tip' => array( + 'description' => __( 'Extra help text explaining the setting.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'placeholder' => array( + 'description' => __( 'Placeholder text to be displayed in text inputs.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'type' => array( + 'description' => __( 'Type of setting. Allowed values: text, email, number, color, password, textarea, select, multiselect, radio, image_width, checkbox.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'options' => array( + 'description' => __( 'Array of options (key value pairs) for inputs such as select, multiselect, and radio buttons.', 'woocommerce' ), + 'type' => 'array', + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + /** * Get a value from WP's settings API. * @since 2.7.0 diff --git a/tests/framework/helpers/class-wc-helper-settings.php b/tests/framework/helpers/class-wc-helper-settings.php index c55e86909e5..480e5e46add 100644 --- a/tests/framework/helpers/class-wc-helper-settings.php +++ b/tests/framework/helpers/class-wc-helper-settings.php @@ -25,20 +25,18 @@ class WC_Helper_Settings { public static function register_groups( $groups ) { $groups[] = array( 'id' => 'test', - 'type' => 'page', 'bad' => 'value', 'label' => __( 'Test Extension', 'woocommerce' ), 'description' => __( 'My awesome test settings.', 'woocommerce' ), ); $groups[] = array( - 'id' => 'test-2', - 'type' => 'page', - 'label' => __( 'Test Extension', 'woocommerce' ), + 'id' => 'sub-test', + 'parent_id' => 'test', + 'label' => __( 'Sub test', 'woocommerce' ), 'description' => '', ); $groups[] = array( 'id' => 'coupon-data', - 'type' => 'metabox', 'label' => __( 'Coupon Data', 'woocommerce' ), ); $groups[] = array( @@ -53,7 +51,7 @@ class WC_Helper_Settings { * @param array $settings * @return array */ - public static function register_settings( $settings ) { + public static function register_test_settings( $settings ) { $settings[] = array( 'id' => 'catalog_options', 'label' => __( 'Shop & Product Pages', 'woocommerce' ), diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index bad7176f07e..18e3ad0177c 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -41,7 +41,8 @@ class Settings extends \WC_Unit_Test_Case { public function test_register_routes() { $routes = $this->server->get_routes(); $this->assertArrayHasKey( '/wc/v1/settings', $routes ); - // @todo test others + $this->assertArrayHasKey( '/wc/v1/settings/(?P[\w-]+)', $routes ); + $this->assertArrayHasKey( '/wc/v1/settings/(?P[\w-]+)/(?P[\w-]+)', $routes ); } /** @@ -64,6 +65,13 @@ class Settings extends \WC_Unit_Test_Case { 'description' => 'My awesome test settings.', ) ); + $this->check_get_group_response( $data[1], array( + 'id' => 'sub-test', + 'label' => 'Sub test', + 'parent_id' => 'test', + 'description' => '', + ) ); + $this->check_get_group_response( $data[2], array( 'id' => 'coupon-data', 'label' => 'Coupon Data', @@ -99,7 +107,7 @@ class Settings extends \WC_Unit_Test_Case { } /** - * Test /settings schema. + * Test groups schema. * @since 2.7.0 */ public function test_get_group_schema() { @@ -114,6 +122,26 @@ class Settings extends \WC_Unit_Test_Case { $this->assertArrayHasKey( 'description', $properties ); } + /** + * Test settings schema. + * @since 2.7.0 + */ + public function test_get_setting_schema() { + $request = new \WP_REST_Request( 'OPTIONS', '/wc/v1/settings/test/woocommerce_shop_page_display' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 8, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'label', $properties ); + $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'default', $properties ); + $this->assertArrayHasKey( 'tip', $properties ); + $this->assertArrayHasKey( 'placeholder', $properties ); + $this->assertArrayHasKey( 'type', $properties ); + $this->assertArrayHasKey( 'options', $properties ); + } + /** * Test getting a single group. * @since 2.7.0 @@ -121,17 +149,17 @@ class Settings extends \WC_Unit_Test_Case { public function test_get_group() { wp_set_current_user( $this->user ); - // test getting a location that does not exist + // test getting a group that does not exist $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/not-real' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); - // test getting the 'invalid' location + // test getting the 'invalid' group $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/invalid' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); - // test getting a valid location + // test getting a valid group $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/coupon-data' ) ); $data = $response->get_data(); @@ -144,7 +172,15 @@ class Settings extends \WC_Unit_Test_Case { 'description' => '', ) ); - // @todo make sure settings are set correctly + // test getting a valid group with settings attached to it + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); + $data = $response->get_data(); + + $this->assertEquals( 2, count( $data['settings'] ) ); + $this->assertEquals( 'woocommerce_shop_page_display', $data['settings'][0]['id'] ); + $this->assertEmpty( $data['settings'][0]['value'] ); + $this->assertEquals( 'woocommerce_enable_lightbox', $data['settings'][1]['id'] ); + $this->assertEquals( 'yes', $data['settings'][1]['value'] ); } /** @@ -159,7 +195,241 @@ class Settings extends \WC_Unit_Test_Case { } /** - * Ensure valid location data response. + * Test updating a single setting. + * @since 2.7.0 + */ + public function test_update_setting() { + wp_set_current_user( $this->user ); + + // test defaults first + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_shop_page_display' ) ); + $data = $response->get_data(); + $this->assertEquals( '', $data['value'] ); + + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); + $data = $response->get_data(); + $this->assertEquals( 'yes', $data['value'] ); + + // test updating shop display setting + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( array( + 'value' => 'both', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'both', $data['value'] ); + $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); + + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( array( + 'value' => 'subcategories', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'subcategories', $data['value'] ); + $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); + + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request->set_body_params( array( + 'value' => '', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( '', $data['value'] ); + $this->assertEquals( '', get_option( 'woocommerce_shop_page_display' ) ); + + // test updating ligtbox + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); + $request->set_body_params( array( + 'value' => 'no', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'no', $data['value'] ); + $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); + + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); + $request->set_body_params( array( + 'value' => 'yes', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'yes', $data['value'] ); + $this->assertEquals( 'yes', get_option( 'woocommerce_enable_lightbox' ) ); + } + + /** + * Test updating multiple settings at once. + * @since 2.7.0 + */ + public function test_update_settings() { + wp_set_current_user( $this->user ); + + // test defaults first + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); + $data = $response->get_data(); + $this->assertEquals( '', $data['settings'][0]['value'] ); + $this->assertEquals( 'yes', $data['settings'][1]['value'] ); + + // test setting both at once + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s', 'test' ) ); + $request->set_body_params( array( + 'values' => array( + 'woocommerce_shop_page_display' => 'both', + 'woocommerce_enable_lightbox' => 'no', + ), + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 'both', $data['settings'][0]['value'] ); + $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); + $this->assertEquals( 'no', $data['settings'][1]['value'] ); + $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); + + // test updating one, but making sure the other value stays the same + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s', 'test' ) ); + $request->set_body_params( array( + 'values' => array( + 'woocommerce_shop_page_display' => 'subcategories', + ), + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 'subcategories', $data['settings'][0]['value'] ); + $this->assertEquals( 'no', $data['settings'][1]['value'] ); + $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); + $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); + } + + /** + * Test getting a single setting. + * @since 2.7.0 + */ + public function test_get_setting() { + wp_set_current_user( $this->user ); + + // test getting an invalid setting from a group that does not exist + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/not-real/woocommerce_enable_lightbox' ) ); + $data = $response->get_data(); + $this->assertEquals( 404, $response->get_status() ); + + // test getting an invalid setting from a group that does exist + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/invalid/invalid' ) ); + $data = $response->get_data(); + $this->assertEquals( 404, $response->get_status() ); + + // test getting a valid setting + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + + $this->assertEquals( 'woocommerce_enable_lightbox', $data['id'] ); + $this->assertEquals( 'Product Image Gallery', $data['label'] ); + $this->assertEquals( 'yes', $data['default'] ); + $this->assertEquals( 'Product gallery images will open in a lightbox.', $data['tip'] ); + $this->assertEquals( 'checkbox', $data['type'] ); + $this->assertEquals( 'yes', $data['value'] ); + } + + /** + * Test getting a single setting without valid user permissions. + * @since 2.7.0 + */ + public function test_get_setting_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + + /** + * Test updating a single setting without valid user permissions. + * @since 2.7.0 + */ + public function test_update_setting_without_permission() { + wp_set_current_user( 0 ); + + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); + $request->set_body_params( array( + 'value' => 'yes', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + + /** + * Test updating multiple settings without valid user permissions. + * @since 2.7.0 + */ + public function test_update_settings_without_permission() { + wp_set_current_user( 0 ); + + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s', 'test' ) ); + $request->set_body_params( array( + 'values' => array( + 'woocommerce_shop_page_display' => 'subcategories', + ), + ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Makes sure our sanitize function runs correctly for different types. + * @since 2.7.0 + */ + public function test_sanitize_setting() { + $endpoint = new \WC_Rest_Settings_Controller; + + // checkbox + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'checkbox', 'default' => 'yes' ), 'no' ); + $this->assertEquals( 'no', $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'checkbox', 'default' => 'yes' ), 'yes' ); + $this->assertEquals( 'yes', $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'checkbox', 'default' => 'yes' ), 'invalid' ); + $this->assertEquals( 'yes', $value ); + + // email + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email' ), 'test@woo.local' ); + $this->assertEquals( 'test@woo.local', $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email' ), ' admin@woo.local! ' ); + $this->assertEquals( 'admin@woo.local', $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email' ), 'blah' ); + $this->assertEquals( '', $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email', 'default' => 'woo@woo.local' ), 'blah' ); + $this->assertEquals( 'woo@woo.local', $value ); + + // textarea + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'textarea' ), ' blah' ); + $this->assertEquals( 'blah', $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'textarea' ), 'blah' ); + $this->assertEquals( 'blah', $value ); + + // multiselect / multiselect countries + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'multiselect' ), array( 'test', 'assertEquals( array( 'test', '<test' ), $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'multi_select_countries' ), array( 'test', 'assertEquals( array( 'test', '<test' ), $value ); + + // image_width + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'image_width' ), array( 'width' => ' 100%', 'height' => '25px ' ) ); + $this->assertEquals( array( 'width' => '100%', 'height' => '25px', 'crop' => 0 ), $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'image_width' ), array( 'width' => '100%', 'height' => '25px', 'crop' => 'something' ) ); + $this->assertEquals( array( 'width' => '100%', 'height' => '25px', 'crop' => 1 ), $value ); + $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'image_width', 'default' => array( 'width' => '50px', 'height' => '50px', 'crop' => true ) ), array() ); + $this->assertEquals( array( 'width' => '50px', 'height' => '50px', 'crop' => 1 ), $value ); + } + + /** + * Ensure valid group data response. * @since 2.7.0 * @param array $response * @param array $expected From 3de423b5c2cf18e2c25aaf76231192edaaa2353a Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 28 Mar 2016 12:04:26 -0700 Subject: [PATCH 110/298] Wrap up settings api --- .../admin/settings/class-wc-settings-page.php | 18 ++++ includes/api/wc-rest-settings-controller.php | 78 +++++++++++----- .../class-wc-register-classic-settings.php | 88 +++++++++++++++++++ .../helpers/class-wc-helper-settings.php | 7 +- tests/unit-tests/api/settings.php | 80 +++++++++++------ woocommerce.php | 1 + 6 files changed, 215 insertions(+), 57 deletions(-) create mode 100644 includes/class-wc-register-classic-settings.php diff --git a/includes/admin/settings/class-wc-settings-page.php b/includes/admin/settings/class-wc-settings-page.php index fb09893fcd1..7831649cc5f 100644 --- a/includes/admin/settings/class-wc-settings-page.php +++ b/includes/admin/settings/class-wc-settings-page.php @@ -43,6 +43,24 @@ abstract class WC_Settings_Page { add_action( 'woocommerce_settings_save_' . $this->id, array( $this, 'save' ) ); } + /** + * Get settings page ID. + * @since 2.7.0 + * @return string + */ + public function get_id() { + return $this->id; + } + + /** + * Get settings page label. + * @since 2.7.0 + * @return string + */ + public function get_label() { + return $this->label; + } + /** * Add this page to settings. */ diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index d1bc059fe28..dd1c48b973e 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -96,6 +96,14 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { $defaults = $this->group_defaults(); $filtered_groups = array(); foreach ( $groups as $group ) { + $sub_groups = array(); + foreach ( $groups as $_group ) { + if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { + $sub_groups[] = $_group['id']; + } + } + $group['sub_groups'] = $sub_groups; + $group = wp_parse_args( $group, $defaults ); if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { $filtered_groups[] = $this->filter_group( $group ); @@ -194,7 +202,14 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { $value = ( ! empty( $value ) ? $value : $default ); break; case 'textarea' : - $value = wp_kses_post( trim( $raw_value ) ); + $value = wp_kses( trim( $raw_value ), + array_merge( + array( + 'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true ) + ), + wp_kses_allowed_html( 'post' ) + ) + ); break; case 'multiselect' : case 'multi_select_countries' : @@ -239,7 +254,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } - $settings = apply_filters( 'woocommerce_settings_' . $request['group'], array() ); + $settings = apply_filters( 'woocommerce_settings-' . $request['group'], array() ); $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $request['setting'] ); if ( empty( $array_key ) ) { @@ -278,9 +293,18 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } + // Find sub groups + $sub_groups = array(); + foreach ( $groups as $_group ) { + if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { + $sub_groups[] = $_group['id']; + } + } + $filtered_group = $this->filter_group( $group ); $filtered_group['settings'] = array(); - $settings = apply_filters( 'woocommerce_settings_' . $group['id'], array() ); + $settings = apply_filters( 'woocommerce_settings-' . $group['id'], array() ); + if ( ! empty( $settings ) ) { foreach ( $settings as $setting ) { $setting = $this->filter_setting( $setting ); @@ -291,6 +315,8 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { } } + $filtered_group['sub_groups'] = $sub_groups; + return $filtered_group; } @@ -333,6 +359,13 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { 'sanitize_callback' => 'sanitize_text_field', ), ), + 'sub_groups' => array( + 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), ), ); @@ -415,26 +448,26 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { */ public function get_value( $setting, $default = '' ) { if ( strstr( $setting, '[' ) ) { // Array value - parse_str( $setting, $setting_array ); - $setting = current( array_keys( $setting ) ); - $values = get_option( $setting, '' ); - $key = key( $setting_array[ $setting ] ); - if ( isset( $values[ $key ] ) ) { - $value = $values[ $key ]; - } else { - $value = null; - } - } else { // Single value - $value = get_option( $setting, null ); - } + parse_str( $setting, $setting_array ); + $setting = current( array_keys( $setting ) ); + $values = get_option( $setting, '' ); + $key = key( $setting_array[ $setting ] ); + if ( isset( $values[ $key ] ) ) { + $value = $values[ $key ]; + } else { + $value = null; + } + } else { // Single value + $value = get_option( $setting, null ); + } - if ( is_array( $setting ) ) { - $value = array_map( 'stripslashes', $value ); - } elseif ( ! is_null( $value ) ) { - $value = stripslashes( $value ); - } + if ( is_array( $value ) ) { + $value = array_map( 'stripslashes', $value ); + } elseif ( ! is_null( $value ) ) { + $value = stripslashes( $value ); + } - return $value === null ? $default : $value; + return $value === null ? $default : $value; } /** @@ -478,7 +511,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @return boolean */ public function allowed_group_keys( $key ) { - return in_array( $key, array( 'id', 'label', 'description', 'parent_id' ) ); + return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); } /** @@ -518,6 +551,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { 'label' => null, 'description' => '', 'parent_id' => '', + 'sub_groups' => array(), ); } diff --git a/includes/class-wc-register-classic-settings.php b/includes/class-wc-register-classic-settings.php new file mode 100644 index 00000000000..8cb0397f6eb --- /dev/null +++ b/includes/class-wc-register-classic-settings.php @@ -0,0 +1,88 @@ +page = $page; + add_filter( 'woocommerce_settings-' . $this->page->get_id() . '', array( $this, 'register_classic_settings' ) ); + } + + /** + * Registers the actual settings to the group they came from. + * @since 2.7.0 + * @param array $settings Existing registered settings + * @return array + */ + public function register_classic_settings( $settings ) { + $classic_sections = $this->page->get_sections(); + if ( empty( $classic_sections ) ) { + $classic_sections = array( '' ); + } + + foreach ( $classic_sections as $classic_section => $classic_section_label ) { + $classic_settings = $this->page->get_settings( $classic_section ); + foreach ( $classic_settings as $classic_setting ) { + $new_setting = array( + 'id' => $classic_setting['id'], + 'label' => ( ! empty( $classic_setting['title'] ) ? $classic_setting['title'] : '' ), + 'description' => ( ! empty( $classic_setting['desc'] ) ? $classic_setting['desc'] : '' ), + 'type' => $classic_setting['type'], + ); + if ( isset( $classic_setting['default'] ) ) { + $new_setting['default'] = $classic_setting['default']; + } + if ( isset( $classic_setting['options'] ) ) { + $new_setting['options'] = $classic_setting['options']; + } + if ( isset( $classic_setting['desc_tip'] ) ) { + if ( true === $classic_setting['desc_tip'] ) { + $new_setting['tip'] = $classic_setting['desc']; + } else if ( ! empty( $classic_setting['desc_tip'] ) ) { + $new_setting['tip'] = $classic_setting['desc_tip']; + } + } + $settings[] = $new_setting; + } + } + return $settings; + } +} + +/** + * Register full settings sections to a single group. + * @since 2.7.0 + * @param array $groups Existing registered groups. + * @return array + */ + function wc_settings_api_register_classic_groups( $groups ) { + $pages = WC_Admin_Settings::get_settings_pages(); + foreach ( $pages as $page ) { + $groups[] = array( + 'id' => $page->get_id(), + 'label' => $page->get_label(), + ); + new WC_Register_Classic_Settings( $page ); + } + return $groups; +} + +add_action( 'woocommerce_settings_groups', 'wc_settings_api_register_classic_groups' ); diff --git a/tests/framework/helpers/class-wc-helper-settings.php b/tests/framework/helpers/class-wc-helper-settings.php index 480e5e46add..2a042bc624b 100644 --- a/tests/framework/helpers/class-wc-helper-settings.php +++ b/tests/framework/helpers/class-wc-helper-settings.php @@ -13,7 +13,7 @@ class WC_Helper_Settings { */ public static function register() { add_filter( 'woocommerce_settings_groups', array( 'WC_Helper_Settings', 'register_groups' ) ); - add_filter( 'woocommerce_settings_test', array( 'WC_Helper_Settings', 'register_test_settings' ) ); + add_filter( 'woocommerce_settings-test', array( 'WC_Helper_Settings', 'register_test_settings' ) ); } /** @@ -52,11 +52,6 @@ class WC_Helper_Settings { * @return array */ public static function register_test_settings( $settings ) { - $settings[] = array( - 'id' => 'catalog_options', - 'label' => __( 'Shop & Product Pages', 'woocommerce' ), - 'type' => 'title', - ); $settings[] = array( 'id' => 'woocommerce_shop_page_display', 'label' => __( 'Shop Page Display', 'woocommerce' ), diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 18e3ad0177c..c43943e1634 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -56,28 +56,22 @@ class Settings extends \WC_Unit_Test_Case { $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( 3, count( $data ) ); - $this->check_get_group_response( $data[0], array( + $this->assertContains( array( 'id' => 'test', 'label' => 'Test Extension', 'parent_id' => '', 'description' => 'My awesome test settings.', - ) ); + 'sub_groups' => array( 'sub-test' ), + ), $data ); - $this->check_get_group_response( $data[1], array( + $this->assertContains( array( 'id' => 'sub-test', 'label' => 'Sub test', 'parent_id' => 'test', 'description' => '', - ) ); - - $this->check_get_group_response( $data[2], array( - 'id' => 'coupon-data', - 'label' => 'Coupon Data', - 'parent_id' => '', - 'description' => '', - ) ); + 'sub_groups' => array(), + ), $data ); } /** @@ -91,21 +85,6 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 401, $response->get_status() ); } - /** - * Test /settings/ correctly filters out bad values. - * Handles required fields and bogus fields. - * @since 2.7.0 - */ - public function test_get_groups_correctly_filters_values() { - wp_set_current_user( $this->user ); - - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings' ) ); - $data = $response->get_data(); - - $this->assertEquals( 'test', $data[0]['id'] ); - $this->assertArrayNotHasKey( 'bad', $data[0] ); - } - /** * Test groups schema. * @since 2.7.0 @@ -115,11 +94,12 @@ class Settings extends \WC_Unit_Test_Case { $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; - $this->assertEquals( 4, count( $properties ) ); + $this->assertEquals( 5, count( $properties ) ); $this->assertArrayHasKey( 'id', $properties ); $this->assertArrayHasKey( 'parent_id', $properties ); $this->assertArrayHasKey( 'label', $properties ); $this->assertArrayHasKey( 'description', $properties ); + $this->assertArrayHasKey( 'sub_groups', $properties ); } /** @@ -172,15 +152,17 @@ class Settings extends \WC_Unit_Test_Case { 'description' => '', ) ); + $this->assertEmpty( $data['sub_groups'] ); + // test getting a valid group with settings attached to it $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); $data = $response->get_data(); - $this->assertEquals( 2, count( $data['settings'] ) ); $this->assertEquals( 'woocommerce_shop_page_display', $data['settings'][0]['id'] ); $this->assertEmpty( $data['settings'][0]['value'] ); $this->assertEquals( 'woocommerce_enable_lightbox', $data['settings'][1]['id'] ); $this->assertEquals( 'yes', $data['settings'][1]['value'] ); + $this->assertEquals( array( 'sub-test' ), $data['sub_groups'] ); } /** @@ -428,6 +410,46 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( array( 'width' => '50px', 'height' => '50px', 'crop' => 1 ), $value ); } + /** + * Tests our classic setting registeration to make sure settings added for WP-Admin are available over the API. + * @since 2.7.0 + */ + public function test_classic_settings() { + wp_set_current_user( $this->user ); + + // Make sure the group is properly registered + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/products' ) ); + $data = $response->get_data(); + + $this->assertEquals( 'products', $data['id'] ); + $this->assertContains( array( + 'id' => 'woocommerce_downloads_require_login', + 'label' => 'Access Restriction', + 'description' => 'Downloads require login', + 'type' => 'checkbox', + 'default' => 'no', + 'tip' => 'This setting does not apply to guest purchases.', + 'value' => 'no', + ), $data['settings'] ); + + // test get single + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/products/woocommerce_dimension_unit' ) ); + $data = $response->get_data(); + + $this->assertEquals( 'cm', $data['default'] ); + + // test update + $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) ); + $request->set_body_params( array( + 'value' => 'yd', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'yd', $data['value'] ); + $this->assertEquals( 'yd', get_option(' woocommerce_dimension_unit' ) ); + } + /** * Ensure valid group data response. * @since 2.7.0 diff --git a/woocommerce.php b/woocommerce.php index 124fc2edaf1..f8a2879bbc6 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -226,6 +226,7 @@ final class WooCommerce { public function includes() { include_once( 'includes/class-wc-autoloader.php' ); include_once( 'includes/wc-core-functions.php' ); + include_once( 'includes/class-wc-register-classic-settings.php' ); include_once( 'includes/wc-widget-functions.php' ); include_once( 'includes/wc-webhook-functions.php' ); include_once( 'includes/class-wc-install.php' ); From 507e40fe1019c9ccd7880f78f2c6755344858e3e Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 28 Mar 2016 12:08:43 -0700 Subject: [PATCH 111/298] Remove settings api docs, moving to wiki --- settings-api-docs/README.md | 83 ---------------------------------- settings-api-docs/groups.md | 58 ------------------------ settings-api-docs/locations.md | 59 ------------------------ 3 files changed, 200 deletions(-) delete mode 100644 settings-api-docs/README.md delete mode 100644 settings-api-docs/groups.md delete mode 100644 settings-api-docs/locations.md diff --git a/settings-api-docs/README.md b/settings-api-docs/README.md deleted file mode 100644 index c5d06efa821..00000000000 --- a/settings-api-docs/README.md +++ /dev/null @@ -1,83 +0,0 @@ -# Settings API Proposal - -The Settings API is a set of WP-API endpoints that return information about WooCommerce settings. Settings can also be updated with the API. - -The API should be capable of handling settings in many different contexts including pages (WooCommerce > Settings), "metaboxes" (product data, coupon data), shipping zones, and be extendable to other contexts in the future. - -All settings are registered with PHP filters. Not through the REST API. The REST API is only for retrieving settings and updating them. - -## Locations -[locations.md](locations.md) - -## Groups -[groups.md](groups.md) - -# The below sections are being moved to their own doc files (and may change) as the API gets fleshed out. - -## /settings/$identifer - -Gets the actual settings to be displayed in a specific area. You can load settings for a specific group, or for a specific metabox. - -GET /settings/page:products:general would return settings for Settings > Products > General. -GET /settings/metabox:coupons would return settings for Coupons > Add New Coupon > Coupon Data metabox. - -To register settings: - - // The filter (page_products_general) should match the identifer for the area we are loading settings for. - apply_filters( 'woocommerce_settings_page_products_general', array( - array( - 'label' => __( 'Measurements', 'woocommerce' ), - 'type' => 'title', - 'id' => 'product_measurement_options' - ), - array( - 'label' => __( 'Weight Unit', 'woocommerce' ), - 'description' => __( 'This controls what unit you will define weights in.', 'woocommerce' ), - 'id' => 'woocommerce_weight_unit', - 'default' => 'kg', - 'type' => 'select', - 'options' => array( - 'kg' => __( 'kg', 'woocommerce' ), - 'g' => __( 'g', 'woocommerce' ), - 'lbs' => __( 'lbs', 'woocommerce' ), - 'oz' => __( 'oz', 'woocommerce' ), - ), - ) - ) ); - -Settings response: - - [ - { - "label": "Measurements", - "type": "title", - "id": "product_measurement_options" - }, - { - "label": "Weight Unit", - "description": "This controls what unit you will define weights in.", - "id": "woocommerce_weight_unit", - "default": "kg", - "type": "select", - "options": { - "kg": "kg", - "g": "g", - "lbs": "lbs", - "oz": "oz" - } - } - ] - -We should different form input types for 'type', text, textarea, select, radio, checkbox, ... - -## GET /settings/$identifer/$setting - -Get data for an individual setting. - -## PUT /settings/$identifer/$setting - -Update a setting by passing a new 'value' in the body. A success response will be returned. - -## PUT /settings/$identifer - -Update multiple settings at the same time with key => value pairs. A success response will be returned. diff --git a/settings-api-docs/groups.md b/settings-api-docs/groups.md deleted file mode 100644 index 60ddf19d7fd..00000000000 --- a/settings-api-docs/groups.md +++ /dev/null @@ -1,58 +0,0 @@ -# Groups - -## Basic Info - -Groups are settings thats are grouped together on setting pages _only_ (type=page). That means setting locations like metaboxes don't have groups. - -For example, a location would be the 'Products' page. -The products page would ave the following groups: 'General', 'Display', 'Inventory', and 'Downloadable Products'. - -![](https://cldup.com/qXlfpvItr6-3000x3000.png) - - { - "id": "general", - "label": "General", - "description": "" - } - -There are 3 fields that make up a group: - -* _id_: A unique identifier that can be used to link settings together. The identifiers for groups only need to be unique on a specific page, so you can have a 'general' group under 'Products' and a 'general' group under Shipping. Alphanumeric string that contains no spaces. Required. -* _label_: A human readable label. This is a translated string that can be used in the UI. Required. -* _description_: A human readable description. This is a translated string that can be used in the UI. Optional. - -Any other fields passed will be stripped out before the JSON response is sent back to the client. - -## Registering a group - -Groups can be registered with the `woocommerce_settings_groups_{$location_id}` filter: - - add_filter( 'woocommerce_settings_groups_products', function( $groups ) { - $groups[] = array( - 'id' => 'extra-settings', - 'label' => __( 'Extras', 'woocommerce-test-extension' ), - 'description' => '', - ); - return $groups; - } ); - - -## Endpoints - -There are no separate endpoints for groups. You can access a list of groups for a specific page/location by calling that location's endpoint. - -### GET /settings/locations/$id - - { - "id": "test", - "type": "page", - "label": "Test Extension", - "description": "My awesome test settings.", - "groups": [ - { - "id": "general", - "label": "General", - "description": "" - } - ] - } \ No newline at end of file diff --git a/settings-api-docs/locations.md b/settings-api-docs/locations.md deleted file mode 100644 index 287727402b1..00000000000 --- a/settings-api-docs/locations.md +++ /dev/null @@ -1,59 +0,0 @@ -# Locations - -## Basic Info - -Settings can be grouped together by location. - -A location is just a grouping of settings that all share a common 'location' key. -This is so you can pull all settings meant to be displayed together in a particular area. - -Example: - -In wp-admin there is a "Coupon Data" box on the "Add New Coupon" page. -The coupon data box is considered location and would be represented like so: - - { - "id": "coupon-data", - "type": "metabox", - "label": "Coupon Data", - "description": "" - } - - -There are 4 fields that make up all locations: - -* _id_: A unique identifier that can be used to link settings together. This shoud be a unique (for the whole system) value. Prefixing with your plugin slug is recommended for non-core changes. Alphanumeric string that contains no spaces. Required. -* _type_: Context for where the settings in this location are going to be displayed. Right now core accepts 'page' for settings pages (pages currently under WooCommerce > Settings), 'metabox' (for metabox grouped settings like Coupon Data - this name is subject to change as this API develops), and 'shipping-zone' for settings associated with shipping zone settings. Alphanumeric string that contains no spaces. Required, defaults to 'page'. -* _label_: A human readable label. This is a translated string that can be used in the UI. Required. -* _description_: A human readable description. This is a translated string that can be used in the UI. Optional. - -Any other fields passed will be stripped out before the JSON response is sent back to the client. - -Locations with type 'page' can also have an associated set of 'groups' which are sub sections/pages. See [groups.md](groups.md). -Pages will return an array of groups in their response. - -## Registering a Location - -Locations can be registered with the `woocommerce_settings_locations` filter: - - add_filter( 'woocommerce_settings_locations', function( $locations ) { - $locations[] = array( - 'id' => 'test-extension', - 'type' => 'page', - 'label' => __( 'Test Extension', 'woocommerce-test-extension' ), - 'description' => __( 'My awesome test settings.', 'woocommerce-test-extension' ), - ); - return $locations; - } ); - - -## Endpoints - -### GET /settings/locations - -Returns a list of all locations supported by WC. -There is an optional ?type parameter that allows you to return only locations for a specific context (like all page locations). - -### GET /settings/locations/$id - -Returns information on a single location + any associated groups. \ No newline at end of file From bf1ffbeff8884bb4c3213a3e510f7f68124d9a5e Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 28 Mar 2016 13:51:17 -0700 Subject: [PATCH 112/298] Fix how classic groups/settings are registered so that they are always avaiable when calling filters. --- includes/api/wc-rest-settings-controller.php | 3 +- .../class-wc-register-classic-settings.php | 40 +++++++++++-------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index dd1c48b973e..53c634f0fa6 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -537,6 +537,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return in_array( $type, array( 'text', 'email', 'number', 'color', 'password', 'textarea', 'select', 'multiselect', 'radio', 'checkbox', + 'multi_select_countries', 'image_width', ) ); } @@ -563,7 +564,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { protected function setting_defaults() { return array( 'id' => null, - 'label' => null, + 'label' => '', 'type' => null, 'description' => '', 'tip' => '', diff --git a/includes/class-wc-register-classic-settings.php b/includes/class-wc-register-classic-settings.php index 8cb0397f6eb..d5351b3406a 100644 --- a/includes/class-wc-register-classic-settings.php +++ b/includes/class-wc-register-classic-settings.php @@ -23,7 +23,22 @@ class WC_Register_Classic_Settings { */ public function __construct( $page ) { $this->page = $page; - add_filter( 'woocommerce_settings-' . $this->page->get_id() . '', array( $this, 'register_classic_settings' ) ); + add_filter( 'woocommerce_settings_groups', array( $this, 'register_classic_group' ) ); + add_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $this, 'register_classic_settings' ) ); + } + + /** + * Registers a setting group. + * @since 2.7.0 + * @param array $group + * @return array + */ + public function register_classic_group( $groups ) { + $groups[] = array( + 'id' => $this->page->get_id(), + 'label' => $this->page->get_label(), + ); + return $groups; } /** @@ -68,21 +83,14 @@ class WC_Register_Classic_Settings { } /** - * Register full settings sections to a single group. + * Register full classic settings to the REST API. * @since 2.7.0 - * @param array $groups Existing registered groups. - * @return array */ - function wc_settings_api_register_classic_groups( $groups ) { - $pages = WC_Admin_Settings::get_settings_pages(); - foreach ( $pages as $page ) { - $groups[] = array( - 'id' => $page->get_id(), - 'label' => $page->get_label(), - ); - new WC_Register_Classic_Settings( $page ); - } - return $groups; -} + function wc_settings_api_register_classic() { + $pages = WC_Admin_Settings::get_settings_pages(); + foreach ( $pages as $page ) { + new WC_Register_Classic_Settings( $page ); + } + } -add_action( 'woocommerce_settings_groups', 'wc_settings_api_register_classic_groups' ); +add_action( 'rest_api_init', 'wc_settings_api_register_classic' ); From 3f90fecd6e337c82d5dbbc50fa3db4f43d624c89 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 30 Mar 2016 09:46:20 -0700 Subject: [PATCH 113/298] Rename classic -> legacy --- .../class-wc-register-classic-settings.php | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/includes/class-wc-register-classic-settings.php b/includes/class-wc-register-classic-settings.php index d5351b3406a..ba314b0f030 100644 --- a/includes/class-wc-register-classic-settings.php +++ b/includes/class-wc-register-classic-settings.php @@ -12,19 +12,19 @@ if ( ! defined( 'ABSPATH' ) ) { * @package WooCommerce/Classes * @category Class */ -class WC_Register_Classic_Settings { +class WC_Register_Legacy_Settings { /** @var class Current settings class. Used to pull settings. */ protected $page; /** - * Hooks into the settings API and starts registering our classic settings. + * Hooks into the settings API and starts registering our settings registered via legacy hooks/filters. * @since 2.7.0 */ public function __construct( $page ) { $this->page = $page; - add_filter( 'woocommerce_settings_groups', array( $this, 'register_classic_group' ) ); - add_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $this, 'register_classic_settings' ) ); + add_filter( 'woocommerce_settings_groups', array( $this, 'register_legacy_group' ) ); + add_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $this, 'register_legacy_settings' ) ); } /** @@ -33,7 +33,7 @@ class WC_Register_Classic_Settings { * @param array $group * @return array */ - public function register_classic_group( $groups ) { + public function register_legacy_group( $groups ) { $groups[] = array( 'id' => $this->page->get_id(), 'label' => $this->page->get_label(), @@ -47,32 +47,32 @@ class WC_Register_Classic_Settings { * @param array $settings Existing registered settings * @return array */ - public function register_classic_settings( $settings ) { - $classic_sections = $this->page->get_sections(); - if ( empty( $classic_sections ) ) { - $classic_sections = array( '' ); + public function register_legacy_settings( $settings ) { + $legacy_sections = $this->page->get_sections(); + if ( empty( $legacy_sections ) ) { + $legacy_sections = array( '' ); } - foreach ( $classic_sections as $classic_section => $classic_section_label ) { - $classic_settings = $this->page->get_settings( $classic_section ); - foreach ( $classic_settings as $classic_setting ) { + foreach ( $legacy_sections as $legacy_section => $legacy_section_label ) { + $legacy_settings = $this->page->get_settings( $legacy_section ); + foreach ( $legacy_settings as $legacy_setting ) { $new_setting = array( - 'id' => $classic_setting['id'], - 'label' => ( ! empty( $classic_setting['title'] ) ? $classic_setting['title'] : '' ), - 'description' => ( ! empty( $classic_setting['desc'] ) ? $classic_setting['desc'] : '' ), - 'type' => $classic_setting['type'], + 'id' => $legacy_setting['id'], + 'label' => ( ! empty( $legacy_setting['title'] ) ? $legacy_setting['title'] : '' ), + 'description' => ( ! empty( $legacy_setting['desc'] ) ? $legacy_setting['desc'] : '' ), + 'type' => $legacy_setting['type'], ); - if ( isset( $classic_setting['default'] ) ) { - $new_setting['default'] = $classic_setting['default']; + if ( isset( $legacy_setting['default'] ) ) { + $new_setting['default'] = $legacy_setting['default']; } - if ( isset( $classic_setting['options'] ) ) { - $new_setting['options'] = $classic_setting['options']; + if ( isset( $legacy_setting['options'] ) ) { + $new_setting['options'] = $legacy_setting['options']; } - if ( isset( $classic_setting['desc_tip'] ) ) { - if ( true === $classic_setting['desc_tip'] ) { - $new_setting['tip'] = $classic_setting['desc']; - } else if ( ! empty( $classic_setting['desc_tip'] ) ) { - $new_setting['tip'] = $classic_setting['desc_tip']; + if ( isset( $legacy_setting['desc_tip'] ) ) { + if ( true === $legacy_setting['desc_tip'] ) { + $new_setting['tip'] = $legacy_setting['desc']; + } else if ( ! empty( $legacy_setting['desc_tip'] ) ) { + $new_setting['tip'] = $legacy_setting['desc_tip']; } } $settings[] = $new_setting; @@ -83,14 +83,14 @@ class WC_Register_Classic_Settings { } /** - * Register full classic settings to the REST API. + * Register legacy settings to the REST API. * @since 2.7.0 */ - function wc_settings_api_register_classic() { + function wc_settings_api_register_legacy() { $pages = WC_Admin_Settings::get_settings_pages(); foreach ( $pages as $page ) { - new WC_Register_Classic_Settings( $page ); + new WC_Register_Legacy_Settings( $page ); } } -add_action( 'rest_api_init', 'wc_settings_api_register_classic' ); +add_action( 'rest_api_init', 'wc_settings_api_register_legacy' ); From 97e7c293d5556018c3aa758056552164d821de09 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 30 Mar 2016 09:47:42 -0700 Subject: [PATCH 114/298] Rename classic settings file to legacy settings --- ...assic-settings.php => class-wc-register-legacy-settings.php} | 0 woocommerce.php | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename includes/{class-wc-register-classic-settings.php => class-wc-register-legacy-settings.php} (100%) diff --git a/includes/class-wc-register-classic-settings.php b/includes/class-wc-register-legacy-settings.php similarity index 100% rename from includes/class-wc-register-classic-settings.php rename to includes/class-wc-register-legacy-settings.php diff --git a/woocommerce.php b/woocommerce.php index f8a2879bbc6..7ca687dc438 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -226,7 +226,7 @@ final class WooCommerce { public function includes() { include_once( 'includes/class-wc-autoloader.php' ); include_once( 'includes/wc-core-functions.php' ); - include_once( 'includes/class-wc-register-classic-settings.php' ); + include_once( 'includes/class-wc-register-legacy-settings.php' ); include_once( 'includes/wc-widget-functions.php' ); include_once( 'includes/wc-webhook-functions.php' ); include_once( 'includes/class-wc-install.php' ); From fa27f277a15635f155b37d249be72711a7b4e70f Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 30 Mar 2016 10:29:57 -0700 Subject: [PATCH 115/298] Split settings and groups controllers into two separate files. --- includes/api/wc-rest-settings-base.php | 178 ++++++++ includes/api/wc-rest-settings-controller.php | 412 +----------------- .../wc-rest-settings-groups-controller.php | 257 +++++++++++ includes/class-wc-api.php | 3 + 4 files changed, 441 insertions(+), 409 deletions(-) create mode 100644 includes/api/wc-rest-settings-base.php create mode 100644 includes/api/wc-rest-settings-groups-controller.php diff --git a/includes/api/wc-rest-settings-base.php b/includes/api/wc-rest-settings-base.php new file mode 100644 index 00000000000..753ff0e0e35 --- /dev/null +++ b/includes/api/wc-rest-settings-base.php @@ -0,0 +1,178 @@ + rest_authorization_required_code() ) + ); + } + return true; + } + + /** + * Cleans a value before setting it. + * @since 2.7.0 + * @param array $setting WC Setting Array + * @param mixed $raw_value Raw value from PUT request + * @return mixed Sanitized value + */ + public function sanitize_setting_value( $setting, $raw_value ) { + switch ( $setting['type'] ) { + case 'checkbox' : + $default = ( ! empty( $setting['default'] ) ? $setting['default'] : 'no' ); + $value = ( in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : $default ); + break; + case 'email' : + $value = sanitize_email( $raw_value ); + $default = ( ! empty( $setting['default'] ) ? $setting['default'] : '' ); + $value = ( ! empty( $value ) ? $value : $default ); + break; + case 'textarea' : + $value = wp_kses( trim( $raw_value ), + array_merge( + array( + 'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true ) + ), + wp_kses_allowed_html( 'post' ) + ) + ); + break; + case 'multiselect' : + case 'multi_select_countries' : + $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) ); + break; + case 'image_width' : + $value = array(); + if ( isset( $raw_value['width'] ) ) { + $value['width'] = wc_clean( $raw_value['width'] ); + $value['height'] = wc_clean( $raw_value['height'] ); + $value['crop'] = isset( $raw_value['crop'] ) ? 1 : 0; + } else { + $value['width'] = $setting['default']['width']; + $value['height'] = $setting['default']['height']; + $value['crop'] = $setting['default']['crop']; + } + break; + default : + $value = wc_clean( $raw_value ); + break; + } + + // A couple fields changed in the REST API -- we can just pass these too so old filters still work + $setting['desc'] = ( ! empty( $setting['description'] ) ? $setting['description'] : '' ); + $setting['title'] = ( ! empty( $setting['label'] ) ? $setting['label'] : '' ); + + $value = apply_filters( 'woocommerce_admin_settings_sanitize_option', $value, $setting, $raw_value ); + $value = apply_filters( "woocommerce_admin_settings_sanitize_option_" . $setting['id'], $value, $setting, $raw_value ); + do_action( 'woocommerce_update_option', $setting ); + + return $value; + } + + /** + * Get a value from WP's settings API. + * @since 2.7.0 + * @param string $setting + * @param string $default + * @return mixed + */ + public function get_value( $setting, $default = '' ) { + if ( strstr( $setting, '[' ) ) { // Array value + parse_str( $setting, $setting_array ); + $setting = current( array_keys( $setting ) ); + $values = get_option( $setting, '' ); + $key = key( $setting_array[ $setting ] ); + if ( isset( $values[ $key ] ) ) { + $value = $values[ $key ]; + } else { + $value = null; + } + } else { // Single value + $value = get_option( $setting, null ); + } + + if ( is_array( $value ) ) { + $value = array_map( 'stripslashes', $value ); + } elseif ( ! is_null( $value ) ) { + $value = stripslashes( $value ); + } + + return $value === null ? $default : $value; + } + + /** + * Filters out bad values from the settings array/filter so we + * only return known values via the API. + * @since 2.7.0 + * @param array $setting + * @return array + */ + public function filter_setting( $setting ) { + $setting = array_intersect_key( + $setting, + array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) + ); + + if ( empty( $setting['options'] ) ) { + unset( $setting['options'] ); + } + + return $setting; + } + + /** + * Callback for allowed keys for each setting response. + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function allowed_setting_keys( $key ) { + return in_array( $key, array( + 'id', 'label', 'description', 'default', 'tip', + 'placeholder', 'type', 'options', 'value', + ) ); + } + + /** + * Boolean for if a setting type is a valid supported setting type. + * @since 2.7.0 + * @param string $type + * @return boolean + */ + public function is_setting_type_valid( $type ) { + return in_array( $type, array( + 'text', 'email', 'number', 'color', 'password', + 'textarea', 'select', 'multiselect', 'radio', 'checkbox', + 'multi_select_countries', 'image_width', + ) ); + } + +} diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index 53c634f0fa6..2da91e3cbff 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) { /** * REST API Settings Controller. - * Handles requests to the /settings endpoints. + * Handles requests to the /settings/$group/$setting endpoints. * * @author WooThemes * @category API @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Controller extends WP_Rest_Controller { +class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { /** * Route base. @@ -26,28 +26,6 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { * @since 2.7.0 */ public function register_routes() { - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base, array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_groups' ), - 'permission_callback' => array( $this, 'permissions_check' ), - ), - 'schema' => array( $this, 'group_schema' ), - ) ); - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)', array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_group' ), - 'permission_callback' => array( $this, 'permissions_check' ), - ), - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_settings' ), - 'permission_callback' => array( $this, 'permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'group_schema' ), - ) ); register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, @@ -64,70 +42,6 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { ) ); } - /** - * Makes sure the current user has access to the settings APIs. - * @since 2.7.0 - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function permissions_check( $request ) { - if ( ! current_user_can( 'manage_options' ) ) { - return new WP_Error( - 'woocommerce_rest_cannot_view', - __( 'Sorry, you cannot access settings.', 'woocommerce' ), - array( 'status' => rest_authorization_required_code() ) - ); - } - return true; - } - - /** - * Get all settings groups. - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|WP_REST_Response - */ - public function get_groups( $request ) { - $groups = apply_filters( 'woocommerce_settings_groups', array() ); - if ( empty( $groups ) ) { - return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); - } - - $defaults = $this->group_defaults(); - $filtered_groups = array(); - foreach ( $groups as $group ) { - $sub_groups = array(); - foreach ( $groups as $_group ) { - if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { - $sub_groups[] = $_group['id']; - } - } - $group['sub_groups'] = $sub_groups; - - $group = wp_parse_args( $group, $defaults ); - if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { - $filtered_groups[] = $this->filter_group( $group ); - } - } - - $response = rest_ensure_response( $filtered_groups ); - return $response; - } - - /** - * Return a single setting group and its settings. - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|WP_REST_Response - */ - public function get_group( $request ) { - $group = $this->_get_group_from_request( $request ); - if ( is_wp_error( $group ) ) { - return $group; - } - return rest_ensure_response( $group ); - } - /** * Return a single setting. * @since 2.7.0 @@ -160,89 +74,6 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return rest_ensure_response( $setting ); } - /** - * Update a multiple settings at once. - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|WP_REST_Response - */ - public function update_settings( $request ) { - $group = $this->_get_group_from_request( $request ); - if ( is_wp_error( $group ) ) { - return $group; - } - - foreach ( $group['settings'] as $array_key => $setting ) { - if ( isset( $request['values'][ $setting['id'] ] ) ) { - $value = $this->sanitize_setting_value( $setting, $request['values'][ $setting['id'] ] ); - $group['settings'][ $array_key ]['value'] = $value; - update_option( $setting['id'], $value ); - } - } - - return rest_ensure_response( $group ); - } - - /** - * Cleans a value before setting it. - * @since 2.7.0 - * @param array $setting WC Setting Array - * @param mixed $raw_value Raw value from PUT request - * @return mixed Sanitized value - */ - public function sanitize_setting_value( $setting, $raw_value ) { - switch ( $setting['type'] ) { - case 'checkbox' : - $default = ( ! empty( $setting['default'] ) ? $setting['default'] : 'no' ); - $value = ( in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : $default ); - break; - case 'email' : - $value = sanitize_email( $raw_value ); - $default = ( ! empty( $setting['default'] ) ? $setting['default'] : '' ); - $value = ( ! empty( $value ) ? $value : $default ); - break; - case 'textarea' : - $value = wp_kses( trim( $raw_value ), - array_merge( - array( - 'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true ) - ), - wp_kses_allowed_html( 'post' ) - ) - ); - break; - case 'multiselect' : - case 'multi_select_countries' : - $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) ); - break; - case 'image_width' : - $value = array(); - if ( isset( $raw_value['width'] ) ) { - $value['width'] = wc_clean( $raw_value['width'] ); - $value['height'] = wc_clean( $raw_value['height'] ); - $value['crop'] = isset( $raw_value['crop'] ) ? 1 : 0; - } else { - $value['width'] = $setting['default']['width']; - $value['height'] = $setting['default']['height']; - $value['crop'] = $setting['default']['crop']; - } - break; - default : - $value = wc_clean( $raw_value ); - break; - } - - // A couple fields changed in the REST API -- we can just pass these too so old filters still work - $setting['desc'] = ( ! empty( $setting['description'] ) ? $setting['description'] : '' ); - $setting['title'] = ( ! empty( $setting['label'] ) ? $setting['label'] : '' ); - - $value = apply_filters( 'woocommerce_admin_settings_sanitize_option', $value, $setting, $raw_value ); - $value = apply_filters( "woocommerce_admin_settings_sanitize_option_" . $setting['id'], $value, $setting, $raw_value ); - do_action( 'woocommerce_update_option', $setting ); - - return $value; - } - /** * Takes a valid request and returns back the corresponding setting array. * @since 2.7.0 @@ -264,114 +95,13 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { $setting = $this->filter_setting( $settings[ $array_key[0] ] ); $setting['value'] = $this->get_value( $setting['id'] ); - if ( ! $this->is_valid_type( $setting['type'] ) ) { + if ( ! $this->is_setting_type_valid( $setting['type'] ) ) { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } return $setting; } - /** - * Takes a valid request and returns back the corresponding group array. - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|array - */ - private function _get_group_from_request( $request ) { - $groups = apply_filters( 'woocommerce_settings_groups', array() ); - if ( empty( $groups ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $index_key = array_keys( wp_list_pluck( $groups, 'id' ), $request['group'] ); - if ( empty( $index_key ) || empty( $groups[ $index_key[0] ] ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - $group = wp_parse_args( $groups[ $index_key[0] ], $this->group_defaults() ); - if ( is_null( $group['id'] ) || is_null( $group['label'] ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); - } - - // Find sub groups - $sub_groups = array(); - foreach ( $groups as $_group ) { - if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { - $sub_groups[] = $_group['id']; - } - } - - $filtered_group = $this->filter_group( $group ); - $filtered_group['settings'] = array(); - $settings = apply_filters( 'woocommerce_settings-' . $group['id'], array() ); - - if ( ! empty( $settings ) ) { - foreach ( $settings as $setting ) { - $setting = $this->filter_setting( $setting ); - $setting['value'] = $this->get_value( $setting['id'] ); - if ( $this->is_valid_type( $setting['type'] ) ) { - $filtered_group['settings'][] = $setting; - } - } - } - - $filtered_group['sub_groups'] = $sub_groups; - - return $filtered_group; - } - - /** - * Get the groups schema, conforming to JSON Schema. - * @since 2.7.0 - * @return array - */ - public function group_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'settings-group', - 'type' => 'object', - 'properties' => array( - 'id' => array( - 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_title', - ), - ), - 'label' => array( - 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'description' => array( - 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'parent_id' => array( - 'description' => __( 'ID of parent grouping.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - 'sub_groups' => array( - 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), - 'type' => 'string', - 'arg_options' => array( - 'sanitize_callback' => 'sanitize_text_field', - ), - ), - ), - ); - - return $this->add_additional_fields_schema( $schema ); - } - /** * Get the settings schema, conforming to JSON Schema. * @since 2.7.0 @@ -439,140 +169,4 @@ class WC_Rest_Settings_Controller extends WP_Rest_Controller { return $this->add_additional_fields_schema( $schema ); } - /** - * Get a value from WP's settings API. - * @since 2.7.0 - * @param string $setting - * @param string $default - * @return mixed - */ - public function get_value( $setting, $default = '' ) { - if ( strstr( $setting, '[' ) ) { // Array value - parse_str( $setting, $setting_array ); - $setting = current( array_keys( $setting ) ); - $values = get_option( $setting, '' ); - $key = key( $setting_array[ $setting ] ); - if ( isset( $values[ $key ] ) ) { - $value = $values[ $key ]; - } else { - $value = null; - } - } else { // Single value - $value = get_option( $setting, null ); - } - - if ( is_array( $value ) ) { - $value = array_map( 'stripslashes', $value ); - } elseif ( ! is_null( $value ) ) { - $value = stripslashes( $value ); - } - - return $value === null ? $default : $value; - } - - /** - * Filters out bad values from the groups array/filter so we - * only return known values via the API. - * @since 2.7.0 - * @param array $group - * @return array - */ - public function filter_group( $group ) { - return array_intersect_key( - $group, - array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) - ); - } - - /** - * Filters out bad values from the settings array/filter so we - * only return known values via the API. - * @since 2.7.0 - * @param array $setting - * @return array - */ - public function filter_setting( $setting ) { - $setting = array_intersect_key( - $setting, - array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) - ); - - if ( empty( $setting['options'] ) ) { - unset( $setting['options'] ); - } - - return $setting; - } - - /** - * Callback for allowed keys for each group response. - * @since 2.7.0 - * @param string $key Key to check - * @return boolean - */ - public function allowed_group_keys( $key ) { - return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); - } - - /** - * Callback for allowed keys for each setting response. - * @since 2.7.0 - * @param string $key Key to check - * @return boolean - */ - public function allowed_setting_keys( $key ) { - return in_array( $key, array( - 'id', 'label', 'description', 'default', 'tip', - 'placeholder', 'type', 'options', 'value', - ) ); - } - - /** - * Boolean for if a setting type is a valid supported setting type. - * @since 2.7.0 - * @param string $type - * @return boolean - */ - public function is_valid_type( $type ) { - return in_array( $type, array( - 'text', 'email', 'number', 'color', 'password', - 'textarea', 'select', 'multiselect', 'radio', 'checkbox', - 'multi_select_countries', 'image_width', - ) ); - } - - /** - * Returns default settings for groups. null means the field is required. - * @since 2.7.0 - * @return array - */ - protected function group_defaults() { - return array( - 'id' => null, - 'label' => null, - 'description' => '', - 'parent_id' => '', - 'sub_groups' => array(), - ); - } - - /** - * Returns default settings for settings. null means the field is required. - * @since 2.7.0 - * @return array - */ - protected function setting_defaults() { - return array( - 'id' => null, - 'label' => '', - 'type' => null, - 'description' => '', - 'tip' => '', - 'placeholder' => '', - 'default' => '', - 'options' => array(), - 'value' => '', - ); - } - } diff --git a/includes/api/wc-rest-settings-groups-controller.php b/includes/api/wc-rest-settings-groups-controller.php new file mode 100644 index 00000000000..b3840282000 --- /dev/null +++ b/includes/api/wc-rest-settings-groups-controller.php @@ -0,0 +1,257 @@ + endpoints. + * + * @author WooThemes + * @category API + * @package WooCommerce/API + * @version 2.7.0 + * @since 2.7.0 + */ +class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { + + /** + * Register routes. + * @since 2.7.0 + */ + public function register_routes() { + register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_groups' ), + 'permission_callback' => array( $this, 'permissions_check' ), + ), + 'schema' => array( $this, 'group_schema' ), + ) ); + register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_group' ), + 'permission_callback' => array( $this, 'permissions_check' ), + ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_settings' ), + 'permission_callback' => array( $this, 'permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'group_schema' ), + ) ); + } + + /** + * Get all settings groups. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function get_groups( $request ) { + $groups = apply_filters( 'woocommerce_settings_groups', array() ); + if ( empty( $groups ) ) { + return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); + } + + $defaults = $this->group_defaults(); + $filtered_groups = array(); + foreach ( $groups as $group ) { + $sub_groups = array(); + foreach ( $groups as $_group ) { + if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { + $sub_groups[] = $_group['id']; + } + } + $group['sub_groups'] = $sub_groups; + + $group = wp_parse_args( $group, $defaults ); + if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { + $filtered_groups[] = $this->filter_group( $group ); + } + } + + $response = rest_ensure_response( $filtered_groups ); + return $response; + } + + /** + * Return a single setting group and its settings. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function get_group( $request ) { + $group = $this->_get_group_from_request( $request ); + if ( is_wp_error( $group ) ) { + return $group; + } + return rest_ensure_response( $group ); + } + + /** + * Update a multiple settings at once. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function update_settings( $request ) { + $group = $this->_get_group_from_request( $request ); + if ( is_wp_error( $group ) ) { + return $group; + } + + foreach ( $group['settings'] as $array_key => $setting ) { + if ( isset( $request['values'][ $setting['id'] ] ) ) { + $value = $this->sanitize_setting_value( $setting, $request['values'][ $setting['id'] ] ); + $group['settings'][ $array_key ]['value'] = $value; + update_option( $setting['id'], $value ); + } + } + + return rest_ensure_response( $group ); + } + + /** + * Takes a valid request and returns back the corresponding group array. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|array + */ + private function _get_group_from_request( $request ) { + $groups = apply_filters( 'woocommerce_settings_groups', array() ); + if ( empty( $groups ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $index_key = array_keys( wp_list_pluck( $groups, 'id' ), $request['group'] ); + if ( empty( $index_key ) || empty( $groups[ $index_key[0] ] ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $group = wp_parse_args( $groups[ $index_key[0] ], $this->group_defaults() ); + if ( is_null( $group['id'] ) || is_null( $group['label'] ) ) { + return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Find sub groups + $sub_groups = array(); + foreach ( $groups as $_group ) { + if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { + $sub_groups[] = $_group['id']; + } + } + + $filtered_group = $this->filter_group( $group ); + $filtered_group['settings'] = array(); + $settings = apply_filters( 'woocommerce_settings-' . $group['id'], array() ); + + if ( ! empty( $settings ) ) { + foreach ( $settings as $setting ) { + $setting = $this->filter_setting( $setting ); + $setting['value'] = $this->get_value( $setting['id'] ); + if ( $this->is_setting_type_valid( $setting['type'] ) ) { + $filtered_group['settings'][] = $setting; + } + } + } + + $filtered_group['sub_groups'] = $sub_groups; + + return $filtered_group; + } + + /** + * Get the groups schema, conforming to JSON Schema. + * @since 2.7.0 + * @return array + */ + public function group_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'settings-group', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'A unique identifier that can be used to link settings together.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_title', + ), + ), + 'label' => array( + 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'description' => array( + 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'parent_id' => array( + 'description' => __( 'ID of parent grouping.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'sub_groups' => array( + 'description' => __( 'IDs for settings sub groups.', 'woocommerce' ), + 'type' => 'string', + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Filters out bad values from the groups array/filter so we + * only return known values via the API. + * @since 2.7.0 + * @param array $group + * @return array + */ + public function filter_group( $group ) { + return array_intersect_key( + $group, + array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) + ); + } + + /** + * Callback for allowed keys for each group response. + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function allowed_group_keys( $key ) { + return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); + } + + /** + * Returns default settings for groups. null means the field is required. + * @since 2.7.0 + * @return array + */ + protected function group_defaults() { + return array( + 'id' => null, + 'label' => null, + 'description' => '', + 'parent_id' => '', + 'sub_groups' => array(), + ); + } + +} diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 81d21796a86..3292d5624d5 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -163,7 +163,9 @@ class WC_API extends WC_Legacy_API { include_once( 'api/class-wc-rest-report-sales-controller.php' ); include_once( 'api/class-wc-rest-report-top-sellers-controller.php' ); include_once( 'api/class-wc-rest-reports-controller.php' ); + include_once( 'api/wc-rest-settings-base.php' ); include_once( 'api/wc-rest-settings-controller.php' ); + include_once( 'api/wc-rest-settings-groups-controller.php' ); include_once( 'api/class-wc-rest-tax-classes-controller.php' ); include_once( 'api/class-wc-rest-taxes-controller.php' ); include_once( 'api/class-wc-rest-webhook-deliveries.php' ); @@ -193,6 +195,7 @@ class WC_API extends WC_Legacy_API { 'WC_REST_Report_Top_Sellers_Controller', 'WC_REST_Reports_Controller', 'WC_Rest_Settings_Controller', + 'WC_REST_Settings_Groups_Controller', 'WC_REST_Tax_Classes_Controller', 'WC_REST_Taxes_Controller', 'WC_REST_Webhook_Deliveries_Controller', From 3c35721beaf6d85450f2a9be297c32e9f0084c29 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 4 Apr 2016 10:34:14 -0700 Subject: [PATCH 116/298] Rename update_ functions to edit_item, and get_groups/get_settings to get_item and get_items per feedback. Also move the namespace into each class. --- includes/api/wc-rest-settings-controller.php | 15 ++++++++---- .../wc-rest-settings-groups-controller.php | 23 +++++++++++-------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index 2da91e3cbff..25d56e07308 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -15,6 +15,11 @@ if ( ! defined( 'ABSPATH' ) ) { */ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { + /** + * WP REST API namespace/version. + */ + protected $namespace = 'wc/v1'; + /** * Route base. * @var string @@ -26,15 +31,15 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { * @since 2.7.0 */ public function register_routes() { - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_setting' ), + 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'permissions_check' ), ), array( 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_setting' ), + 'callback' => array( $this, 'edit_item' ), 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), @@ -48,7 +53,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function get_setting( $request ) { + public function get_item( $request ) { $setting = $this->_get_setting_from_request( $request ); if ( is_wp_error( $setting ) ) { return $setting; @@ -62,7 +67,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function update_setting( $request ) { + public function edit_item( $request ) { $setting = $this->_get_setting_from_request( $request ); if ( is_wp_error( $setting ) ) { return $setting; diff --git a/includes/api/wc-rest-settings-groups-controller.php b/includes/api/wc-rest-settings-groups-controller.php index b3840282000..e44ba3d33bd 100644 --- a/includes/api/wc-rest-settings-groups-controller.php +++ b/includes/api/wc-rest-settings-groups-controller.php @@ -15,28 +15,33 @@ if ( ! defined( 'ABSPATH' ) ) { */ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { + /** + * WP REST API namespace/version. + */ + protected $namespace = 'wc/v1'; + /** * Register routes. * @since 2.7.0 */ public function register_routes() { - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base, array( + register_rest_route( $this->namespace, '/' . $this->rest_base, array( array( 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_groups' ), + 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'permissions_check' ), ), 'schema' => array( $this, 'group_schema' ), ) ); - register_rest_route( WC_API::REST_API_NAMESPACE, '/' . $this->rest_base . '/(?P[\w-]+)', array( + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_group' ), + 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'permissions_check' ), ), array( 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_settings' ), + 'callback' => array( $this, 'edit_item' ), 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), @@ -45,12 +50,12 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { } /** - * Get all settings groups. + * Get all settings groups items. * @since 2.7.0 * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function get_groups( $request ) { + public function get_items( $request ) { $groups = apply_filters( 'woocommerce_settings_groups', array() ); if ( empty( $groups ) ) { return new WP_Error( 'rest_setting_groups_empty', __( 'No setting groups have been registered.', 'woocommerce' ), array( 'status' => 500 ) ); @@ -83,7 +88,7 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function get_group( $request ) { + public function get_item( $request ) { $group = $this->_get_group_from_request( $request ); if ( is_wp_error( $group ) ) { return $group; @@ -97,7 +102,7 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function update_settings( $request ) { + public function edit_item( $request ) { $group = $this->_get_group_from_request( $request ); if ( is_wp_error( $group ) ) { return $group; From 56b769614d8d189b7b4a7b00a27ce01811ae6254 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Mon, 4 Apr 2016 12:09:32 -0700 Subject: [PATCH 117/298] edit_item should be update_item --- includes/api/wc-rest-settings-controller.php | 4 ++-- includes/api/wc-rest-settings-groups-controller.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/wc-rest-settings-controller.php index 25d56e07308..39ea067d0c1 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/wc-rest-settings-controller.php @@ -39,7 +39,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { ), array( 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'edit_item' ), + 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), @@ -67,7 +67,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function edit_item( $request ) { + public function update_item( $request ) { $setting = $this->_get_setting_from_request( $request ); if ( is_wp_error( $setting ) ) { return $setting; diff --git a/includes/api/wc-rest-settings-groups-controller.php b/includes/api/wc-rest-settings-groups-controller.php index e44ba3d33bd..0ab9a2d4976 100644 --- a/includes/api/wc-rest-settings-groups-controller.php +++ b/includes/api/wc-rest-settings-groups-controller.php @@ -41,7 +41,7 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { ), array( 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'edit_item' ), + 'callback' => array( $this, 'update_item' ), 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), @@ -102,7 +102,7 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ - public function edit_item( $request ) { + public function update_item( $request ) { $group = $this->_get_group_from_request( $request ); if ( is_wp_error( $group ) ) { return $group; From 7b78a6d9a7a51daca8b375e9ba8f3c4adc13f8cf Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Mon, 6 Jun 2016 14:59:54 -0300 Subject: [PATCH 118/298] Small tweaks to make it follow the REST API standards --- ...stract-wc-rest-settings-api-controller.php | 183 ++++++++++++++++++ ... => class-wc-rest-settings-controller.php} | 31 ++- ...ss-wc-rest-settings-groups-controller.php} | 114 ++++++----- includes/api/wc-rest-settings-base.php | 178 ----------------- includes/class-wc-api.php | 6 +- 5 files changed, 260 insertions(+), 252 deletions(-) create mode 100644 includes/abstracts/abstract-wc-rest-settings-api-controller.php rename includes/api/{wc-rest-settings-controller.php => class-wc-rest-settings-controller.php} (89%) rename includes/api/{wc-rest-settings-groups-controller.php => class-wc-rest-settings-groups-controller.php} (90%) delete mode 100644 includes/api/wc-rest-settings-base.php diff --git a/includes/abstracts/abstract-wc-rest-settings-api-controller.php b/includes/abstracts/abstract-wc-rest-settings-api-controller.php new file mode 100644 index 00000000000..207df4137a6 --- /dev/null +++ b/includes/abstracts/abstract-wc-rest-settings-api-controller.php @@ -0,0 +1,183 @@ + rest_authorization_required_code() ) + ); + } + + return true; + } + + /** + * Cleans a value before setting it. + * + * @since 2.7.0 + * + * @param array $setting WC Setting Array + * @param mixed $raw_value Raw value from PUT request + * @return mixed Sanitized value + */ + public function sanitize_setting_value( $setting, $raw_value ) { + switch ( $setting['type'] ) { + case 'checkbox' : + $default = ( ! empty( $setting['default'] ) ? $setting['default'] : 'no' ); + $value = ( in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : $default ); + break; + case 'email' : + $value = sanitize_email( $raw_value ); + $default = ( ! empty( $setting['default'] ) ? $setting['default'] : '' ); + $value = ( ! empty( $value ) ? $value : $default ); + break; + case 'textarea' : + $value = wp_kses( trim( $raw_value ), + array_merge( + array( + 'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true ) + ), + wp_kses_allowed_html( 'post' ) + ) + ); + break; + case 'multiselect' : + case 'multi_select_countries' : + $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) ); + break; + case 'image_width' : + $value = array(); + if ( isset( $raw_value['width'] ) ) { + $value['width'] = wc_clean( $raw_value['width'] ); + $value['height'] = wc_clean( $raw_value['height'] ); + $value['crop'] = isset( $raw_value['crop'] ) ? 1 : 0; + } else { + $value['width'] = $setting['default']['width']; + $value['height'] = $setting['default']['height']; + $value['crop'] = $setting['default']['crop']; + } + break; + default : + $value = wc_clean( $raw_value ); + break; + } + + // A couple fields changed in the REST API -- we can just pass these too so old filters still work + $setting['desc'] = ( ! empty( $setting['description'] ) ? $setting['description'] : '' ); + $setting['title'] = ( ! empty( $setting['label'] ) ? $setting['label'] : '' ); + + $value = apply_filters( 'woocommerce_admin_settings_sanitize_option', $value, $setting, $raw_value ); + $value = apply_filters( "woocommerce_admin_settings_sanitize_option_" . $setting['id'], $value, $setting, $raw_value ); + do_action( 'woocommerce_update_option', $setting ); + + return $value; + } + + /** + * Get a value from WP's settings API. + * + * @since 2.7.0 + * @param string $setting + * @param string $default + * @return mixed + */ + public function get_value( $setting, $default = '' ) { + if ( strstr( $setting, '[' ) ) { // Array value. + parse_str( $setting, $setting_array ); + $setting = current( array_keys( $setting ) ); + $values = get_option( $setting, '' ); + $key = key( $setting_array[ $setting ] ); + $value = isset( $values[ $key ] ) ? $values[ $key ] : null; + } else { // Single value. + $value = get_option( $setting, null ); + } + + if ( is_array( $value ) ) { + $value = array_map( 'stripslashes', $value ); + } elseif ( ! is_null( $value ) ) { + $value = stripslashes( $value ); + } + + return $value === null ? $default : $value; + } + + /** + * Filters out bad values from the settings array/filter so we + * only return known values via the API. + * + * @since 2.7.0 + * @param array $setting + * @return array + */ + public function filter_setting( $setting ) { + $setting = array_intersect_key( + $setting, + array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) + ); + + if ( empty( $setting['options'] ) ) { + unset( $setting['options'] ); + } + + return $setting; + } + + /** + * Callback for allowed keys for each setting response. + * + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function allowed_setting_keys( $key ) { + return in_array( $key, array( + 'id', 'label', 'description', 'default', 'tip', + 'placeholder', 'type', 'options', 'value', + ) ); + } + + /** + * Boolean for if a setting type is a valid supported setting type. + * + * @since 2.7.0 + * @param string $type + * @return boolean + */ + public function is_setting_type_valid( $type ) { + return in_array( $type, array( + 'text', 'email', 'number', 'color', 'password', + 'textarea', 'select', 'multiselect', 'radio', 'checkbox', + 'multi_select_countries', 'image_width', + ) ); + } +} diff --git a/includes/api/wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php similarity index 89% rename from includes/api/wc-rest-settings-controller.php rename to includes/api/class-wc-rest-settings-controller.php index 39ea067d0c1..1df6100997e 100644 --- a/includes/api/wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -13,19 +13,13 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { +class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { /** * WP REST API namespace/version. */ protected $namespace = 'wc/v1'; - /** - * Route base. - * @var string - */ - protected $rest_base = 'settings'; - /** * Register routes. * @since 2.7.0 @@ -43,7 +37,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), - 'schema' => array( $this, 'setting_schema' ), + 'schema' => array( $this, 'get_public_item_schema' ), ) ); } @@ -54,7 +48,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { * @return WP_Error|WP_REST_Response */ public function get_item( $request ) { - $setting = $this->_get_setting_from_request( $request ); + $setting = $this->prepare_item_for_response( $request ); if ( is_wp_error( $setting ) ) { return $setting; } @@ -68,7 +62,7 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { * @return WP_Error|WP_REST_Response */ public function update_item( $request ) { - $setting = $this->_get_setting_from_request( $request ); + $setting = $this->prepare_item_for_response( $request ); if ( is_wp_error( $setting ) ) { return $setting; } @@ -80,12 +74,13 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { } /** - * Takes a valid request and returns back the corresponding setting array. - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|array + * Prepare a report sales object for serialization. + * + * @param null $_ + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. */ - private function _get_setting_from_request( $request ) { + public function prepare_item_for_response( $_, $request ) { if ( empty( $request['group'] ) || empty( $request['setting'] ) ) { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } @@ -109,10 +104,11 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { /** * Get the settings schema, conforming to JSON Schema. - * @since 2.7.0 + * + * @since 2.7.0 * @return array */ - public function setting_schema() { + public function get_item_schema() { $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'settings', @@ -173,5 +169,4 @@ class WC_Rest_Settings_Controller extends WP_Rest_Settings_Base { return $this->add_additional_fields_schema( $schema ); } - } diff --git a/includes/api/wc-rest-settings-groups-controller.php b/includes/api/class-wc-rest-settings-groups-controller.php similarity index 90% rename from includes/api/wc-rest-settings-groups-controller.php rename to includes/api/class-wc-rest-settings-groups-controller.php index 0ab9a2d4976..0cb38048d4a 100644 --- a/includes/api/wc-rest-settings-groups-controller.php +++ b/includes/api/class-wc-rest-settings-groups-controller.php @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { +class WC_Rest_Settings_Groups_Controller extends WC_REST_Settings_API_Controller { /** * WP REST API namespace/version. @@ -31,8 +31,9 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'permissions_check' ), ), - 'schema' => array( $this, 'group_schema' ), + 'schema' => array( $this, 'get_public_item_schema' ), ) ); + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, @@ -45,12 +46,13 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), - 'schema' => array( $this, 'group_schema' ), + 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** * Get all settings groups items. + * * @since 2.7.0 * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response @@ -84,12 +86,13 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { /** * Return a single setting group and its settings. + * * @since 2.7.0 * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ public function get_item( $request ) { - $group = $this->_get_group_from_request( $request ); + $group = $this->prepare_item_for_response( $request ); if ( is_wp_error( $group ) ) { return $group; } @@ -98,12 +101,13 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { /** * Update a multiple settings at once. + * * @since 2.7.0 * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response */ public function update_item( $request ) { - $group = $this->_get_group_from_request( $request ); + $group = $this->prepare_item_for_response( $request ); if ( is_wp_error( $group ) ) { return $group; } @@ -120,12 +124,13 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { } /** - * Takes a valid request and returns back the corresponding group array. - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|array + * Prepare a report sales object for serialization. + * + * @param null $_ + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. */ - private function _get_group_from_request( $request ) { + public function prepare_item_for_response( $_, $request ) { $groups = apply_filters( 'woocommerce_settings_groups', array() ); if ( empty( $groups ) ) { return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); @@ -141,7 +146,7 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } - // Find sub groups + // Find sub groups. $sub_groups = array(); foreach ( $groups as $_group ) { if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { @@ -169,11 +174,54 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { } /** - * Get the groups schema, conforming to JSON Schema. + * Filters out bad values from the groups array/filter so we + * only return known values via the API. + * + * @since 2.7.0 + * @param array $group + * @return array + */ + public function filter_group( $group ) { + return array_intersect_key( + $group, + array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) + ); + } + + /** + * Callback for allowed keys for each group response. + * + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function allowed_group_keys( $key ) { + return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); + } + + /** + * Returns default settings for groups. null means the field is required. + * * @since 2.7.0 * @return array */ - public function group_schema() { + protected function group_defaults() { + return array( + 'id' => null, + 'label' => null, + 'description' => '', + 'parent_id' => '', + 'sub_groups' => array(), + ); + } + + /** + * Get the groups schema, conforming to JSON Schema. + * + * @since 2.7.0 + * @return array + */ + public function get_item_schema() { $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'settings-group', @@ -219,44 +267,4 @@ class WC_Rest_Settings_Groups_Controller extends WP_Rest_Settings_Base { return $this->add_additional_fields_schema( $schema ); } - - /** - * Filters out bad values from the groups array/filter so we - * only return known values via the API. - * @since 2.7.0 - * @param array $group - * @return array - */ - public function filter_group( $group ) { - return array_intersect_key( - $group, - array_flip( array_filter( array_keys( $group ), array( $this, 'allowed_group_keys' ) ) ) - ); - } - - /** - * Callback for allowed keys for each group response. - * @since 2.7.0 - * @param string $key Key to check - * @return boolean - */ - public function allowed_group_keys( $key ) { - return in_array( $key, array( 'id', 'label', 'description', 'parent_id', 'sub_groups' ) ); - } - - /** - * Returns default settings for groups. null means the field is required. - * @since 2.7.0 - * @return array - */ - protected function group_defaults() { - return array( - 'id' => null, - 'label' => null, - 'description' => '', - 'parent_id' => '', - 'sub_groups' => array(), - ); - } - } diff --git a/includes/api/wc-rest-settings-base.php b/includes/api/wc-rest-settings-base.php deleted file mode 100644 index 753ff0e0e35..00000000000 --- a/includes/api/wc-rest-settings-base.php +++ /dev/null @@ -1,178 +0,0 @@ - rest_authorization_required_code() ) - ); - } - return true; - } - - /** - * Cleans a value before setting it. - * @since 2.7.0 - * @param array $setting WC Setting Array - * @param mixed $raw_value Raw value from PUT request - * @return mixed Sanitized value - */ - public function sanitize_setting_value( $setting, $raw_value ) { - switch ( $setting['type'] ) { - case 'checkbox' : - $default = ( ! empty( $setting['default'] ) ? $setting['default'] : 'no' ); - $value = ( in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : $default ); - break; - case 'email' : - $value = sanitize_email( $raw_value ); - $default = ( ! empty( $setting['default'] ) ? $setting['default'] : '' ); - $value = ( ! empty( $value ) ? $value : $default ); - break; - case 'textarea' : - $value = wp_kses( trim( $raw_value ), - array_merge( - array( - 'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true ) - ), - wp_kses_allowed_html( 'post' ) - ) - ); - break; - case 'multiselect' : - case 'multi_select_countries' : - $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) ); - break; - case 'image_width' : - $value = array(); - if ( isset( $raw_value['width'] ) ) { - $value['width'] = wc_clean( $raw_value['width'] ); - $value['height'] = wc_clean( $raw_value['height'] ); - $value['crop'] = isset( $raw_value['crop'] ) ? 1 : 0; - } else { - $value['width'] = $setting['default']['width']; - $value['height'] = $setting['default']['height']; - $value['crop'] = $setting['default']['crop']; - } - break; - default : - $value = wc_clean( $raw_value ); - break; - } - - // A couple fields changed in the REST API -- we can just pass these too so old filters still work - $setting['desc'] = ( ! empty( $setting['description'] ) ? $setting['description'] : '' ); - $setting['title'] = ( ! empty( $setting['label'] ) ? $setting['label'] : '' ); - - $value = apply_filters( 'woocommerce_admin_settings_sanitize_option', $value, $setting, $raw_value ); - $value = apply_filters( "woocommerce_admin_settings_sanitize_option_" . $setting['id'], $value, $setting, $raw_value ); - do_action( 'woocommerce_update_option', $setting ); - - return $value; - } - - /** - * Get a value from WP's settings API. - * @since 2.7.0 - * @param string $setting - * @param string $default - * @return mixed - */ - public function get_value( $setting, $default = '' ) { - if ( strstr( $setting, '[' ) ) { // Array value - parse_str( $setting, $setting_array ); - $setting = current( array_keys( $setting ) ); - $values = get_option( $setting, '' ); - $key = key( $setting_array[ $setting ] ); - if ( isset( $values[ $key ] ) ) { - $value = $values[ $key ]; - } else { - $value = null; - } - } else { // Single value - $value = get_option( $setting, null ); - } - - if ( is_array( $value ) ) { - $value = array_map( 'stripslashes', $value ); - } elseif ( ! is_null( $value ) ) { - $value = stripslashes( $value ); - } - - return $value === null ? $default : $value; - } - - /** - * Filters out bad values from the settings array/filter so we - * only return known values via the API. - * @since 2.7.0 - * @param array $setting - * @return array - */ - public function filter_setting( $setting ) { - $setting = array_intersect_key( - $setting, - array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) - ); - - if ( empty( $setting['options'] ) ) { - unset( $setting['options'] ); - } - - return $setting; - } - - /** - * Callback for allowed keys for each setting response. - * @since 2.7.0 - * @param string $key Key to check - * @return boolean - */ - public function allowed_setting_keys( $key ) { - return in_array( $key, array( - 'id', 'label', 'description', 'default', 'tip', - 'placeholder', 'type', 'options', 'value', - ) ); - } - - /** - * Boolean for if a setting type is a valid supported setting type. - * @since 2.7.0 - * @param string $type - * @return boolean - */ - public function is_setting_type_valid( $type ) { - return in_array( $type, array( - 'text', 'email', 'number', 'color', 'password', - 'textarea', 'select', 'multiselect', 'radio', 'checkbox', - 'multi_select_countries', 'image_width', - ) ); - } - -} diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 3292d5624d5..eb278b6f92c 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -143,6 +143,7 @@ class WC_API extends WC_Legacy_API { // Abstract controllers. include_once( 'abstracts/abstract-wc-rest-controller.php' ); include_once( 'abstracts/abstract-wc-rest-posts-controller.php' ); + include_once( 'abstracts/abstract-wc-rest-settings-api-controller.php' ); include_once( 'abstracts/abstract-wc-rest-terms-controller.php' ); include_once( 'abstracts/abstract-wc-settings-api.php' ); @@ -163,9 +164,8 @@ class WC_API extends WC_Legacy_API { include_once( 'api/class-wc-rest-report-sales-controller.php' ); include_once( 'api/class-wc-rest-report-top-sellers-controller.php' ); include_once( 'api/class-wc-rest-reports-controller.php' ); - include_once( 'api/wc-rest-settings-base.php' ); - include_once( 'api/wc-rest-settings-controller.php' ); - include_once( 'api/wc-rest-settings-groups-controller.php' ); + include_once( 'api/class-wc-rest-settings-controller.php' ); + include_once( 'api/class-wc-rest-settings-groups-controller.php' ); include_once( 'api/class-wc-rest-tax-classes-controller.php' ); include_once( 'api/class-wc-rest-taxes-controller.php' ); include_once( 'api/class-wc-rest-webhook-deliveries.php' ); From b69c9814af7518d9cd1f9053f35812c24b566071 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 6 Jun 2016 17:00:09 -0600 Subject: [PATCH 119/298] Match parent signature of prepare_item_for_response(), add getter method for settings. --- .../api/class-wc-rest-settings-controller.php | 76 ++++++++++++------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index 1df6100997e..adbca2995a9 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -48,52 +48,38 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { * @return WP_Error|WP_REST_Response */ public function get_item( $request ) { - $setting = $this->prepare_item_for_response( $request ); - if ( is_wp_error( $setting ) ) { - return $setting; - } - return rest_ensure_response( $setting ); - } + $setting = $this->get_setting( $request['group'], $request['setting'] ); - /** - * Update a single setting. - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $setting = $this->prepare_item_for_response( $request ); if ( is_wp_error( $setting ) ) { return $setting; } - $value = $setting['value'] = $this->sanitize_setting_value( $setting, $request['value'] ); - update_option( $setting['id'], $value ); + $response = $this->prepare_item_for_response( $setting, $request ); - return rest_ensure_response( $setting ); + return rest_ensure_response( $response ); } /** - * Prepare a report sales object for serialization. + * Get setting data. * - * @param null $_ - * @param WP_REST_Request $request Request object. - * @return WP_REST_Response $response Response data. + * @param string $group Group ID. + * @param string $setting_id Setting ID. + * + * @return stdClass|WP_Error */ - public function prepare_item_for_response( $_, $request ) { - if ( empty( $request['group'] ) || empty( $request['setting'] ) ) { + public function get_setting( $group, $setting_id ) { + if ( empty( $group ) || empty( $setting_id ) ) { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } - $settings = apply_filters( 'woocommerce_settings-' . $request['group'], array() ); - $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $request['setting'] ); + $settings = apply_filters( 'woocommerce_settings-' . $group, array() ); + $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id ); if ( empty( $array_key ) ) { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } - $setting = $this->filter_setting( $settings[ $array_key[0] ] ); - $setting['value'] = $this->get_value( $setting['id'] ); + $setting = $settings[ $array_key[0] ]; if ( ! $this->is_setting_type_valid( $setting['type'] ) ) { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); @@ -102,6 +88,42 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { return $setting; } + /** + * Update a single setting in a group. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $setting = $this->get_setting( $request['group'], $request['setting'] ); + + if ( is_wp_error( $setting ) ) { + return $setting; + } + + $response = $this->prepare_item_for_response( $setting, $request ); + $value = $this->sanitize_setting_value( $setting, $request['value'] ); + $response['value'] = $value; + + update_option( $setting['id'], $value ); + + return rest_ensure_response( $response ); + } + + /** + * Prepare a single setting object for response. + * + * @param object $item Setting object. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response Response data. + */ + public function prepare_item_for_response( $item, $request ) { + $setting = $this->filter_setting( $item ); + $setting['value'] = $this->get_value( $setting['id'] ); + + return $setting; + } + /** * Get the settings schema, conforming to JSON Schema. * From 519be1c519b639ae95fe89761606de0cc4ecd37f Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 6 Jun 2016 18:50:11 -0600 Subject: [PATCH 120/298] Add Settings controller getter method for all group settings. --- .../api/class-wc-rest-settings-controller.php | 44 +++++++++++++++++-- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index adbca2995a9..473d84a291f 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -59,20 +59,56 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { return rest_ensure_response( $response ); } + /** + * Get all settings in a group. + * + * @param string $group_id Group ID. + * + * @return array|WP_Error + */ + public function get_group_settings( $group_id ) { + if ( empty( $group_id ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); + + if ( empty( $settings ) ) { + return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $filtered_settings = array(); + + foreach ( $settings as $setting ) { + $setting = $this->filter_setting( $setting ); + if ( $this->is_setting_type_valid( $setting['type'] ) ) { + $setting['value'] = $this->get_value( $setting['id'] ); + $filtered_settings[] = $setting; + } + } + + return $filtered_settings; + } + /** * Get setting data. * - * @param string $group Group ID. + * @param string $group_id Group ID. * @param string $setting_id Setting ID. * * @return stdClass|WP_Error */ - public function get_setting( $group, $setting_id ) { - if ( empty( $group ) || empty( $setting_id ) ) { + public function get_setting( $group_id, $setting_id ) { + if ( empty( $setting_id ) ) { return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); } - $settings = apply_filters( 'woocommerce_settings-' . $group, array() ); + $settings = $this->get_group_settings( $group_id ); + + if ( is_wp_error( $settings ) ) { + return $settings; + } + $array_key = array_keys( wp_list_pluck( $settings, 'id' ), $setting_id ); if ( empty( $array_key ) ) { From b2c628f0d86343b34e81e948f5d3b9eacef03d74 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 6 Jun 2016 19:06:02 -0600 Subject: [PATCH 121/298] =?UTF-8?q?Move=20settings=20group=20endpoint=20to?= =?UTF-8?q?=20Settings=20controller=20and=20only=20return=20settings-schem?= =?UTF-8?q?a=E2=80=99d=20items.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/class-wc-rest-settings-controller.php | 25 +++++++++++++++++++ ...ass-wc-rest-settings-groups-controller.php | 5 ---- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index 473d84a291f..4eda627fc66 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -25,6 +25,15 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { * @since 2.7.0 */ public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, @@ -59,6 +68,22 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { return rest_ensure_response( $response ); } + /** + * Return all settings in a group. + * @since 2.7.0 + * @param WP_REST_Request $request + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $settings = $this->get_group_settings( $request['group'] ); + + if ( is_wp_error( $settings ) ) { + return $settings; + } + + return rest_ensure_response( $settings ); + } + /** * Get all settings in a group. * diff --git a/includes/api/class-wc-rest-settings-groups-controller.php b/includes/api/class-wc-rest-settings-groups-controller.php index 0cb38048d4a..9f3f6004adf 100644 --- a/includes/api/class-wc-rest-settings-groups-controller.php +++ b/includes/api/class-wc-rest-settings-groups-controller.php @@ -35,11 +35,6 @@ class WC_Rest_Settings_Groups_Controller extends WC_REST_Settings_API_Controller ) ); register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( - array( - 'methods' => WP_REST_Server::READABLE, - 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'permissions_check' ), - ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), From 7c119ac268b4e71670689eb93d60d2c9fd7787c0 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 7 Jun 2016 09:22:35 -0600 Subject: [PATCH 122/298] Add _links to /settings/ and /settings// responses. --- .../api/class-wc-rest-settings-controller.php | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index 4eda627fc66..1a2b9449bd2 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -81,7 +81,15 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { return $settings; } - return rest_ensure_response( $settings ); + $data = array(); + + foreach ( $settings as $setting_obj ) { + $setting = $this->prepare_item_for_response( $setting_obj, $request ); + $setting = $this->prepare_response_for_collection( $setting ); + $data[] = $setting; + } + + return rest_ensure_response( $data ); } /** @@ -179,10 +187,39 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { * @return WP_REST_Response $response Response data. */ public function prepare_item_for_response( $item, $request ) { - $setting = $this->filter_setting( $item ); - $setting['value'] = $this->get_value( $setting['id'] ); + $data = $this->filter_setting( $item ); + $data['value'] = $this->get_value( $data['id'] ); - return $setting; + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $data['id'], $request['group'] ) ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param string $setting_id Setting ID. + * @param string $group_id Group ID. + * @return array Links for the given setting. + */ + protected function prepare_links( $setting_id, $group_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $group_id; + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $setting_id ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + ); + + return $links; } /** From 24014a5d042a290a19aa40f92aec5ff0e292f83c Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 7 Jun 2016 16:53:52 -0600 Subject: [PATCH 123/298] Move bulk settings updating to the Settings controller, following existing batch endpoint patterns. --- .../api/class-wc-rest-settings-controller.php | 49 ++++++++++++++++--- ...ass-wc-rest-settings-groups-controller.php | 34 ------------- 2 files changed, 43 insertions(+), 40 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index 1a2b9449bd2..91bdec0a962 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -34,7 +34,17 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { 'schema' => array( $this, 'get_public_item_schema' ), ) ); - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)/(?P[\w-]+)', array( array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), @@ -57,7 +67,7 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { * @return WP_Error|WP_REST_Response */ public function get_item( $request ) { - $setting = $this->get_setting( $request['group'], $request['setting'] ); + $setting = $this->get_setting( $request['group'], $request['id'] ); if ( is_wp_error( $setting ) ) { return $setting; @@ -157,6 +167,32 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { return $setting; } + /** + * Bulk create, update and delete items. + * + * @param WP_REST_Request $request Full details about the request. + * @return array Of WP_Error or WP_REST_Response. + */ + public function batch_items( $request ) { + // Get the request params. + $items = array_filter( $request->get_params() ); + + /* + * Since our batch settings update is group-specific and matches based on the route, + * we inject the URL parameters (containing group) into the batch items + */ + if ( ! empty( $items['update'] ) ) { + $to_update = array(); + foreach ( $items['update'] as $item ) { + $to_update[] = array_merge( $request->get_url_params(), $item ); + } + $request = new WP_REST_Request( $request->get_method() ); + $request->set_body_params( array( 'update' => $to_update ) ); + } + + return parent::batch_items( $request ); + } + /** * Update a single setting in a group. * @since 2.7.0 @@ -164,15 +200,16 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { * @return WP_Error|WP_REST_Response */ public function update_item( $request ) { - $setting = $this->get_setting( $request['group'], $request['setting'] ); + $setting = $this->get_setting( $request['group'], $request['id'] ); if ( is_wp_error( $setting ) ) { return $setting; } - $response = $this->prepare_item_for_response( $setting, $request ); - $value = $this->sanitize_setting_value( $setting, $request['value'] ); - $response['value'] = $value; + $response = $this->prepare_item_for_response( $setting, $request ); + $value = $this->sanitize_setting_value( $setting, $request['value'] ); + + $response->set_data( array_merge( $response->get_data(), compact( 'value' ) ) ); update_option( $setting['id'], $value ); diff --git a/includes/api/class-wc-rest-settings-groups-controller.php b/includes/api/class-wc-rest-settings-groups-controller.php index 9f3f6004adf..310f00b8895 100644 --- a/includes/api/class-wc-rest-settings-groups-controller.php +++ b/includes/api/class-wc-rest-settings-groups-controller.php @@ -33,16 +33,6 @@ class WC_Rest_Settings_Groups_Controller extends WC_REST_Settings_API_Controller ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); - - register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\w-]+)', array( - array( - 'methods' => WP_REST_Server::EDITABLE, - 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'permissions_check' ), - 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), - ), - 'schema' => array( $this, 'get_public_item_schema' ), - ) ); } /** @@ -94,30 +84,6 @@ class WC_Rest_Settings_Groups_Controller extends WC_REST_Settings_API_Controller return rest_ensure_response( $group ); } - /** - * Update a multiple settings at once. - * - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|WP_REST_Response - */ - public function update_item( $request ) { - $group = $this->prepare_item_for_response( $request ); - if ( is_wp_error( $group ) ) { - return $group; - } - - foreach ( $group['settings'] as $array_key => $setting ) { - if ( isset( $request['values'][ $setting['id'] ] ) ) { - $value = $this->sanitize_setting_value( $setting, $request['values'][ $setting['id'] ] ); - $group['settings'][ $array_key ]['value'] = $value; - update_option( $setting['id'], $value ); - } - } - - return rest_ensure_response( $group ); - } - /** * Prepare a report sales object for serialization. * From 9d9d318727314d803394ad6211b0492fe4a49b5f Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 7 Jun 2016 16:54:28 -0600 Subject: [PATCH 124/298] Handle select options in setting sanitization function. --- .../abstracts/abstract-wc-rest-settings-api-controller.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/includes/abstracts/abstract-wc-rest-settings-api-controller.php b/includes/abstracts/abstract-wc-rest-settings-api-controller.php index 207df4137a6..1d148dd8487 100644 --- a/includes/abstracts/abstract-wc-rest-settings-api-controller.php +++ b/includes/abstracts/abstract-wc-rest-settings-api-controller.php @@ -87,6 +87,11 @@ class WC_REST_Settings_API_Controller extends WC_REST_Controller { $value['crop'] = $setting['default']['crop']; } break; + case 'select': + $options = array_keys( $setting['options'] ); + $default = ( empty( $setting['default'] ) ? $options[0] : $setting['default'] ); + $value = in_array( $raw_value, $options ) ? $raw_value : $default; + break; default : $value = wc_clean( $raw_value ); break; From bbc5aec1d122cf020e1b01f4451e7edd0a2712e6 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 8 Jun 2016 10:25:07 -0600 Subject: [PATCH 125/298] =?UTF-8?q?Don=E2=80=99t=20register=20legacy=20set?= =?UTF-8?q?tings=20without=20IDs.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/class-wc-register-legacy-settings.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/class-wc-register-legacy-settings.php b/includes/class-wc-register-legacy-settings.php index ba314b0f030..a9d262ac632 100644 --- a/includes/class-wc-register-legacy-settings.php +++ b/includes/class-wc-register-legacy-settings.php @@ -56,6 +56,9 @@ class WC_Register_Legacy_Settings { foreach ( $legacy_sections as $legacy_section => $legacy_section_label ) { $legacy_settings = $this->page->get_settings( $legacy_section ); foreach ( $legacy_settings as $legacy_setting ) { + if ( ! isset( $legacy_setting['id'] ) ) { + continue; + } $new_setting = array( 'id' => $legacy_setting['id'], 'label' => ( ! empty( $legacy_setting['title'] ) ? $legacy_setting['title'] : '' ), From 4f98586979c242315df8cc7573ab9e121f165ca8 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 8 Jun 2016 10:34:44 -0600 Subject: [PATCH 126/298] Add _links to returned settings groups. --- ...ass-wc-rest-settings-groups-controller.php | 76 +++++++------------ 1 file changed, 26 insertions(+), 50 deletions(-) diff --git a/includes/api/class-wc-rest-settings-groups-controller.php b/includes/api/class-wc-rest-settings-groups-controller.php index 310f00b8895..1884c028b55 100644 --- a/includes/api/class-wc-rest-settings-groups-controller.php +++ b/includes/api/class-wc-rest-settings-groups-controller.php @@ -61,7 +61,11 @@ class WC_Rest_Settings_Groups_Controller extends WC_REST_Settings_API_Controller $group = wp_parse_args( $group, $defaults ); if ( ! is_null( $group['id'] ) && ! is_null( $group['label'] ) ) { - $filtered_groups[] = $this->filter_group( $group ); + $group_obj = $this->filter_group( $group ); + $group_data = $this->prepare_item_for_response( $group_obj, $request ); + $group_data = $this->prepare_response_for_collection( $group_data ); + + $filtered_groups[] = $group_data; } } @@ -70,68 +74,40 @@ class WC_Rest_Settings_Groups_Controller extends WC_REST_Settings_API_Controller } /** - * Return a single setting group and its settings. + * Prepare links for the request. * - * @since 2.7.0 - * @param WP_REST_Request $request - * @return WP_Error|WP_REST_Response + * @param string $group_id Group ID. + * @return array Links for the given group. */ - public function get_item( $request ) { - $group = $this->prepare_item_for_response( $request ); - if ( is_wp_error( $group ) ) { - return $group; - } - return rest_ensure_response( $group ); + protected function prepare_links( $group_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'item' => array( + 'href' => rest_url( trailingslashit( $base ) . $group_id ), + 'embeddable' => true, + ), + ); + + return $links; } /** * Prepare a report sales object for serialization. * - * @param null $_ + * @param array $item Group object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. */ - public function prepare_item_for_response( $_, $request ) { - $groups = apply_filters( 'woocommerce_settings_groups', array() ); - if ( empty( $groups ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); - } + public function prepare_item_for_response( $item, $request ) { + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); - $index_key = array_keys( wp_list_pluck( $groups, 'id' ), $request['group'] ); - if ( empty( $index_key ) || empty( $groups[ $index_key[0] ] ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); - } + $response = rest_ensure_response( $data ); - $group = wp_parse_args( $groups[ $index_key[0] ], $this->group_defaults() ); - if ( is_null( $group['id'] ) || is_null( $group['label'] ) ) { - return new WP_Error( 'rest_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); - } + $response->add_links( $this->prepare_links( $item['id'] ) ); - // Find sub groups. - $sub_groups = array(); - foreach ( $groups as $_group ) { - if ( ! empty( $_group['parent_id'] ) && $group['id'] === $_group['parent_id'] ) { - $sub_groups[] = $_group['id']; - } - } - - $filtered_group = $this->filter_group( $group ); - $filtered_group['settings'] = array(); - $settings = apply_filters( 'woocommerce_settings-' . $group['id'], array() ); - - if ( ! empty( $settings ) ) { - foreach ( $settings as $setting ) { - $setting = $this->filter_setting( $setting ); - $setting['value'] = $this->get_value( $setting['id'] ); - if ( $this->is_setting_type_valid( $setting['type'] ) ) { - $filtered_group['settings'][] = $setting; - } - } - } - - $filtered_group['sub_groups'] = $sub_groups; - - return $filtered_group; + return $response; } /** From 95990e32ca03bac5ee39c26f263a1798c30f143e Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 8 Jun 2016 13:08:49 -0600 Subject: [PATCH 127/298] Fix unit tests. --- tests/unit-tests/api/settings.php | 153 +++++++++++++++++++----------- 1 file changed, 96 insertions(+), 57 deletions(-) diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index c43943e1634..4cf2ac1104e 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -42,7 +42,7 @@ class Settings extends \WC_Unit_Test_Case { $routes = $this->server->get_routes(); $this->assertArrayHasKey( '/wc/v1/settings', $routes ); $this->assertArrayHasKey( '/wc/v1/settings/(?P[\w-]+)', $routes ); - $this->assertArrayHasKey( '/wc/v1/settings/(?P[\w-]+)/(?P[\w-]+)', $routes ); + $this->assertArrayHasKey( '/wc/v1/settings/(?P[\w-]+)/(?P[\w-]+)', $routes ); } /** @@ -62,7 +62,15 @@ class Settings extends \WC_Unit_Test_Case { 'label' => 'Test Extension', 'parent_id' => '', 'description' => 'My awesome test settings.', - 'sub_groups' => array( 'sub-test' ), + 'sub_groups' => array( 'sub-test' ), + '_links' => array( + 'item' => array( + array( + 'href' => rest_url( '/wc/v1/settings/test' ), + 'embeddable' => true, + ), + ), + ), ), $data ); $this->assertContains( array( @@ -71,6 +79,14 @@ class Settings extends \WC_Unit_Test_Case { 'parent_id' => 'test', 'description' => '', 'sub_groups' => array(), + '_links' => array( + 'item' => array( + array( + 'href' => rest_url( '/wc/v1/settings/sub-test' ), + 'embeddable' => true, + ), + ), + ), ), $data ); } @@ -140,29 +156,39 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 404, $response->get_status() ); // test getting a valid group - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/coupon-data' ) ); + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/general' ) ); $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); - - $this->check_get_group_response( $data, array( - 'id' => 'coupon-data', - 'label' => 'Coupon Data', - 'parent_id' => '', - 'description' => '', - ) ); - - $this->assertEmpty( $data['sub_groups'] ); + $this->assertContains( array( + 'id' => 'woocommerce_demo_store', + 'label' => 'Store Notice', + 'description' => 'Enable site-wide store notice text', + 'type' => 'checkbox', + 'default' => 'no', + 'value' => 'no', + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v1/settings/general/woocommerce_demo_store' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v1/settings/general' ), + ), + ), + ) + ), $data ); // test getting a valid group with settings attached to it $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); $data = $response->get_data(); - $this->assertEquals( 2, count( $data['settings'] ) ); - $this->assertEquals( 'woocommerce_shop_page_display', $data['settings'][0]['id'] ); - $this->assertEmpty( $data['settings'][0]['value'] ); - $this->assertEquals( 'woocommerce_enable_lightbox', $data['settings'][1]['id'] ); - $this->assertEquals( 'yes', $data['settings'][1]['value'] ); - $this->assertEquals( array( 'sub-test' ), $data['sub_groups'] ); + $this->assertEquals( 2, count( $data ) ); + $this->assertEquals( 'woocommerce_shop_page_display', $data[0]['id'] ); + $this->assertEmpty( $data[0]['value'] ); + $this->assertEquals( 'woocommerce_enable_lightbox', $data[1]['id'] ); + $this->assertEquals( 'yes', $data[1]['value'] ); } /** @@ -255,36 +281,48 @@ class Settings extends \WC_Unit_Test_Case { // test defaults first $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); $data = $response->get_data(); - $this->assertEquals( '', $data['settings'][0]['value'] ); - $this->assertEquals( 'yes', $data['settings'][1]['value'] ); + $this->assertEquals( '', $data[0]['value'] ); + $this->assertEquals( 'yes', $data[1]['value'] ); // test setting both at once - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s', 'test' ) ); + $request = new \WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); $request->set_body_params( array( - 'values' => array( - 'woocommerce_shop_page_display' => 'both', - 'woocommerce_enable_lightbox' => 'no', + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'both', + ), + array( + 'id' => 'woocommerce_enable_lightbox', + 'value' => 'no', + ), ), ) ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); - $this->assertEquals( 'both', $data['settings'][0]['value'] ); + $this->assertEquals( 'both', $data['update'][0]['value'] ); $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); - $this->assertEquals( 'no', $data['settings'][1]['value'] ); + $this->assertEquals( 'no', $data['update'][1]['value'] ); $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); // test updating one, but making sure the other value stays the same - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s', 'test' ) ); + $request = new \WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); $request->set_body_params( array( - 'values' => array( - 'woocommerce_shop_page_display' => 'subcategories', + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'subcategories', + ), ), ) ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); - $this->assertEquals( 'subcategories', $data['settings'][0]['value'] ); - $this->assertEquals( 'no', $data['settings'][1]['value'] ); + $this->assertEquals( 'subcategories', $data['update'][0]['value'] ); $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); + + $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); + $data = $response->get_data(); + $this->assertEquals( 'no', $data[1]['value'] ); $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); } @@ -354,10 +392,13 @@ class Settings extends \WC_Unit_Test_Case { public function test_update_settings_without_permission() { wp_set_current_user( 0 ); - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s', 'test' ) ); + $request = new \WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); $request->set_body_params( array( - 'values' => array( - 'woocommerce_shop_page_display' => 'subcategories', + 'update' => array( + array( + 'id' => 'woocommerce_shop_page_display', + 'value' => 'subcategories', + ), ), ) ); $response = $this->server->dispatch( $request ); @@ -411,7 +452,7 @@ class Settings extends \WC_Unit_Test_Case { } /** - * Tests our classic setting registeration to make sure settings added for WP-Admin are available over the API. + * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API. * @since 2.7.0 */ public function test_classic_settings() { @@ -420,17 +461,28 @@ class Settings extends \WC_Unit_Test_Case { // Make sure the group is properly registered $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/products' ) ); $data = $response->get_data(); - - $this->assertEquals( 'products', $data['id'] ); + $this->assertTrue( is_array( $data ) ); $this->assertContains( array( - 'id' => 'woocommerce_downloads_require_login', - 'label' => 'Access Restriction', + 'id' => 'woocommerce_downloads_require_login', + 'label' => 'Access Restriction', 'description' => 'Downloads require login', - 'type' => 'checkbox', - 'default' => 'no', - 'tip' => 'This setting does not apply to guest purchases.', - 'value' => 'no', - ), $data['settings'] ); + 'type' => 'checkbox', + 'default' => 'no', + 'tip' => 'This setting does not apply to guest purchases.', + 'value' => 'no', + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v1/settings/products/woocommerce_downloads_require_login' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v1/settings/products' ), + ), + ), + ), + ), $data ); // test get single $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/products/woocommerce_dimension_unit' ) ); @@ -450,17 +502,4 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 'yd', get_option(' woocommerce_dimension_unit' ) ); } - /** - * Ensure valid group data response. - * @since 2.7.0 - * @param array $response - * @param array $expected - */ - protected function check_get_group_response( $response, $expected ) { - $this->assertEquals( $expected['id'], $response['id'] ); - $this->assertEquals( $expected['parent_id'], $response['parent_id'] ); - $this->assertEquals( $expected['label'], $response['label'] ); - $this->assertEquals( $expected['description'], $response['description'] ); - } - } From 83d252b6d3a0ce50afb0fabfe4bc5f19a55c1a84 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 8 Jun 2016 15:01:30 -0600 Subject: [PATCH 128/298] Remove namespace from Settings API unit test file. This fails builds on PHP 5.2.x. --- tests/unit-tests/api/settings.php | 69 +++++++++++++++---------------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 4cf2ac1104e..390d80c161a 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -1,12 +1,11 @@ server = $wp_rest_server = new \WP_Test_Spy_REST_Server; + $this->server = $wp_rest_server = new WP_Test_Spy_REST_Server; do_action( 'rest_api_init' ); - $this->endpoint = new \WC_Rest_Settings_Controller(); - \WC_Helper_Settings::register(); + $this->endpoint = new WC_Rest_Settings_Controller(); + WC_Helper_Settings::register(); $this->user = $this->factory->user->create( array( 'role' => 'administrator', ) ); @@ -52,7 +51,7 @@ class Settings extends \WC_Unit_Test_Case { public function test_get_groups() { wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings' ) ); $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); @@ -97,7 +96,7 @@ class Settings extends \WC_Unit_Test_Case { public function test_get_groups_without_permission() { wp_set_current_user( 0 ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -106,7 +105,7 @@ class Settings extends \WC_Unit_Test_Case { * @since 2.7.0 */ public function test_get_group_schema() { - $request = new \WP_REST_Request( 'OPTIONS', '/wc/v1/settings' ); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v1/settings' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; @@ -123,7 +122,7 @@ class Settings extends \WC_Unit_Test_Case { * @since 2.7.0 */ public function test_get_setting_schema() { - $request = new \WP_REST_Request( 'OPTIONS', '/wc/v1/settings/test/woocommerce_shop_page_display' ); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v1/settings/test/woocommerce_shop_page_display' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; @@ -146,17 +145,17 @@ class Settings extends \WC_Unit_Test_Case { wp_set_current_user( $this->user ); // test getting a group that does not exist - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/not-real' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/not-real' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting the 'invalid' group - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/invalid' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/invalid' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting a valid group - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/general' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/general' ) ); $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); @@ -182,7 +181,7 @@ class Settings extends \WC_Unit_Test_Case { ), $data ); // test getting a valid group with settings attached to it - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); $data = $response->get_data(); $this->assertEquals( 2, count( $data ) ); $this->assertEquals( 'woocommerce_shop_page_display', $data[0]['id'] ); @@ -198,7 +197,7 @@ class Settings extends \WC_Unit_Test_Case { public function test_get_group_without_permission() { wp_set_current_user( 0 ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/coupon-data' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/coupon-data' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -210,16 +209,16 @@ class Settings extends \WC_Unit_Test_Case { wp_set_current_user( $this->user ); // test defaults first - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_shop_page_display' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_shop_page_display' ) ); $data = $response->get_data(); $this->assertEquals( '', $data['value'] ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); $data = $response->get_data(); $this->assertEquals( 'yes', $data['value'] ); // test updating shop display setting - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); $request->set_body_params( array( 'value' => 'both', ) ); @@ -229,7 +228,7 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 'both', $data['value'] ); $this->assertEquals( 'both', get_option( 'woocommerce_shop_page_display' ) ); - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); $request->set_body_params( array( 'value' => 'subcategories', ) ); @@ -239,7 +238,7 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 'subcategories', $data['value'] ); $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_shop_page_display' ) ); $request->set_body_params( array( 'value' => '', ) ); @@ -250,7 +249,7 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( '', get_option( 'woocommerce_shop_page_display' ) ); // test updating ligtbox - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); $request->set_body_params( array( 'value' => 'no', ) ); @@ -260,7 +259,7 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 'no', $data['value'] ); $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); $request->set_body_params( array( 'value' => 'yes', ) ); @@ -279,13 +278,13 @@ class Settings extends \WC_Unit_Test_Case { wp_set_current_user( $this->user ); // test defaults first - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); $data = $response->get_data(); $this->assertEquals( '', $data[0]['value'] ); $this->assertEquals( 'yes', $data[1]['value'] ); // test setting both at once - $request = new \WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); + $request = new WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); $request->set_body_params( array( 'update' => array( array( @@ -306,7 +305,7 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); // test updating one, but making sure the other value stays the same - $request = new \WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); + $request = new WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); $request->set_body_params( array( 'update' => array( array( @@ -320,7 +319,7 @@ class Settings extends \WC_Unit_Test_Case { $this->assertEquals( 'subcategories', $data['update'][0]['value'] ); $this->assertEquals( 'subcategories', get_option( 'woocommerce_shop_page_display' ) ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test' ) ); $data = $response->get_data(); $this->assertEquals( 'no', $data[1]['value'] ); $this->assertEquals( 'no', get_option( 'woocommerce_enable_lightbox' ) ); @@ -334,17 +333,17 @@ class Settings extends \WC_Unit_Test_Case { wp_set_current_user( $this->user ); // test getting an invalid setting from a group that does not exist - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/not-real/woocommerce_enable_lightbox' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/not-real/woocommerce_enable_lightbox' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting an invalid setting from a group that does exist - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/invalid/invalid' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/invalid/invalid' ) ); $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting a valid setting - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); @@ -364,7 +363,7 @@ class Settings extends \WC_Unit_Test_Case { public function test_get_setting_without_permission() { wp_set_current_user( 0 ); - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/test/woocommerce_enable_lightbox' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -376,7 +375,7 @@ class Settings extends \WC_Unit_Test_Case { public function test_update_setting_without_permission() { wp_set_current_user( 0 ); - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'test', 'woocommerce_enable_lightbox' ) ); $request->set_body_params( array( 'value' => 'yes', ) ); @@ -392,7 +391,7 @@ class Settings extends \WC_Unit_Test_Case { public function test_update_settings_without_permission() { wp_set_current_user( 0 ); - $request = new \WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); + $request = new WP_REST_Request( 'POST', '/wc/v1/settings/test/batch' ); $request->set_body_params( array( 'update' => array( array( @@ -410,7 +409,7 @@ class Settings extends \WC_Unit_Test_Case { * @since 2.7.0 */ public function test_sanitize_setting() { - $endpoint = new \WC_Rest_Settings_Controller; + $endpoint = new WC_Rest_Settings_Controller; // checkbox $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'checkbox', 'default' => 'yes' ), 'no' ); @@ -459,7 +458,7 @@ class Settings extends \WC_Unit_Test_Case { wp_set_current_user( $this->user ); // Make sure the group is properly registered - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/products' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/products' ) ); $data = $response->get_data(); $this->assertTrue( is_array( $data ) ); $this->assertContains( array( @@ -485,13 +484,13 @@ class Settings extends \WC_Unit_Test_Case { ), $data ); // test get single - $response = $this->server->dispatch( new \WP_REST_Request( 'GET', '/wc/v1/settings/products/woocommerce_dimension_unit' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/products/woocommerce_dimension_unit' ) ); $data = $response->get_data(); $this->assertEquals( 'cm', $data['default'] ); // test update - $request = new \WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) ); + $request = new WP_REST_Request( 'PUT', sprintf( '/wc/v1/settings/%s/%s', 'products', 'woocommerce_dimension_unit' ) ); $request->set_body_params( array( 'value' => 'yd', ) ); From 3de28d2356ba206997d3846c91d82b2afbc5bde5 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 08:47:09 -0600 Subject: [PATCH 129/298] Take in options data to be saved as an optional argument, defaulting to $_POST. This allows for reuse of the options field saving mechanism. --- includes/admin/class-wc-admin-settings.php | 14 +++++++++----- includes/admin/wc-admin-functions.php | 5 +++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/includes/admin/class-wc-admin-settings.php b/includes/admin/class-wc-admin-settings.php index 4df6c3fec05..b4d42d8ddb3 100644 --- a/includes/admin/class-wc-admin-settings.php +++ b/includes/admin/class-wc-admin-settings.php @@ -662,10 +662,14 @@ class WC_Admin_Settings { * Loops though the woocommerce options array and outputs each field. * * @param array $options Options array to output + * @param array $data Optional. Data to use for saving. Defaults to $_POST. * @return bool */ - public static function save_fields( $options ) { - if ( empty( $_POST ) ) { + public static function save_fields( $options, $data = null ) { + if ( is_null( $data ) ) { + $data = $_POST; + } + if ( empty( $data ) ) { return false; } @@ -683,17 +687,17 @@ class WC_Admin_Settings { parse_str( $option['id'], $option_name_array ); $option_name = current( array_keys( $option_name_array ) ); $setting_name = key( $option_name_array[ $option_name ] ); - $raw_value = isset( $_POST[ $option_name ][ $setting_name ] ) ? wp_unslash( $_POST[ $option_name ][ $setting_name ] ) : null; + $raw_value = isset( $data[ $option_name ][ $setting_name ] ) ? wp_unslash( $data[ $option_name ][ $setting_name ] ) : null; } else { $option_name = $option['id']; $setting_name = ''; - $raw_value = isset( $_POST[ $option['id'] ] ) ? wp_unslash( $_POST[ $option['id'] ] ) : null; + $raw_value = isset( $data[ $option['id'] ] ) ? wp_unslash( $data[ $option['id'] ] ) : null; } // Format the value based on option type. switch ( $option['type'] ) { case 'checkbox' : - $value = is_null( $raw_value ) ? 'no' : 'yes'; + $value = in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : 'no'; break; case 'textarea' : $value = wp_kses_post( trim( $raw_value ) ); diff --git a/includes/admin/wc-admin-functions.php b/includes/admin/wc-admin-functions.php index 968254b9175..9ec801cd7bc 100644 --- a/includes/admin/wc-admin-functions.php +++ b/includes/admin/wc-admin-functions.php @@ -145,14 +145,15 @@ function woocommerce_admin_fields( $options ) { * Update all settings which are passed. * * @param array $options + * @param array $data */ -function woocommerce_update_options( $options ) { +function woocommerce_update_options( $options, $data = null ) { if ( ! class_exists( 'WC_Admin_Settings' ) ) { include 'class-wc-admin-settings.php'; } - WC_Admin_Settings::save_fields( $options ); + WC_Admin_Settings::save_fields( $options, $data ); } /** From f3e21123d19c061798fdef34932a9ae701feac27 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 08:48:17 -0600 Subject: [PATCH 130/298] =?UTF-8?q?Use=20WC=20Admin=20Settings=E2=80=99s?= =?UTF-8?q?=20get=5Foption()=20in=20REST=20Settings=20controller=20instead?= =?UTF-8?q?=20of=20duplicating=20code.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...stract-wc-rest-settings-api-controller.php | 28 ------------------- .../api/class-wc-rest-settings-controller.php | 4 +-- 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/includes/abstracts/abstract-wc-rest-settings-api-controller.php b/includes/abstracts/abstract-wc-rest-settings-api-controller.php index 1d148dd8487..c13dfe1268a 100644 --- a/includes/abstracts/abstract-wc-rest-settings-api-controller.php +++ b/includes/abstracts/abstract-wc-rest-settings-api-controller.php @@ -108,34 +108,6 @@ class WC_REST_Settings_API_Controller extends WC_REST_Controller { return $value; } - /** - * Get a value from WP's settings API. - * - * @since 2.7.0 - * @param string $setting - * @param string $default - * @return mixed - */ - public function get_value( $setting, $default = '' ) { - if ( strstr( $setting, '[' ) ) { // Array value. - parse_str( $setting, $setting_array ); - $setting = current( array_keys( $setting ) ); - $values = get_option( $setting, '' ); - $key = key( $setting_array[ $setting ] ); - $value = isset( $values[ $key ] ) ? $values[ $key ] : null; - } else { // Single value. - $value = get_option( $setting, null ); - } - - if ( is_array( $value ) ) { - $value = array_map( 'stripslashes', $value ); - } elseif ( ! is_null( $value ) ) { - $value = stripslashes( $value ); - } - - return $value === null ? $default : $value; - } - /** * Filters out bad values from the settings array/filter so we * only return known values via the API. diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index 91bdec0a962..e69cf82501d 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -125,7 +125,7 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { foreach ( $settings as $setting ) { $setting = $this->filter_setting( $setting ); if ( $this->is_setting_type_valid( $setting['type'] ) ) { - $setting['value'] = $this->get_value( $setting['id'] ); + $setting['value'] = WC_Admin_Settings::get_option( $setting['id'] ); $filtered_settings[] = $setting; } } @@ -225,7 +225,7 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { */ public function prepare_item_for_response( $item, $request ) { $data = $this->filter_setting( $item ); - $data['value'] = $this->get_value( $data['id'] ); + $data['value'] = WC_Admin_Settings::get_option( $data['id'] ); $context = empty( $request['context'] ) ? 'view' : $request['context']; $data = $this->add_additional_fields_to_object( $data, $request ); From cca2a0ff5e193994ef2f8c688cffc149f8691751 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 09:16:30 -0600 Subject: [PATCH 131/298] =?UTF-8?q?Reuse=20WC=20Admin=20Setting=E2=80=99s?= =?UTF-8?q?=20save=5Ffields()=20instead=20of=20duplicating=20code=20for=20?= =?UTF-8?q?sanitizing=20saved=20values.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...stract-wc-rest-settings-api-controller.php | 67 ------------------- .../api/class-wc-rest-settings-controller.php | 10 +-- tests/unit-tests/api/settings.php | 46 ------------- 3 files changed, 5 insertions(+), 118 deletions(-) diff --git a/includes/abstracts/abstract-wc-rest-settings-api-controller.php b/includes/abstracts/abstract-wc-rest-settings-api-controller.php index c13dfe1268a..8d6cd5823b3 100644 --- a/includes/abstracts/abstract-wc-rest-settings-api-controller.php +++ b/includes/abstracts/abstract-wc-rest-settings-api-controller.php @@ -41,73 +41,6 @@ class WC_REST_Settings_API_Controller extends WC_REST_Controller { return true; } - /** - * Cleans a value before setting it. - * - * @since 2.7.0 - * - * @param array $setting WC Setting Array - * @param mixed $raw_value Raw value from PUT request - * @return mixed Sanitized value - */ - public function sanitize_setting_value( $setting, $raw_value ) { - switch ( $setting['type'] ) { - case 'checkbox' : - $default = ( ! empty( $setting['default'] ) ? $setting['default'] : 'no' ); - $value = ( in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : $default ); - break; - case 'email' : - $value = sanitize_email( $raw_value ); - $default = ( ! empty( $setting['default'] ) ? $setting['default'] : '' ); - $value = ( ! empty( $value ) ? $value : $default ); - break; - case 'textarea' : - $value = wp_kses( trim( $raw_value ), - array_merge( - array( - 'iframe' => array( 'src' => true, 'style' => true, 'id' => true, 'class' => true ) - ), - wp_kses_allowed_html( 'post' ) - ) - ); - break; - case 'multiselect' : - case 'multi_select_countries' : - $value = array_filter( array_map( 'wc_clean', (array) $raw_value ) ); - break; - case 'image_width' : - $value = array(); - if ( isset( $raw_value['width'] ) ) { - $value['width'] = wc_clean( $raw_value['width'] ); - $value['height'] = wc_clean( $raw_value['height'] ); - $value['crop'] = isset( $raw_value['crop'] ) ? 1 : 0; - } else { - $value['width'] = $setting['default']['width']; - $value['height'] = $setting['default']['height']; - $value['crop'] = $setting['default']['crop']; - } - break; - case 'select': - $options = array_keys( $setting['options'] ); - $default = ( empty( $setting['default'] ) ? $options[0] : $setting['default'] ); - $value = in_array( $raw_value, $options ) ? $raw_value : $default; - break; - default : - $value = wc_clean( $raw_value ); - break; - } - - // A couple fields changed in the REST API -- we can just pass these too so old filters still work - $setting['desc'] = ( ! empty( $setting['description'] ) ? $setting['description'] : '' ); - $setting['title'] = ( ! empty( $setting['label'] ) ? $setting['label'] : '' ); - - $value = apply_filters( 'woocommerce_admin_settings_sanitize_option', $value, $setting, $raw_value ); - $value = apply_filters( "woocommerce_admin_settings_sanitize_option_" . $setting['id'], $value, $setting, $raw_value ); - do_action( 'woocommerce_update_option', $setting ); - - return $value; - } - /** * Filters out bad values from the settings array/filter so we * only return known values via the API. diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index e69cf82501d..f591a77cec5 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -206,12 +206,12 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { return $setting; } + $update_data = array(); + $update_data[ $setting['id'] ] = $request['value']; + + WC_Admin_Settings::save_fields( array( $setting ), $update_data ); + $response = $this->prepare_item_for_response( $setting, $request ); - $value = $this->sanitize_setting_value( $setting, $request['value'] ); - - $response->set_data( array_merge( $response->get_data(), compact( 'value' ) ) ); - - update_option( $setting['id'], $value ); return rest_ensure_response( $response ); } diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 390d80c161a..39894569962 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -404,52 +404,6 @@ class Settings extends WC_Unit_Test_Case { $this->assertEquals( 401, $response->get_status() ); } - /** - * Makes sure our sanitize function runs correctly for different types. - * @since 2.7.0 - */ - public function test_sanitize_setting() { - $endpoint = new WC_Rest_Settings_Controller; - - // checkbox - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'checkbox', 'default' => 'yes' ), 'no' ); - $this->assertEquals( 'no', $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'checkbox', 'default' => 'yes' ), 'yes' ); - $this->assertEquals( 'yes', $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'checkbox', 'default' => 'yes' ), 'invalid' ); - $this->assertEquals( 'yes', $value ); - - // email - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email' ), 'test@woo.local' ); - $this->assertEquals( 'test@woo.local', $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email' ), ' admin@woo.local! ' ); - $this->assertEquals( 'admin@woo.local', $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email' ), 'blah' ); - $this->assertEquals( '', $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'email', 'default' => 'woo@woo.local' ), 'blah' ); - $this->assertEquals( 'woo@woo.local', $value ); - - // textarea - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'textarea' ), ' blah' ); - $this->assertEquals( 'blah', $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'textarea' ), 'blah' ); - $this->assertEquals( 'blah', $value ); - - // multiselect / multiselect countries - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'multiselect' ), array( 'test', 'assertEquals( array( 'test', '<test' ), $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'multi_select_countries' ), array( 'test', 'assertEquals( array( 'test', '<test' ), $value ); - - // image_width - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'image_width' ), array( 'width' => ' 100%', 'height' => '25px ' ) ); - $this->assertEquals( array( 'width' => '100%', 'height' => '25px', 'crop' => 0 ), $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'image_width' ), array( 'width' => '100%', 'height' => '25px', 'crop' => 'something' ) ); - $this->assertEquals( array( 'width' => '100%', 'height' => '25px', 'crop' => 1 ), $value ); - $value = $endpoint->sanitize_setting_value( array( 'id' => 'test', 'type' => 'image_width', 'default' => array( 'width' => '50px', 'height' => '50px', 'crop' => true ) ), array() ); - $this->assertEquals( array( 'width' => '50px', 'height' => '50px', 'crop' => 1 ), $value ); - } - /** * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API. * @since 2.7.0 From 09f7723457eb64b1cd603a6d3922bb18fba1a575 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 10:09:31 -0600 Subject: [PATCH 132/298] Add initial test file for WC_Register_Legacy_Settings, with test for constructor. --- .../settings/register-legacy-settings.php | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 tests/unit-tests/settings/register-legacy-settings.php diff --git a/tests/unit-tests/settings/register-legacy-settings.php b/tests/unit-tests/settings/register-legacy-settings.php new file mode 100644 index 00000000000..fb8801a7438 --- /dev/null +++ b/tests/unit-tests/settings/register-legacy-settings.php @@ -0,0 +1,32 @@ +page = new WC_Settings_General(); + } + + public function test_constructor() { + + $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); + + $this->assertEquals( has_filter( 'woocommerce_settings_groups', array( $legacy_settings, 'register_legacy_group' ) ), 10 ); + $this->assertEquals( has_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $legacy_settings, 'register_legacy_settings' ) ), 10 ); + } + +} \ No newline at end of file From 51cae9c44126a98c3a3d4f94456c1f02a538c338 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 10:38:30 -0600 Subject: [PATCH 133/298] Add test for register_legacy_group() and coverage annotations. --- .../settings/register-legacy-settings.php | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/unit-tests/settings/register-legacy-settings.php b/tests/unit-tests/settings/register-legacy-settings.php index fb8801a7438..876ba9b1fc2 100644 --- a/tests/unit-tests/settings/register-legacy-settings.php +++ b/tests/unit-tests/settings/register-legacy-settings.php @@ -21,12 +21,37 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { $this->page = new WC_Settings_General(); } + /** + * @covers WC_Register_Legacy_Settings::__construct + */ public function test_constructor() { - $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); $this->assertEquals( has_filter( 'woocommerce_settings_groups', array( $legacy_settings, 'register_legacy_group' ) ), 10 ); $this->assertEquals( has_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $legacy_settings, 'register_legacy_settings' ) ), 10 ); } + /** + * @covers WC_Register_Legacy_Settings::register_legacy_group + */ + public function test_register_legacy_group() { + $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); + + $existing = array( + 'id' => 'existing-id', + 'label' => 'Existing Group', + ); + $initial = array( $existing ); + $expected = array( + $existing, + array( + 'id' => $this->page->get_id(), + 'label' => $this->page->get_label(), + ), + ); + $actual = $legacy_settings->register_legacy_group( $initial ); + + $this->assertEquals( $expected, $actual ); + } + } \ No newline at end of file From b4eaa12f7a4f178eb8ad4e930c924bd955431492 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 11:37:35 -0600 Subject: [PATCH 134/298] =?UTF-8?q?Break=20=E2=80=9Clegacy=E2=80=9D=20sett?= =?UTF-8?q?ing=20to=20=E2=80=9Cnew=E2=80=9D=20conversion=20into=20it?= =?UTF-8?q?=E2=80=99s=20own=20method.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../class-wc-register-legacy-settings.php | 60 ++++++++----- .../settings/register-legacy-settings.php | 90 +++++++++++++++++++ 2 files changed, 128 insertions(+), 22 deletions(-) diff --git a/includes/class-wc-register-legacy-settings.php b/includes/class-wc-register-legacy-settings.php index a9d262ac632..76318fd428b 100644 --- a/includes/class-wc-register-legacy-settings.php +++ b/includes/class-wc-register-legacy-settings.php @@ -56,33 +56,49 @@ class WC_Register_Legacy_Settings { foreach ( $legacy_sections as $legacy_section => $legacy_section_label ) { $legacy_settings = $this->page->get_settings( $legacy_section ); foreach ( $legacy_settings as $legacy_setting ) { - if ( ! isset( $legacy_setting['id'] ) ) { - continue; + $new_setting = $this->new_setting_from_legacy( $legacy_setting ); + if ( $new_setting ) { + $settings[] = $new_setting; } - $new_setting = array( - 'id' => $legacy_setting['id'], - 'label' => ( ! empty( $legacy_setting['title'] ) ? $legacy_setting['title'] : '' ), - 'description' => ( ! empty( $legacy_setting['desc'] ) ? $legacy_setting['desc'] : '' ), - 'type' => $legacy_setting['type'], - ); - if ( isset( $legacy_setting['default'] ) ) { - $new_setting['default'] = $legacy_setting['default']; - } - if ( isset( $legacy_setting['options'] ) ) { - $new_setting['options'] = $legacy_setting['options']; - } - if ( isset( $legacy_setting['desc_tip'] ) ) { - if ( true === $legacy_setting['desc_tip'] ) { - $new_setting['tip'] = $legacy_setting['desc']; - } else if ( ! empty( $legacy_setting['desc_tip'] ) ) { - $new_setting['tip'] = $legacy_setting['desc_tip']; - } - } - $settings[] = $new_setting; } } return $settings; } + + /** + * Convert a "legacy" setting (WC_Settings_Page::get_settings()) into the format expected + * for the REST API Settings Controller + * + * @param $legacy_setting Settings array, as produced by a subclass of WC_Settings_Page. + * + * @return array|bool Boolean false if legacy setting has no ID, Array of converted new setting otherwise. + */ + public function new_setting_from_legacy( $legacy_setting ) { + if ( ! isset( $legacy_setting['id'] ) ) { + return false; + } + $new_setting = array( + 'id' => $legacy_setting['id'], + 'label' => ( ! empty( $legacy_setting['title'] ) ? $legacy_setting['title'] : '' ), + 'description' => ( ! empty( $legacy_setting['desc'] ) ? $legacy_setting['desc'] : '' ), + 'type' => $legacy_setting['type'], + ); + if ( isset( $legacy_setting['default'] ) ) { + $new_setting['default'] = $legacy_setting['default']; + } + if ( isset( $legacy_setting['options'] ) ) { + $new_setting['options'] = $legacy_setting['options']; + } + if ( isset( $legacy_setting['desc_tip'] ) ) { + if ( true === $legacy_setting['desc_tip'] ) { + $new_setting['tip'] = $legacy_setting['desc']; + } else if ( ! empty( $legacy_setting['desc_tip'] ) ) { + $new_setting['tip'] = $legacy_setting['desc_tip']; + } + } + + return $new_setting; + } } /** diff --git a/tests/unit-tests/settings/register-legacy-settings.php b/tests/unit-tests/settings/register-legacy-settings.php index 876ba9b1fc2..7bad6e41b59 100644 --- a/tests/unit-tests/settings/register-legacy-settings.php +++ b/tests/unit-tests/settings/register-legacy-settings.php @@ -54,4 +54,94 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { $this->assertEquals( $expected, $actual ); } + public function new_setting_from_legacy_provider() { + return array( + // No "id" case + array( + array( + 'type' => 'some-type-with-no-id', + ), + false, + ), + // All optional properties except 'desc_tip' + array( + array( + 'id' => 'setting-id', + 'type' => 'select', + 'title' => 'Setting Name', + 'desc' => 'Setting Description', + 'default' => 'one', + 'options' => array( 'one', 'two' ), + ), + array( + 'id' => 'setting-id', + 'type' => 'select', + 'label' => 'Setting Name', + 'description' => 'Setting Description', + 'default' => 'one', + 'options' => array( 'one', 'two' ), + ), + ), + // Boolean 'desc_tip' defaulting to 'desc' value + array( + array( + 'id' => 'setting-id', + 'type' => 'select', + 'title' => 'Setting Name', + 'desc' => 'Setting Description', + 'desc_tip' => true, + ), + array( + 'id' => 'setting-id', + 'type' => 'select', + 'label' => 'Setting Name', + 'description' => 'Setting Description', + 'tip' => 'Setting Description', + ), + ), + // String 'desc_tip' + array( + array( + 'id' => 'setting-id', + 'type' => 'select', + 'title' => 'Setting Name', + 'desc' => 'Setting Description', + 'desc_tip' => 'Setting Tip', + ), + array( + 'id' => 'setting-id', + 'type' => 'select', + 'label' => 'Setting Name', + 'description' => 'Setting Description', + 'tip' => 'Setting Tip', + ), + ), + // Empty 'title' and 'desc' + array( + array( + 'id' => 'setting-id', + 'type' => 'select', + ), + array( + 'id' => 'setting-id', + 'type' => 'select', + 'label' => '', + 'description' => '', + ), + ), + ); + } + + /** + * @dataProvider new_setting_from_legacy_provider + * @covers WC_Register_Legacy_Settings::new_setting_from_legacy + */ + public function test_new_setting_from_legacy( $input, $expected ) { + $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); + + $actual = $legacy_settings->new_setting_from_legacy( $input ); + + $this->assertEquals( $expected, $actual ); + } + } \ No newline at end of file From 91a86efed90c681fac20fa39318a228c22fc5987 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 12:07:02 -0600 Subject: [PATCH 135/298] Add test coverage for register_legacy_settings(). --- .../settings/register-legacy-settings.php | 85 ++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/tests/unit-tests/settings/register-legacy-settings.php b/tests/unit-tests/settings/register-legacy-settings.php index 7bad6e41b59..2fa41ce58c9 100644 --- a/tests/unit-tests/settings/register-legacy-settings.php +++ b/tests/unit-tests/settings/register-legacy-settings.php @@ -18,7 +18,19 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { public function setUp() { parent::setUp(); - $this->page = new WC_Settings_General(); + $mock_page = $this->getMock( 'WC_Settings_General' ); + + $mock_page + ->expects( $this->any() ) + ->method( 'get_id' ) + ->will( $this->returnValue( 'page-id' ) ); + + $mock_page + ->expects( $this->any() ) + ->method( 'get_label' ) + ->will( $this->returnValue( 'Page Label' ) ); + + $this->page = $mock_page; } /** @@ -144,4 +156,75 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { $this->assertEquals( $expected, $actual ); } + /** + * @covers WC_Register_Legacy_Settings::register_legacy_settings + */ + public function test_register_legacy_settings_one_section() { + $this->page + ->expects( $this->any() ) + ->method( 'get_sections' ) + ->will( $this->returnValue( array() ) ); + + $this->page + ->expects( $this->once() ) + ->method( 'get_settings' ) + ->with( $this->equalTo( 0 ) ) + ->will( $this->returnValue( array() ) ); + + $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); + + $expected = array(); + $actual = $legacy_settings->register_legacy_settings( array() ); + + $this->assertEquals( $expected, $actual ); + } + + /** + * @covers WC_Register_Legacy_Settings::register_legacy_settings + */ + public function test_register_legacy_settings() { + $this->page + ->expects( $this->any() ) + ->method( 'get_sections' ) + ->will( $this->returnValue( array() ) ); + + $settings = array( + array( + 'id' => 'setting-1', + 'type' => 'text', + ), + array( + 'type' => 'no-id', + ), + array( + 'id' => 'setting-2', + 'type' => 'textarea', + ), + ); + + $this->page + ->expects( $this->any() ) + ->method( 'get_settings' ) + ->will( $this->returnValue( $settings ) ); + + $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); + + $expected = array( + array( + 'id' => 'setting-1', + 'type' => 'text', + 'label' => '', + 'description' => '', + ), + array( + 'id' => 'setting-2', + 'type' => 'textarea', + 'label' => '', + 'description' => '', + ), + ); + $actual = $legacy_settings->register_legacy_settings( array() ); + + $this->assertEquals( $expected, $actual ); + } } \ No newline at end of file From a0f227a17cea59b8c7d8487ee30367877de68f96 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 14:27:54 -0600 Subject: [PATCH 136/298] Add test coverage for all WP_Error-returning cases in the Settings API. --- tests/unit-tests/api/settings.php | 76 ++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 2 deletions(-) diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 39894569962..ba4e5dd900f 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -100,6 +100,22 @@ class Settings extends WC_Unit_Test_Case { $this->assertEquals( 401, $response->get_status() ); } + /** + * Test /settings without valid permissions/creds. + * @since 2.7.0 + * @covers WC_Rest_Settings_Groups_Controller::get_items + */ + public function test_get_groups_none_registered() { + wp_set_current_user( $this->user ); + + remove_all_filters( 'woocommerce_settings_groups' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings' ) ); + $this->assertEquals( 500, $response->get_status() ); + + WC_Helper_Settings::register(); + } + /** * Test groups schema. * @since 2.7.0 @@ -144,14 +160,16 @@ class Settings extends WC_Unit_Test_Case { public function test_get_group() { wp_set_current_user( $this->user ); + // test route callback receiving an empty group id + $result = $this->endpoint->get_group_settings( '' ); + $this->assertIsWPError( $result ); + // test getting a group that does not exist $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/not-real' ) ); - $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting the 'invalid' group $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/settings/invalid' ) ); - $data = $response->get_data(); $this->assertEquals( 404, $response->get_status() ); // test getting a valid group @@ -367,6 +385,44 @@ class Settings extends WC_Unit_Test_Case { $this->assertEquals( 401, $response->get_status() ); } + /** + * Tests the GET single setting route handler receiving an empty setting ID. + */ + public function test_get_setting_empty_setting_id() { + $result = $this->endpoint->get_setting( 'test', '' ); + + $this->assertIsWPError( $result ); + } + + /** + * Tests the GET single setting route handler receiving an invalid setting ID. + */ + public function test_get_setting_invalid_setting_id() { + $result = $this->endpoint->get_setting( 'test', 'invalid' ); + + $this->assertIsWPError( $result ); + } + + /** + * Tests the GET single setting route handler encountering an invalid setting type. + */ + public function test_get_setting_invalid_setting_type() { + $controller = $this->getMock( 'WC_Rest_Settings_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) ); + + $controller + ->expects( $this->any() ) + ->method( 'get_group_settings' ) + ->will( $this->returnValue( WC_Helper_Settings::register_test_settings( array() ) ) ); + + $controller + ->expects( $this->any() ) + ->method( 'is_setting_type_valid' ) + ->will( $this->returnValue( false ) ); + + $result = $controller->get_setting( 'test', 'woocommerce_enable_lightbox' ); + + $this->assertIsWPError( $result ); + } /** * Test updating a single setting without valid user permissions. @@ -404,6 +460,22 @@ class Settings extends WC_Unit_Test_Case { $this->assertEquals( 401, $response->get_status() ); } + /** + * Test updating a bad setting ID. + * @since 2.7.0 + * @covers WC_Rest_Settings_Controller::update_item + */ + public function test_update_setting_bad_setting_id() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', '/wc/v1/settings/test/invalid' ); + $request->set_body_params( array( + 'value' => 'test', + ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 404, $response->get_status() ); + } + /** * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API. * @since 2.7.0 From e14d77a987fd5d7012433a7396b4b4c63b43baf7 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Mon, 13 Jun 2016 16:11:51 -0600 Subject: [PATCH 137/298] =?UTF-8?q?When=20saving=20settings,=20only=20allo?= =?UTF-8?q?w=20values=20found=20in=20=E2=80=9Coptions=E2=80=9D=20for=20?= =?UTF-8?q?=E2=80=9Cselect=E2=80=9D=20type=20fields.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/admin/class-wc-admin-settings.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/includes/admin/class-wc-admin-settings.php b/includes/admin/class-wc-admin-settings.php index b4d42d8ddb3..2e4d242f26f 100644 --- a/includes/admin/class-wc-admin-settings.php +++ b/includes/admin/class-wc-admin-settings.php @@ -718,6 +718,15 @@ class WC_Admin_Settings { $value['crop'] = $option['default']['crop']; } break; + case 'select': + $allowed_values = empty( $option['options'] ) ? array() : array_keys( $option['options'] ); + if ( empty( $option['default'] ) && empty( $allowed_values ) ) { + $value = null; + break; + } + $default = ( empty( $option['default'] ) ? $allowed_values[0] : $option['default'] ); + $value = in_array( $raw_value, $allowed_values ) ? $raw_value : $default; + break; default : $value = wc_clean( $raw_value ); break; From f168f356bc8f8545b6852f79d7a770a46ef91f84 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 14:11:50 -0600 Subject: [PATCH 138/298] Rename WC_Rest_Settings_Controller to WC_Rest_Settings_Options_Controller. --- ...er.php => class-wc-rest-settings-options-controller.php} | 2 +- includes/class-wc-api.php | 4 ++-- tests/unit-tests/api/settings.php | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) rename includes/api/{class-wc-rest-settings-controller.php => class-wc-rest-settings-options-controller.php} (99%) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-options-controller.php similarity index 99% rename from includes/api/class-wc-rest-settings-controller.php rename to includes/api/class-wc-rest-settings-options-controller.php index f591a77cec5..073d4bfa767 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-options-controller.php @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { +class WC_Rest_Settings_Options_Controller extends WC_REST_Settings_API_Controller { /** * WP REST API namespace/version. diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index eb278b6f92c..453dcdcf6a5 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -164,7 +164,7 @@ class WC_API extends WC_Legacy_API { include_once( 'api/class-wc-rest-report-sales-controller.php' ); include_once( 'api/class-wc-rest-report-top-sellers-controller.php' ); include_once( 'api/class-wc-rest-reports-controller.php' ); - include_once( 'api/class-wc-rest-settings-controller.php' ); + include_once( 'api/class-wc-rest-settings-options-controller.php' ); include_once( 'api/class-wc-rest-settings-groups-controller.php' ); include_once( 'api/class-wc-rest-tax-classes-controller.php' ); include_once( 'api/class-wc-rest-taxes-controller.php' ); @@ -194,7 +194,7 @@ class WC_API extends WC_Legacy_API { 'WC_REST_Report_Sales_Controller', 'WC_REST_Report_Top_Sellers_Controller', 'WC_REST_Reports_Controller', - 'WC_Rest_Settings_Controller', + 'WC_Rest_Settings_Options_Controller', 'WC_REST_Settings_Groups_Controller', 'WC_REST_Tax_Classes_Controller', 'WC_REST_Taxes_Controller', diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index ba4e5dd900f..6269aac2381 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -17,7 +17,7 @@ class Settings extends WC_Unit_Test_Case { global $wp_rest_server; $this->server = $wp_rest_server = new WP_Test_Spy_REST_Server; do_action( 'rest_api_init' ); - $this->endpoint = new WC_Rest_Settings_Controller(); + $this->endpoint = new WC_Rest_Settings_Options_Controller(); WC_Helper_Settings::register(); $this->user = $this->factory->user->create( array( 'role' => 'administrator', @@ -407,7 +407,7 @@ class Settings extends WC_Unit_Test_Case { * Tests the GET single setting route handler encountering an invalid setting type. */ public function test_get_setting_invalid_setting_type() { - $controller = $this->getMock( 'WC_Rest_Settings_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) ); + $controller = $this->getMock( 'WC_Rest_Settings_Options_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) ); $controller ->expects( $this->any() ) @@ -463,7 +463,7 @@ class Settings extends WC_Unit_Test_Case { /** * Test updating a bad setting ID. * @since 2.7.0 - * @covers WC_Rest_Settings_Controller::update_item + * @covers WC_Rest_Settings_Options_Controller::update_item */ public function test_update_setting_bad_setting_id() { wp_set_current_user( $this->user ); From 2fcb15d9cfab3c704cddf5f4c81e7938a8b6070b Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 14:19:15 -0600 Subject: [PATCH 139/298] Rename WC_Rest_Settings_Groups_Controller to WC_Rest_Settings_Controller. --- ...s-controller.php => class-wc-rest-settings-controller.php} | 2 +- includes/class-wc-api.php | 4 ++-- tests/unit-tests/api/settings.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename includes/api/{class-wc-rest-settings-groups-controller.php => class-wc-rest-settings-controller.php} (98%) diff --git a/includes/api/class-wc-rest-settings-groups-controller.php b/includes/api/class-wc-rest-settings-controller.php similarity index 98% rename from includes/api/class-wc-rest-settings-groups-controller.php rename to includes/api/class-wc-rest-settings-controller.php index 1884c028b55..b89191d2e28 100644 --- a/includes/api/class-wc-rest-settings-groups-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Groups_Controller extends WC_REST_Settings_API_Controller { +class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { /** * WP REST API namespace/version. diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 453dcdcf6a5..d10cd0a86f1 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -164,8 +164,8 @@ class WC_API extends WC_Legacy_API { include_once( 'api/class-wc-rest-report-sales-controller.php' ); include_once( 'api/class-wc-rest-report-top-sellers-controller.php' ); include_once( 'api/class-wc-rest-reports-controller.php' ); + include_once( 'api/class-wc-rest-settings-controller.php' ); include_once( 'api/class-wc-rest-settings-options-controller.php' ); - include_once( 'api/class-wc-rest-settings-groups-controller.php' ); include_once( 'api/class-wc-rest-tax-classes-controller.php' ); include_once( 'api/class-wc-rest-taxes-controller.php' ); include_once( 'api/class-wc-rest-webhook-deliveries.php' ); @@ -194,8 +194,8 @@ class WC_API extends WC_Legacy_API { 'WC_REST_Report_Sales_Controller', 'WC_REST_Report_Top_Sellers_Controller', 'WC_REST_Reports_Controller', + 'WC_Rest_Settings_Controller', 'WC_Rest_Settings_Options_Controller', - 'WC_REST_Settings_Groups_Controller', 'WC_REST_Tax_Classes_Controller', 'WC_REST_Taxes_Controller', 'WC_REST_Webhook_Deliveries_Controller', diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 6269aac2381..f9cd9faaf95 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -103,7 +103,7 @@ class Settings extends WC_Unit_Test_Case { /** * Test /settings without valid permissions/creds. * @since 2.7.0 - * @covers WC_Rest_Settings_Groups_Controller::get_items + * @covers WC_Rest_Settings_Controller::get_items */ public function test_get_groups_none_registered() { wp_set_current_user( $this->user ); From 8ff799562b9f24e7d31fc6f85832672483afe721 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 14:47:56 -0600 Subject: [PATCH 140/298] Remove WC_REST_Settings_Controller dependency on WC_REST_Settings_API_Controller. --- .../api/class-wc-rest-settings-controller.php | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index b89191d2e28..560bd125466 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -13,13 +13,20 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { +class WC_Rest_Settings_Controller extends WC_REST_Controller { /** * WP REST API namespace/version. */ protected $namespace = 'wc/v1'; + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'settings'; + /** * Register routes. * @since 2.7.0 @@ -29,7 +36,7 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); @@ -152,6 +159,21 @@ class WC_Rest_Settings_Controller extends WC_REST_Settings_API_Controller { ); } + /** + * Makes sure the current user has access to READ the settings APIs. + * + * @since 2.7.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + /** * Get the groups schema, conforming to JSON Schema. * From af1e3d0417a040231bd87b0db4759967d6ac5353 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 14:48:58 -0600 Subject: [PATCH 141/298] Remove WC_REST_Settings_Options_Controller dependency on WC_REST_Settings_API_Controller. --- ...ss-wc-rest-settings-options-controller.php | 97 ++++++++++++++++++- 1 file changed, 92 insertions(+), 5 deletions(-) diff --git a/includes/api/class-wc-rest-settings-options-controller.php b/includes/api/class-wc-rest-settings-options-controller.php index 073d4bfa767..5086d2107ae 100644 --- a/includes/api/class-wc-rest-settings-options-controller.php +++ b/includes/api/class-wc-rest-settings-options-controller.php @@ -13,13 +13,20 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Options_Controller extends WC_REST_Settings_API_Controller { +class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * WP REST API namespace/version. */ protected $namespace = 'wc/v1'; + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'settings'; + /** * Register routes. * @since 2.7.0 @@ -29,7 +36,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Settings_API_Controlle array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); @@ -38,7 +45,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Settings_API_Controlle array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'batch_items' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_batch_schema' ), @@ -48,12 +55,12 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Settings_API_Controlle array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), @@ -259,6 +266,86 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Settings_API_Controlle return $links; } + /** + * Makes sure the current user has access to READ the settings APIs. + * + * @since 2.7.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Makes sure the current user has access to WRITE the settings APIs. + * + * @since 2.7.0 + * @param WP_REST_Request $request Full data about the request. + * @return WP_Error|boolean + */ + public function update_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + + /** + * Filters out bad values from the settings array/filter so we + * only return known values via the API. + * + * @since 2.7.0 + * @param array $setting + * @return array + */ + public function filter_setting( $setting ) { + $setting = array_intersect_key( + $setting, + array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) + ); + + if ( empty( $setting['options'] ) ) { + unset( $setting['options'] ); + } + + return $setting; + } + + /** + * Callback for allowed keys for each setting response. + * + * @since 2.7.0 + * @param string $key Key to check + * @return boolean + */ + public function allowed_setting_keys( $key ) { + return in_array( $key, array( + 'id', 'label', 'description', 'default', 'tip', + 'placeholder', 'type', 'options', 'value', + ) ); + } + + /** + * Boolean for if a setting type is a valid supported setting type. + * + * @since 2.7.0 + * @param string $type + * @return boolean + */ + public function is_setting_type_valid( $type ) { + return in_array( $type, array( + 'text', 'email', 'number', 'color', 'password', + 'textarea', 'select', 'multiselect', 'radio', 'checkbox', + 'multi_select_countries', 'image_width', + ) ); + } + /** * Get the settings schema, conforming to JSON Schema. * From d77373227a1e34139f6441710b4caba272f390ab Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 14:51:48 -0600 Subject: [PATCH 142/298] Remove now defunct WC_REST_Settings_API_Controller class. --- ...stract-wc-rest-settings-api-controller.php | 93 ------------------- includes/class-wc-api.php | 1 - 2 files changed, 94 deletions(-) delete mode 100644 includes/abstracts/abstract-wc-rest-settings-api-controller.php diff --git a/includes/abstracts/abstract-wc-rest-settings-api-controller.php b/includes/abstracts/abstract-wc-rest-settings-api-controller.php deleted file mode 100644 index 8d6cd5823b3..00000000000 --- a/includes/abstracts/abstract-wc-rest-settings-api-controller.php +++ /dev/null @@ -1,93 +0,0 @@ - rest_authorization_required_code() ) - ); - } - - return true; - } - - /** - * Filters out bad values from the settings array/filter so we - * only return known values via the API. - * - * @since 2.7.0 - * @param array $setting - * @return array - */ - public function filter_setting( $setting ) { - $setting = array_intersect_key( - $setting, - array_flip( array_filter( array_keys( $setting ), array( $this, 'allowed_setting_keys' ) ) ) - ); - - if ( empty( $setting['options'] ) ) { - unset( $setting['options'] ); - } - - return $setting; - } - - /** - * Callback for allowed keys for each setting response. - * - * @since 2.7.0 - * @param string $key Key to check - * @return boolean - */ - public function allowed_setting_keys( $key ) { - return in_array( $key, array( - 'id', 'label', 'description', 'default', 'tip', - 'placeholder', 'type', 'options', 'value', - ) ); - } - - /** - * Boolean for if a setting type is a valid supported setting type. - * - * @since 2.7.0 - * @param string $type - * @return boolean - */ - public function is_setting_type_valid( $type ) { - return in_array( $type, array( - 'text', 'email', 'number', 'color', 'password', - 'textarea', 'select', 'multiselect', 'radio', 'checkbox', - 'multi_select_countries', 'image_width', - ) ); - } -} diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index d10cd0a86f1..4e7834367e8 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -143,7 +143,6 @@ class WC_API extends WC_Legacy_API { // Abstract controllers. include_once( 'abstracts/abstract-wc-rest-controller.php' ); include_once( 'abstracts/abstract-wc-rest-posts-controller.php' ); - include_once( 'abstracts/abstract-wc-rest-settings-api-controller.php' ); include_once( 'abstracts/abstract-wc-rest-terms-controller.php' ); include_once( 'abstracts/abstract-wc-settings-api.php' ); From 383b5b2944d12e60c105b3f7c879053fde5d859c Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 15:43:03 -0600 Subject: [PATCH 143/298] Move legacy setting API registration hooks into main WC_API class. --- includes/class-wc-api.php | 14 ++++++++++++++ includes/class-wc-register-legacy-settings.php | 13 ------------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 4e7834367e8..9f86a3e978b 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -121,6 +121,9 @@ class WC_API extends WC_Legacy_API { // Init REST API routes. add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) ); + + // Register legacy settings to the REST API. + add_action( 'rest_api_init', array( $this, 'register_legacy_settings' ) ); } /** @@ -206,4 +209,15 @@ class WC_API extends WC_Legacy_API { $this->$controller->register_routes(); } } + + /** + * Register legacy settings to the REST API. + * @since 2.7.0 + */ + public function register_legacy_settings() { + $pages = WC_Admin_Settings::get_settings_pages(); + foreach ( $pages as $page ) { + new WC_Register_Legacy_Settings( $page ); + } + } } diff --git a/includes/class-wc-register-legacy-settings.php b/includes/class-wc-register-legacy-settings.php index 76318fd428b..eb32b02df35 100644 --- a/includes/class-wc-register-legacy-settings.php +++ b/includes/class-wc-register-legacy-settings.php @@ -100,16 +100,3 @@ class WC_Register_Legacy_Settings { return $new_setting; } } - -/** - * Register legacy settings to the REST API. - * @since 2.7.0 - */ - function wc_settings_api_register_legacy() { - $pages = WC_Admin_Settings::get_settings_pages(); - foreach ( $pages as $page ) { - new WC_Register_Legacy_Settings( $page ); - } - } - -add_action( 'rest_api_init', 'wc_settings_api_register_legacy' ); From 5c1b3a8d62bd4db882053aed6891fc169efb6222 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 15:46:36 -0600 Subject: [PATCH 144/298] Remove now defunct WP API vendor file. --- includes/vendor/wp-api-functions.php | 199 --------------------------- 1 file changed, 199 deletions(-) delete mode 100644 includes/vendor/wp-api-functions.php diff --git a/includes/vendor/wp-api-functions.php b/includes/vendor/wp-api-functions.php deleted file mode 100644 index 90c0713a229..00000000000 --- a/includes/vendor/wp-api-functions.php +++ /dev/null @@ -1,199 +0,0 @@ - null, - 'update_callback' => null, - 'schema' => null, - ); - - $args = wp_parse_args( $args, $defaults ); - - global $wp_rest_additional_fields; - - $object_types = (array) $object_type; - - foreach ( $object_types as $object_type ) { - $wp_rest_additional_fields[ $object_type ][ $attribute ] = $args; - } - } -} - -if ( ! function_exists( 'register_api_field' ) ) { - /** - * Backwards compat shim - */ - function register_api_field( $object_type, $attributes, $args = array() ) { - _deprecated_function( 'register_api_field', 'WPAPI-2.0', 'register_rest_field' ); - register_rest_field( $object_type, $attributes, $args ); - } -} - -if ( ! function_exists( 'rest_validate_request_arg' ) ) { - /** - * Validate a request argument based on details registered to the route. - * - * @param mixed $value - * @param WP_REST_Request $request - * @param string $param - * @return WP_Error|boolean - */ - function rest_validate_request_arg( $value, $request, $param ) { - - $attributes = $request->get_attributes(); - if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { - return true; - } - $args = $attributes['args'][ $param ]; - - if ( ! empty( $args['enum'] ) ) { - if ( ! in_array( $value, $args['enum'] ) ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not one of %s' ), $param, implode( ', ', $args['enum'] ) ) ); - } - } - - if ( 'integer' === $args['type'] && ! is_numeric( $value ) ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not of type %s' ), $param, 'integer' ) ); - } - - if ( 'string' === $args['type'] && ! is_string( $value ) ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s is not of type %s' ), $param, 'string' ) ); - } - - if ( isset( $args['format'] ) ) { - switch ( $args['format'] ) { - case 'date-time' : - if ( ! rest_parse_date( $value ) ) { - return new WP_Error( 'rest_invalid_date', __( 'The date you provided is invalid.' ) ); - } - break; - - case 'email' : - if ( ! is_email( $value ) ) { - return new WP_Error( 'rest_invalid_email', __( 'The email address you provided is invalid.' ) ); - } - break; - } - } - - if ( in_array( $args['type'], array( 'numeric', 'integer' ) ) && ( isset( $args['minimum'] ) || isset( $args['maximum'] ) ) ) { - if ( isset( $args['minimum'] ) && ! isset( $args['maximum'] ) ) { - if ( ! empty( $args['exclusiveMinimum'] ) && $value <= $args['minimum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be greater than %d (exclusive)' ), $param, $args['minimum'] ) ); - } else if ( empty( $args['exclusiveMinimum'] ) && $value < $args['minimum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be greater than %d (inclusive)' ), $param, $args['minimum'] ) ); - } - } else if ( isset( $args['maximum'] ) && ! isset( $args['minimum'] ) ) { - if ( ! empty( $args['exclusiveMaximum'] ) && $value >= $args['maximum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be less than %d (exclusive)' ), $param, $args['maximum'] ) ); - } else if ( empty( $args['exclusiveMaximum'] ) && $value > $args['maximum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be less than %d (inclusive)' ), $param, $args['maximum'] ) ); - } - } else if ( isset( $args['maximum'] ) && isset( $args['minimum'] ) ) { - if ( ! empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) { - if ( $value >= $args['maximum'] || $value <= $args['minimum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (exclusive) and %d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); - } - } else if ( empty( $args['exclusiveMinimum'] ) && ! empty( $args['exclusiveMaximum'] ) ) { - if ( $value >= $args['maximum'] || $value < $args['minimum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (inclusive) and %d (exclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); - } - } else if ( ! empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) { - if ( $value > $args['maximum'] || $value <= $args['minimum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (exclusive) and %d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); - } - } else if ( empty( $args['exclusiveMinimum'] ) && empty( $args['exclusiveMaximum'] ) ) { - if ( $value > $args['maximum'] || $value < $args['minimum'] ) { - return new WP_Error( 'rest_invalid_param', sprintf( __( '%s must be between %d (inclusive) and %d (inclusive)' ), $param, $args['minimum'], $args['maximum'] ) ); - } - } - } - } - - return true; - } -} - -if ( ! function_exists( 'rest_sanitize_request_arg' ) ) { - /** - * Sanitize a request argument based on details registered to the route. - * - * @param mixed $value - * @param WP_REST_Request $request - * @param string $param - * @return mixed - */ - function rest_sanitize_request_arg( $value, $request, $param ) { - - $attributes = $request->get_attributes(); - if ( ! isset( $attributes['args'][ $param ] ) || ! is_array( $attributes['args'][ $param ] ) ) { - return $value; - } - $args = $attributes['args'][ $param ]; - - if ( 'integer' === $args['type'] ) { - return (int) $value; - } - - if ( isset( $args['format'] ) ) { - switch ( $args['format'] ) { - case 'date-time' : - return sanitize_text_field( $value ); - - case 'email' : - /* - * sanitize_email() validates, which would be unexpected - */ - return sanitize_text_field( $value ); - - case 'uri' : - return esc_url_raw( $value ); - } - } - - return $value; - } - -} From 1a95055303dd559ad79cab76c1f904ece92ef00c Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 16:01:14 -0600 Subject: [PATCH 145/298] Call register_legacy_settings() directly instead of adding another hook. --- includes/class-wc-api.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 9f86a3e978b..2d69d7fee26 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -121,9 +121,6 @@ class WC_API extends WC_Legacy_API { // Init REST API routes. add_action( 'rest_api_init', array( $this, 'register_rest_routes' ) ); - - // Register legacy settings to the REST API. - add_action( 'rest_api_init', array( $this, 'register_legacy_settings' ) ); } /** @@ -179,6 +176,9 @@ class WC_API extends WC_Legacy_API { * @since 2.6.0 */ public function register_rest_routes() { + // Register legacy settings to the REST API. + $this->register_legacy_settings(); + $controllers = array( 'WC_REST_Coupons_Controller', 'WC_REST_Customer_Downloads_Controller', From 226fdb870bcbbfbc6aa2ff9854414f96b1ff9abf Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 19 Jul 2016 11:24:05 -0700 Subject: [PATCH 146/298] Misc cleanup of descriptions and some error strings. --- .../api/class-wc-rest-settings-controller.php | 6 +++-- ...ss-wc-rest-settings-options-controller.php | 19 +++++++++----- .../class-wc-register-legacy-settings.php | 9 ++++--- .../helpers/class-wc-helper-settings.php | 3 +++ tests/unit-tests/api/settings.php | 25 ++++++++++++++++++- .../settings/register-legacy-settings.php | 13 ++++++++-- 6 files changed, 61 insertions(+), 14 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index 560bd125466..467912eb72a 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -29,6 +29,7 @@ class WC_Rest_Settings_Controller extends WC_REST_Controller { /** * Register routes. + * * @since 2.7.0 */ public function register_routes() { @@ -101,6 +102,7 @@ class WC_Rest_Settings_Controller extends WC_REST_Controller { /** * Prepare a report sales object for serialization. * + * @since 2.7.0 * @param array $item Group object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. @@ -194,14 +196,14 @@ class WC_Rest_Settings_Controller extends WC_REST_Controller { ), ), 'label' => array( - 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable translation wrapped label. Meant to be used in interfaces.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'description' => array( - 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable translation wrapped description. Meant to be used in interfaces', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', diff --git a/includes/api/class-wc-rest-settings-options-controller.php b/includes/api/class-wc-rest-settings-options-controller.php index 5086d2107ae..1e3fe20d0b8 100644 --- a/includes/api/class-wc-rest-settings-options-controller.php +++ b/includes/api/class-wc-rest-settings-options-controller.php @@ -29,6 +29,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Register routes. + * * @since 2.7.0 */ public function register_routes() { @@ -69,6 +70,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Return a single setting. + * * @since 2.7.0 * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response @@ -87,6 +89,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Return all settings in a group. + * * @since 2.7.0 * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response @@ -112,19 +115,19 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Get all settings in a group. * + * @since 2.7.0 * @param string $group_id Group ID. - * * @return array|WP_Error */ public function get_group_settings( $group_id ) { if ( empty( $group_id ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } $settings = apply_filters( 'woocommerce_settings-' . $group_id, array() ); if ( empty( $settings ) ) { - return new WP_Error( 'rest_setting_setting_invalid', __( 'Invalid setting.', 'woocommerce' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_setting_setting_group_invalid', __( 'Invalid setting group.', 'woocommerce' ), array( 'status' => 404 ) ); } $filtered_settings = array(); @@ -143,9 +146,9 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Get setting data. * + * @since 2.7.0 * @param string $group_id Group ID. * @param string $setting_id Setting ID. - * * @return stdClass|WP_Error */ public function get_setting( $group_id, $setting_id ) { @@ -177,6 +180,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Bulk create, update and delete items. * + * @since 2.7.0 * @param WP_REST_Request $request Full details about the request. * @return array Of WP_Error or WP_REST_Response. */ @@ -202,6 +206,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Update a single setting in a group. + * @since 2.7.0 * @param WP_REST_Request $request * @return WP_Error|WP_REST_Response @@ -226,6 +231,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Prepare a single setting object for response. * + * @since 2.7.0 * @param object $item Setting object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response $response Response data. @@ -248,6 +254,7 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { /** * Prepare links for the request. * + * @since 2.7.0 * @param string $setting_id Setting ID. * @param string $group_id Group ID. * @return array Links for the given setting. @@ -366,14 +373,14 @@ class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { ), ), 'label' => array( - 'description' => __( 'A human readable label. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable translation wrapped label. Meant to be used in interfaces.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'description' => array( - 'description' => __( 'A human readable description. This is a translated string that can be used in interfaces.', 'woocommerce' ), + 'description' => __( 'A human readable translation wrapped description. Meant to be used in interfaces.', 'woocommerce' ), 'type' => 'string', 'arg_options' => array( 'sanitize_callback' => 'sanitize_text_field', diff --git a/includes/class-wc-register-legacy-settings.php b/includes/class-wc-register-legacy-settings.php index eb32b02df35..a342c414947 100644 --- a/includes/class-wc-register-legacy-settings.php +++ b/includes/class-wc-register-legacy-settings.php @@ -9,7 +9,7 @@ if ( ! defined( 'ABSPATH' ) ) { * * @version 2.7.0 * @since 2.7.0 - * @package WooCommerce/Classes + * @package WooCommerce/Classes * @category Class */ class WC_Register_Legacy_Settings { @@ -19,6 +19,7 @@ class WC_Register_Legacy_Settings { /** * Hooks into the settings API and starts registering our settings registered via legacy hooks/filters. + * * @since 2.7.0 */ public function __construct( $page ) { @@ -29,6 +30,7 @@ class WC_Register_Legacy_Settings { /** * Registers a setting group. + * * @since 2.7.0 * @param array $group * @return array @@ -43,6 +45,7 @@ class WC_Register_Legacy_Settings { /** * Registers the actual settings to the group they came from. + * * @since 2.7.0 * @param array $settings Existing registered settings * @return array @@ -67,10 +70,10 @@ class WC_Register_Legacy_Settings { /** * Convert a "legacy" setting (WC_Settings_Page::get_settings()) into the format expected - * for the REST API Settings Controller + * for the REST API Settings Controller. * + * @since 2.7.0 * @param $legacy_setting Settings array, as produced by a subclass of WC_Settings_Page. - * * @return array|bool Boolean false if legacy setting has no ID, Array of converted new setting otherwise. */ public function new_setting_from_legacy( $legacy_setting ) { diff --git a/tests/framework/helpers/class-wc-helper-settings.php b/tests/framework/helpers/class-wc-helper-settings.php index 2a042bc624b..93495166dee 100644 --- a/tests/framework/helpers/class-wc-helper-settings.php +++ b/tests/framework/helpers/class-wc-helper-settings.php @@ -9,6 +9,7 @@ class WC_Helper_Settings { /** * Hooks in some dummy data for testing the settings REST API. + * * @since 2.7.0 */ public static function register() { @@ -18,6 +19,7 @@ class WC_Helper_Settings { /** * Registers some example setting groups, including invalid ones that should not show up in JSON responses. + * * @since 2.7.0 * @param array $groups * @return array @@ -47,6 +49,7 @@ class WC_Helper_Settings { /** * Registers some example settings. + * * @since 2.7.0 * @param array $settings * @return array diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index f9cd9faaf95..0b64745685b 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -1,7 +1,8 @@ endpoint->get_setting( 'test', '' ); @@ -396,6 +411,8 @@ class Settings extends WC_Unit_Test_Case { /** * Tests the GET single setting route handler receiving an invalid setting ID. + * + * @since 2.7.0 */ public function test_get_setting_invalid_setting_id() { $result = $this->endpoint->get_setting( 'test', 'invalid' ); @@ -405,6 +422,8 @@ class Settings extends WC_Unit_Test_Case { /** * Tests the GET single setting route handler encountering an invalid setting type. + * + * @since 2.7.0 */ public function test_get_setting_invalid_setting_type() { $controller = $this->getMock( 'WC_Rest_Settings_Options_Controller', array( 'get_group_settings', 'is_setting_type_valid' ) ); @@ -426,6 +445,7 @@ class Settings extends WC_Unit_Test_Case { /** * Test updating a single setting without valid user permissions. + * * @since 2.7.0 */ public function test_update_setting_without_permission() { @@ -442,6 +462,7 @@ class Settings extends WC_Unit_Test_Case { /** * Test updating multiple settings without valid user permissions. + * * @since 2.7.0 */ public function test_update_settings_without_permission() { @@ -462,6 +483,7 @@ class Settings extends WC_Unit_Test_Case { /** * Test updating a bad setting ID. + * * @since 2.7.0 * @covers WC_Rest_Settings_Options_Controller::update_item */ @@ -478,6 +500,7 @@ class Settings extends WC_Unit_Test_Case { /** * Tests our classic setting registration to make sure settings added for WP-Admin are available over the API. + * * @since 2.7.0 */ public function test_classic_settings() { diff --git a/tests/unit-tests/settings/register-legacy-settings.php b/tests/unit-tests/settings/register-legacy-settings.php index 2fa41ce58c9..8f94342c174 100644 --- a/tests/unit-tests/settings/register-legacy-settings.php +++ b/tests/unit-tests/settings/register-legacy-settings.php @@ -2,6 +2,7 @@ /** * Settings API Tests + * * @package WooCommerce\Tests\Settings * @since 2.7.0 */ @@ -34,16 +35,18 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { } /** + * @since 2.7.0 * @covers WC_Register_Legacy_Settings::__construct */ public function test_constructor() { $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); - + $this->assertEquals( has_filter( 'woocommerce_settings_groups', array( $legacy_settings, 'register_legacy_group' ) ), 10 ); $this->assertEquals( has_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $legacy_settings, 'register_legacy_settings' ) ), 10 ); } /** + * @since 2.7.0 * @covers WC_Register_Legacy_Settings::register_legacy_group */ public function test_register_legacy_group() { @@ -66,6 +69,9 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { $this->assertEquals( $expected, $actual ); } + /** + * @since 2.7.0 + */ public function new_setting_from_legacy_provider() { return array( // No "id" case @@ -145,6 +151,7 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { } /** + * @since 2.7.0 * @dataProvider new_setting_from_legacy_provider * @covers WC_Register_Legacy_Settings::new_setting_from_legacy */ @@ -157,6 +164,7 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { } /** + * @since 2.7.0 * @covers WC_Register_Legacy_Settings::register_legacy_settings */ public function test_register_legacy_settings_one_section() { @@ -180,6 +188,7 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { } /** + * @since 2.7.0 * @covers WC_Register_Legacy_Settings::register_legacy_settings */ public function test_register_legacy_settings() { @@ -227,4 +236,4 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { $this->assertEquals( $expected, $actual ); } -} \ No newline at end of file +} From 48e6be6dcf3b8133bb5610271d5b0ff151fe2545 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 19 Jul 2016 11:38:18 -0700 Subject: [PATCH 147/298] Move WP-APIs test server code to a vendor directory, make sure it matches the version of the other vendor files. --- tests/bootstrap.php | 5 ++--- .../framework/{ => vendor}/class-wp-test-spy-rest-server.php | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) rename tests/framework/{ => vendor}/class-wp-test-spy-rest-server.php (91%) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 87e65f64053..20ddc8ba5a6 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -115,10 +115,9 @@ class WC_Unit_Tests_Bootstrap { require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-settings.php' ); /** - * WP-API - * @todo to be removed when the wp-api branch is merged. + * WP-API. */ - require_once( $this->tests_dir . '/framework/class-wp-test-spy-rest-server.php' ); + require_once( $this->tests_dir . '/framework/vendor/class-wp-test-spy-rest-server.php' ); } /** diff --git a/tests/framework/class-wp-test-spy-rest-server.php b/tests/framework/vendor/class-wp-test-spy-rest-server.php similarity index 91% rename from tests/framework/class-wp-test-spy-rest-server.php rename to tests/framework/vendor/class-wp-test-spy-rest-server.php index ba485b65a1a..4d08c783bd9 100644 --- a/tests/framework/class-wp-test-spy-rest-server.php +++ b/tests/framework/vendor/class-wp-test-spy-rest-server.php @@ -1,7 +1,6 @@ Date: Tue, 26 Jul 2016 11:08:29 -0700 Subject: [PATCH 148/298] Rename helper class from 'legacy' to be more descriptive of whats happening. Registering wp-admin settings to the REST API. --- includes/class-wc-api.php | 10 +- .../class-wc-register-legacy-settings.php | 105 ----------------- .../class-wc-register-wp-admin-settings.php | 111 ++++++++++++++++++ ...ngs.php => register-wp-admin-settings.php} | 50 ++++---- woocommerce.php | 2 +- 5 files changed, 143 insertions(+), 135 deletions(-) delete mode 100644 includes/class-wc-register-legacy-settings.php create mode 100644 includes/class-wc-register-wp-admin-settings.php rename tests/unit-tests/settings/{register-legacy-settings.php => register-wp-admin-settings.php} (73%) diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 2d69d7fee26..57af7e23649 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -176,8 +176,8 @@ class WC_API extends WC_Legacy_API { * @since 2.6.0 */ public function register_rest_routes() { - // Register legacy settings to the REST API. - $this->register_legacy_settings(); + // Register settings to the REST API. + $this->register_wp_admin_settings(); $controllers = array( 'WC_REST_Coupons_Controller', @@ -211,13 +211,13 @@ class WC_API extends WC_Legacy_API { } /** - * Register legacy settings to the REST API. + * Register WC settings from WP-API to the REST API. * @since 2.7.0 */ - public function register_legacy_settings() { + public function register_wp_admin_settings() { $pages = WC_Admin_Settings::get_settings_pages(); foreach ( $pages as $page ) { - new WC_Register_Legacy_Settings( $page ); + new WC_Register_WP_Admin_Settings( $page ); } } } diff --git a/includes/class-wc-register-legacy-settings.php b/includes/class-wc-register-legacy-settings.php deleted file mode 100644 index a342c414947..00000000000 --- a/includes/class-wc-register-legacy-settings.php +++ /dev/null @@ -1,105 +0,0 @@ -page = $page; - add_filter( 'woocommerce_settings_groups', array( $this, 'register_legacy_group' ) ); - add_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $this, 'register_legacy_settings' ) ); - } - - /** - * Registers a setting group. - * - * @since 2.7.0 - * @param array $group - * @return array - */ - public function register_legacy_group( $groups ) { - $groups[] = array( - 'id' => $this->page->get_id(), - 'label' => $this->page->get_label(), - ); - return $groups; - } - - /** - * Registers the actual settings to the group they came from. - * - * @since 2.7.0 - * @param array $settings Existing registered settings - * @return array - */ - public function register_legacy_settings( $settings ) { - $legacy_sections = $this->page->get_sections(); - if ( empty( $legacy_sections ) ) { - $legacy_sections = array( '' ); - } - - foreach ( $legacy_sections as $legacy_section => $legacy_section_label ) { - $legacy_settings = $this->page->get_settings( $legacy_section ); - foreach ( $legacy_settings as $legacy_setting ) { - $new_setting = $this->new_setting_from_legacy( $legacy_setting ); - if ( $new_setting ) { - $settings[] = $new_setting; - } - } - } - return $settings; - } - - /** - * Convert a "legacy" setting (WC_Settings_Page::get_settings()) into the format expected - * for the REST API Settings Controller. - * - * @since 2.7.0 - * @param $legacy_setting Settings array, as produced by a subclass of WC_Settings_Page. - * @return array|bool Boolean false if legacy setting has no ID, Array of converted new setting otherwise. - */ - public function new_setting_from_legacy( $legacy_setting ) { - if ( ! isset( $legacy_setting['id'] ) ) { - return false; - } - $new_setting = array( - 'id' => $legacy_setting['id'], - 'label' => ( ! empty( $legacy_setting['title'] ) ? $legacy_setting['title'] : '' ), - 'description' => ( ! empty( $legacy_setting['desc'] ) ? $legacy_setting['desc'] : '' ), - 'type' => $legacy_setting['type'], - ); - if ( isset( $legacy_setting['default'] ) ) { - $new_setting['default'] = $legacy_setting['default']; - } - if ( isset( $legacy_setting['options'] ) ) { - $new_setting['options'] = $legacy_setting['options']; - } - if ( isset( $legacy_setting['desc_tip'] ) ) { - if ( true === $legacy_setting['desc_tip'] ) { - $new_setting['tip'] = $legacy_setting['desc']; - } else if ( ! empty( $legacy_setting['desc_tip'] ) ) { - $new_setting['tip'] = $legacy_setting['desc_tip']; - } - } - - return $new_setting; - } -} diff --git a/includes/class-wc-register-wp-admin-settings.php b/includes/class-wc-register-wp-admin-settings.php new file mode 100644 index 00000000000..361ce6a60d2 --- /dev/null +++ b/includes/class-wc-register-wp-admin-settings.php @@ -0,0 +1,111 @@ +page = $page; + add_filter( 'woocommerce_settings_groups', array( $this, 'register_group' ) ); + add_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $this, 'register_settings' ) ); + } + + /** + * Registers a setting group, based on admin page ID & label as parent group. + * + * @since 2.7.0 + * @param array $groups Array of previously registered groups. + * @return array + */ + public function register_group( $groups ) { + $groups[] = array( + 'id' => $this->page->get_id(), + 'label' => $this->page->get_label(), + ); + return $groups; + } + + /** + * Registers settings to a specific group. + * + * @since 2.7.0 + * @param array $settings Existing registered settings + * @return array + */ + public function register_settings( $settings ) { + /** + * wp-admin settings can be broken down into separate sections from + * a UI standpoint. This will grab all the sections associated with + * a particular setting group (like 'products') and register them + * to the REST API. + */ + $sections = $this->page->get_sections(); + if ( empty( $sections ) ) { + // Default section is just an empty string, per admin page classes + $sections = array( '' ); + } + + foreach ( $sections as $section => $section_label ) { + $settings_from_section = $this->page->get_settings( $section ); + foreach ( $settings_from_section as $setting ) { + $new_setting = $this->register_setting( $setting ); + if ( $new_setting ) { + $settings[] = $new_setting; + } + } + } + return $settings; + } + + /** + * Register's a specific setting (from WC_Settings_Page::get_settings() ) + * into the format expected for the REST API Settings Controller. + * + * @since 2.7.0 + * @param array $setting Settings array, as produced by a subclass of WC_Settings_Page. + * @return array|bool boolean False if setting has no ID or converted array. + */ + public function register_setting( $setting ) { + if ( ! isset( $setting['id'] ) ) { + return false; + } + $new_setting = array( + 'id' => $setting['id'], + 'label' => ( ! empty( $setting['title'] ) ? $setting['title'] : '' ), + 'description' => ( ! empty( $setting['desc'] ) ? $setting['desc'] : '' ), + 'type' => $setting['type'], + ); + if ( isset( $setting['default'] ) ) { + $new_setting['default'] = $setting['default']; + } + if ( isset( $setting['options'] ) ) { + $new_setting['options'] = $setting['options']; + } + if ( isset( $setting['desc_tip'] ) ) { + if ( true === $setting['desc_tip'] ) { + $new_setting['tip'] = $setting['desc']; + } else if ( ! empty( $setting['desc_tip'] ) ) { + $new_setting['tip'] = $setting['desc_tip']; + } + } + + return $new_setting; + } +} diff --git a/tests/unit-tests/settings/register-legacy-settings.php b/tests/unit-tests/settings/register-wp-admin-settings.php similarity index 73% rename from tests/unit-tests/settings/register-legacy-settings.php rename to tests/unit-tests/settings/register-wp-admin-settings.php index 8f94342c174..0a8f29dc32c 100644 --- a/tests/unit-tests/settings/register-legacy-settings.php +++ b/tests/unit-tests/settings/register-wp-admin-settings.php @@ -1,12 +1,14 @@ page ); + $settings = new WC_Register_WP_Admin_Settings( $this->page ); - $this->assertEquals( has_filter( 'woocommerce_settings_groups', array( $legacy_settings, 'register_legacy_group' ) ), 10 ); - $this->assertEquals( has_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $legacy_settings, 'register_legacy_settings' ) ), 10 ); + $this->assertEquals( has_filter( 'woocommerce_settings_groups', array( $settings, 'register_group' ) ), 10 ); + $this->assertEquals( has_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $settings, 'register_settings' ) ), 10 ); } /** * @since 2.7.0 - * @covers WC_Register_Legacy_Settings::register_legacy_group + * @covers WC_Register_WP_Admin_Settings::register_group */ - public function test_register_legacy_group() { - $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); + public function test_register_group() { + $settings = new WC_Register_WP_Admin_Settings( $this->page ); $existing = array( 'id' => 'existing-id', @@ -64,7 +66,7 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { 'label' => $this->page->get_label(), ), ); - $actual = $legacy_settings->register_legacy_group( $initial ); + $actual = $settings->register_group( $initial ); $this->assertEquals( $expected, $actual ); } @@ -72,7 +74,7 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { /** * @since 2.7.0 */ - public function new_setting_from_legacy_provider() { + public function register_setting_provider() { return array( // No "id" case array( @@ -152,22 +154,22 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { /** * @since 2.7.0 - * @dataProvider new_setting_from_legacy_provider - * @covers WC_Register_Legacy_Settings::new_setting_from_legacy + * @dataProvider register_setting_provider + * @covers WC_Register_WP_Admin_Settings::register_setting */ - public function test_new_setting_from_legacy( $input, $expected ) { - $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); + public function test_register_setting( $input, $expected ) { + $settings = new WC_Register_WP_Admin_Settings( $this->page ); - $actual = $legacy_settings->new_setting_from_legacy( $input ); + $actual = $settings->register_setting( $input ); $this->assertEquals( $expected, $actual ); } /** * @since 2.7.0 - * @covers WC_Register_Legacy_Settings::register_legacy_settings + * @covers WC_Register_WP_Admin_Settings::register_settings */ - public function test_register_legacy_settings_one_section() { + public function test_register_settings_one_section() { $this->page ->expects( $this->any() ) ->method( 'get_sections' ) @@ -179,19 +181,19 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { ->with( $this->equalTo( 0 ) ) ->will( $this->returnValue( array() ) ); - $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); + $settings = new WC_Register_WP_Admin_Settings( $this->page ); $expected = array(); - $actual = $legacy_settings->register_legacy_settings( array() ); + $actual = $settings->register_settings( array() ); $this->assertEquals( $expected, $actual ); } /** * @since 2.7.0 - * @covers WC_Register_Legacy_Settings::register_legacy_settings + * @covers WC_Register_WP_Admin_Settings::register_settings */ - public function test_register_legacy_settings() { + public function test_register_settings() { $this->page ->expects( $this->any() ) ->method( 'get_sections' ) @@ -216,7 +218,7 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { ->method( 'get_settings' ) ->will( $this->returnValue( $settings ) ); - $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); + $settings = new WC_Register_WP_Admin_Settings( $this->page ); $expected = array( array( @@ -232,7 +234,7 @@ class WC_Tests_Register_Legacy_Settings extends WC_Unit_Test_Case { 'description' => '', ), ); - $actual = $legacy_settings->register_legacy_settings( array() ); + $actual = $settings->register_settings( array() ); $this->assertEquals( $expected, $actual ); } diff --git a/woocommerce.php b/woocommerce.php index 7ca687dc438..ba40cc0cd77 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -226,7 +226,7 @@ final class WooCommerce { public function includes() { include_once( 'includes/class-wc-autoloader.php' ); include_once( 'includes/wc-core-functions.php' ); - include_once( 'includes/class-wc-register-legacy-settings.php' ); + include_once( 'includes/class-wc-register-wp-admin-settings.php' ); include_once( 'includes/wc-widget-functions.php' ); include_once( 'includes/wc-webhook-functions.php' ); include_once( 'includes/class-wc-install.php' ); From 55b37b3338c72889234bc84e2ac79d6bb8be9a2c Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 26 Jul 2016 11:08:29 -0700 Subject: [PATCH 149/298] Rename helper class from 'legacy' to be more descriptive of whats happening. Registering wp-admin settings to the REST API. --- .../class-wc-register-legacy-settings.php | 105 -------- .../settings/register-legacy-settings.php | 239 ------------------ 2 files changed, 344 deletions(-) delete mode 100644 includes/class-wc-register-legacy-settings.php delete mode 100644 tests/unit-tests/settings/register-legacy-settings.php diff --git a/includes/class-wc-register-legacy-settings.php b/includes/class-wc-register-legacy-settings.php deleted file mode 100644 index a342c414947..00000000000 --- a/includes/class-wc-register-legacy-settings.php +++ /dev/null @@ -1,105 +0,0 @@ -page = $page; - add_filter( 'woocommerce_settings_groups', array( $this, 'register_legacy_group' ) ); - add_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $this, 'register_legacy_settings' ) ); - } - - /** - * Registers a setting group. - * - * @since 2.7.0 - * @param array $group - * @return array - */ - public function register_legacy_group( $groups ) { - $groups[] = array( - 'id' => $this->page->get_id(), - 'label' => $this->page->get_label(), - ); - return $groups; - } - - /** - * Registers the actual settings to the group they came from. - * - * @since 2.7.0 - * @param array $settings Existing registered settings - * @return array - */ - public function register_legacy_settings( $settings ) { - $legacy_sections = $this->page->get_sections(); - if ( empty( $legacy_sections ) ) { - $legacy_sections = array( '' ); - } - - foreach ( $legacy_sections as $legacy_section => $legacy_section_label ) { - $legacy_settings = $this->page->get_settings( $legacy_section ); - foreach ( $legacy_settings as $legacy_setting ) { - $new_setting = $this->new_setting_from_legacy( $legacy_setting ); - if ( $new_setting ) { - $settings[] = $new_setting; - } - } - } - return $settings; - } - - /** - * Convert a "legacy" setting (WC_Settings_Page::get_settings()) into the format expected - * for the REST API Settings Controller. - * - * @since 2.7.0 - * @param $legacy_setting Settings array, as produced by a subclass of WC_Settings_Page. - * @return array|bool Boolean false if legacy setting has no ID, Array of converted new setting otherwise. - */ - public function new_setting_from_legacy( $legacy_setting ) { - if ( ! isset( $legacy_setting['id'] ) ) { - return false; - } - $new_setting = array( - 'id' => $legacy_setting['id'], - 'label' => ( ! empty( $legacy_setting['title'] ) ? $legacy_setting['title'] : '' ), - 'description' => ( ! empty( $legacy_setting['desc'] ) ? $legacy_setting['desc'] : '' ), - 'type' => $legacy_setting['type'], - ); - if ( isset( $legacy_setting['default'] ) ) { - $new_setting['default'] = $legacy_setting['default']; - } - if ( isset( $legacy_setting['options'] ) ) { - $new_setting['options'] = $legacy_setting['options']; - } - if ( isset( $legacy_setting['desc_tip'] ) ) { - if ( true === $legacy_setting['desc_tip'] ) { - $new_setting['tip'] = $legacy_setting['desc']; - } else if ( ! empty( $legacy_setting['desc_tip'] ) ) { - $new_setting['tip'] = $legacy_setting['desc_tip']; - } - } - - return $new_setting; - } -} diff --git a/tests/unit-tests/settings/register-legacy-settings.php b/tests/unit-tests/settings/register-legacy-settings.php deleted file mode 100644 index 8f94342c174..00000000000 --- a/tests/unit-tests/settings/register-legacy-settings.php +++ /dev/null @@ -1,239 +0,0 @@ -getMock( 'WC_Settings_General' ); - - $mock_page - ->expects( $this->any() ) - ->method( 'get_id' ) - ->will( $this->returnValue( 'page-id' ) ); - - $mock_page - ->expects( $this->any() ) - ->method( 'get_label' ) - ->will( $this->returnValue( 'Page Label' ) ); - - $this->page = $mock_page; - } - - /** - * @since 2.7.0 - * @covers WC_Register_Legacy_Settings::__construct - */ - public function test_constructor() { - $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); - - $this->assertEquals( has_filter( 'woocommerce_settings_groups', array( $legacy_settings, 'register_legacy_group' ) ), 10 ); - $this->assertEquals( has_filter( 'woocommerce_settings-' . $this->page->get_id(), array( $legacy_settings, 'register_legacy_settings' ) ), 10 ); - } - - /** - * @since 2.7.0 - * @covers WC_Register_Legacy_Settings::register_legacy_group - */ - public function test_register_legacy_group() { - $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); - - $existing = array( - 'id' => 'existing-id', - 'label' => 'Existing Group', - ); - $initial = array( $existing ); - $expected = array( - $existing, - array( - 'id' => $this->page->get_id(), - 'label' => $this->page->get_label(), - ), - ); - $actual = $legacy_settings->register_legacy_group( $initial ); - - $this->assertEquals( $expected, $actual ); - } - - /** - * @since 2.7.0 - */ - public function new_setting_from_legacy_provider() { - return array( - // No "id" case - array( - array( - 'type' => 'some-type-with-no-id', - ), - false, - ), - // All optional properties except 'desc_tip' - array( - array( - 'id' => 'setting-id', - 'type' => 'select', - 'title' => 'Setting Name', - 'desc' => 'Setting Description', - 'default' => 'one', - 'options' => array( 'one', 'two' ), - ), - array( - 'id' => 'setting-id', - 'type' => 'select', - 'label' => 'Setting Name', - 'description' => 'Setting Description', - 'default' => 'one', - 'options' => array( 'one', 'two' ), - ), - ), - // Boolean 'desc_tip' defaulting to 'desc' value - array( - array( - 'id' => 'setting-id', - 'type' => 'select', - 'title' => 'Setting Name', - 'desc' => 'Setting Description', - 'desc_tip' => true, - ), - array( - 'id' => 'setting-id', - 'type' => 'select', - 'label' => 'Setting Name', - 'description' => 'Setting Description', - 'tip' => 'Setting Description', - ), - ), - // String 'desc_tip' - array( - array( - 'id' => 'setting-id', - 'type' => 'select', - 'title' => 'Setting Name', - 'desc' => 'Setting Description', - 'desc_tip' => 'Setting Tip', - ), - array( - 'id' => 'setting-id', - 'type' => 'select', - 'label' => 'Setting Name', - 'description' => 'Setting Description', - 'tip' => 'Setting Tip', - ), - ), - // Empty 'title' and 'desc' - array( - array( - 'id' => 'setting-id', - 'type' => 'select', - ), - array( - 'id' => 'setting-id', - 'type' => 'select', - 'label' => '', - 'description' => '', - ), - ), - ); - } - - /** - * @since 2.7.0 - * @dataProvider new_setting_from_legacy_provider - * @covers WC_Register_Legacy_Settings::new_setting_from_legacy - */ - public function test_new_setting_from_legacy( $input, $expected ) { - $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); - - $actual = $legacy_settings->new_setting_from_legacy( $input ); - - $this->assertEquals( $expected, $actual ); - } - - /** - * @since 2.7.0 - * @covers WC_Register_Legacy_Settings::register_legacy_settings - */ - public function test_register_legacy_settings_one_section() { - $this->page - ->expects( $this->any() ) - ->method( 'get_sections' ) - ->will( $this->returnValue( array() ) ); - - $this->page - ->expects( $this->once() ) - ->method( 'get_settings' ) - ->with( $this->equalTo( 0 ) ) - ->will( $this->returnValue( array() ) ); - - $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); - - $expected = array(); - $actual = $legacy_settings->register_legacy_settings( array() ); - - $this->assertEquals( $expected, $actual ); - } - - /** - * @since 2.7.0 - * @covers WC_Register_Legacy_Settings::register_legacy_settings - */ - public function test_register_legacy_settings() { - $this->page - ->expects( $this->any() ) - ->method( 'get_sections' ) - ->will( $this->returnValue( array() ) ); - - $settings = array( - array( - 'id' => 'setting-1', - 'type' => 'text', - ), - array( - 'type' => 'no-id', - ), - array( - 'id' => 'setting-2', - 'type' => 'textarea', - ), - ); - - $this->page - ->expects( $this->any() ) - ->method( 'get_settings' ) - ->will( $this->returnValue( $settings ) ); - - $legacy_settings = new WC_Register_Legacy_Settings( $this->page ); - - $expected = array( - array( - 'id' => 'setting-1', - 'type' => 'text', - 'label' => '', - 'description' => '', - ), - array( - 'id' => 'setting-2', - 'type' => 'textarea', - 'label' => '', - 'description' => '', - ), - ); - $actual = $legacy_settings->register_legacy_settings( array() ); - - $this->assertEquals( $expected, $actual ); - } -} From 28611544b8106935270c9bcd7e780d111f0e7303 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 26 Jul 2016 13:57:30 -0700 Subject: [PATCH 150/298] Remote spy-server --- .../vendor/class-wp-test-spy-rest-server.php | 37 ------------------- 1 file changed, 37 deletions(-) delete mode 100644 tests/framework/vendor/class-wp-test-spy-rest-server.php diff --git a/tests/framework/vendor/class-wp-test-spy-rest-server.php b/tests/framework/vendor/class-wp-test-spy-rest-server.php deleted file mode 100644 index 4d08c783bd9..00000000000 --- a/tests/framework/vendor/class-wp-test-spy-rest-server.php +++ /dev/null @@ -1,37 +0,0 @@ -endpoints; - } - - /** - * Allow calling protected methods from tests - * - * @param string $method Method to call - * @param array $args Arguments to pass to the method - * @return mixed - */ - public function __call( $method, $args ) { - return call_user_func_array( array( $this, $method ), $args ); - } - - /** - * Call dispatch() with the rest_post_dispatch filter - */ - public function dispatch( $request ) { - $result = parent::dispatch( $request ); - $result = rest_ensure_response( $result ); - if ( is_wp_error( $result ) ) { - $result = $this->error_to_response( $result ); - } - return apply_filters( 'rest_post_dispatch', rest_ensure_response( $result ), $this, $request ); - } -} From 5bdf2fb9e4aa98850fc2219f1b1441c93b0421cb Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 26 Jul 2016 13:58:22 -0700 Subject: [PATCH 151/298] Remove call to spy server --- tests/bootstrap.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 20ddc8ba5a6..fbe3abfbdea 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -113,11 +113,6 @@ class WC_Unit_Tests_Bootstrap { require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-shipping-zones.php' ); require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-payment-token.php' ); require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-settings.php' ); - - /** - * WP-API. - */ - require_once( $this->tests_dir . '/framework/vendor/class-wp-test-spy-rest-server.php' ); } /** From 9adce86239ce719bd2d6075d582d46198348d7cd Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 26 Jul 2016 14:19:50 -0700 Subject: [PATCH 152/298] Use the new REST unit test base class --- tests/unit-tests/api/settings.php | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/tests/unit-tests/api/settings.php b/tests/unit-tests/api/settings.php index 0b64745685b..8f9c0583373 100644 --- a/tests/unit-tests/api/settings.php +++ b/tests/unit-tests/api/settings.php @@ -1,12 +1,12 @@ server = $wp_rest_server = new WP_Test_Spy_REST_Server; - do_action( 'rest_api_init' ); $this->endpoint = new WC_Rest_Settings_Options_Controller(); WC_Helper_Settings::register(); $this->user = $this->factory->user->create( array( @@ -25,15 +22,6 @@ class Settings extends WC_Unit_Test_Case { ) ); } - /** - * Unset the server. - */ - public function tearDown() { - parent::tearDown(); - global $wp_rest_server; - $wp_rest_server = null; - } - /** * Test route registration. * From 1d4615aee31f7f660b4d30883428bfbf13ce0c7a Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 26 Jul 2016 14:33:55 -0700 Subject: [PATCH 153/298] Fix setting class case. REST should be uppercase. --- includes/api/class-wc-rest-settings-controller.php | 2 +- includes/api/class-wc-rest-settings-options-controller.php | 2 +- includes/class-wc-api.php | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/includes/api/class-wc-rest-settings-controller.php b/includes/api/class-wc-rest-settings-controller.php index 467912eb72a..98cbc31f9b3 100644 --- a/includes/api/class-wc-rest-settings-controller.php +++ b/includes/api/class-wc-rest-settings-controller.php @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Controller extends WC_REST_Controller { +class WC_REST_Settings_Controller extends WC_REST_Controller { /** * WP REST API namespace/version. diff --git a/includes/api/class-wc-rest-settings-options-controller.php b/includes/api/class-wc-rest-settings-options-controller.php index 1e3fe20d0b8..ee993905efb 100644 --- a/includes/api/class-wc-rest-settings-options-controller.php +++ b/includes/api/class-wc-rest-settings-options-controller.php @@ -13,7 +13,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @version 2.7.0 * @since 2.7.0 */ -class WC_Rest_Settings_Options_Controller extends WC_REST_Controller { +class WC_REST_Settings_Options_Controller extends WC_REST_Controller { /** * WP REST API namespace/version. diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index a33b0054886..41587e21343 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -196,8 +196,8 @@ class WC_API extends WC_Legacy_API { 'WC_REST_Report_Sales_Controller', 'WC_REST_Report_Top_Sellers_Controller', 'WC_REST_Reports_Controller', - 'WC_Rest_Settings_Controller', - 'WC_Rest_Settings_Options_Controller', + 'WC_REST_Settings_Controller', + 'WC_REST_Settings_Options_Controller', 'WC_REST_Tax_Classes_Controller', 'WC_REST_Taxes_Controller', 'WC_REST_Webhook_Deliveries_Controller', From 052f4d9cc356f97b2fbbaba346af04e2d6f7476d Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 27 Jul 2016 10:13:03 +0100 Subject: [PATCH 154/298] Update education text Closes #11519 --- includes/admin/class-wc-admin-help.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/admin/class-wc-admin-help.php b/includes/admin/class-wc-admin-help.php index eace3cc963d..d790c3224b7 100644 --- a/includes/admin/class-wc-admin-help.php +++ b/includes/admin/class-wc-admin-help.php @@ -212,7 +212,7 @@ class WC_Admin_Help { 'title' => __( 'Education', 'woocommerce' ), 'content' => '

    ' . __( 'Education', 'woocommerce' ) . '

    ' . - '

    ' . __( 'If you would like to learn about using WooCommerce from an expert, consider following a WooCommerce course ran by one of our educational partners.', 'woocommerce' ) . '

    ' . + '

    ' . __( 'If you would like to learn about using WooCommerce from an expert, consider following a WooCommerce course offered by one of our educational partners.', 'woocommerce' ) . '

    ' . '

    ' . __( 'View Education Partners', 'woocommerce' ) . '

    ' ) ); From 0d6a3af1080be9f844f456bfaddfe358868da920 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 27 Jul 2016 10:22:02 +0100 Subject: [PATCH 155/298] Remove sorting function --- .../admin/settings-views-html-settings-tax.js | 33 ------------------- .../settings-views-html-settings-tax.min.js | 2 +- .../settings/views/html-settings-tax.php | 11 +++---- 3 files changed, 5 insertions(+), 41 deletions(-) diff --git a/assets/js/admin/settings-views-html-settings-tax.js b/assets/js/admin/settings-views-html-settings-tax.js index 9519cf155bc..495aac4e3c2 100644 --- a/assets/js/admin/settings-views-html-settings-tax.js +++ b/assets/js/admin/settings-views-html-settings-tax.js @@ -120,7 +120,6 @@ this.listenTo( this.model, 'change:rates', this.setUnloadConfirmation ); this.listenTo( this.model, 'saved:rates', this.clearUnloadConfirmation ); $tbody.on( 'change autocompletechange', ':input', { view: this }, this.updateModelOnChange ); - $tbody.on( 'sortupdate', { view: this }, this.updateModelOnSort ); $search_field.on( 'keyup search', { view: this }, this.onSearchField ); $pagination.on( 'click', 'a', { view: this }, this.onPageChange ); $pagination.on( 'change', 'input', { view: this }, this.onPageChange ); @@ -182,13 +181,6 @@ $pagination.empty(); view.page = 1; } - - // Disable sorting if there is a search term filtering the items. - if ( $search_field.val() ) { - $tbody.sortable( 'disable' ); - } else { - $tbody.sortable( 'enable' ); - } }, updateUrl: function() { if ( ! window.history.replaceState ) { @@ -364,31 +356,6 @@ model.setRateAttribute( id, attribute, val ); }, - updateModelOnSort: function( event ) { - var view = event.data.view, - model = view.model, - rates = _.indexBy( model.get( 'rates' ), 'tax_rate_id' ), - changes = {}; - - _.each( rates, function( rate ) { - var new_position = 0; - var old_position = parseInt( rate.tax_rate_order, 10 ); - - if ( $table.find( 'tr[data-id="' + rate.tax_rate_id + '"]').length ) { - new_position = parseInt( $table.find( 'tr[data-id="' + rate.tax_rate_id + '"]').index(), 10 ) + parseInt( ( view.page - 1 ) * view.per_page, 10 ); - } else { - new_position = old_position; - } - - if ( old_position !== new_position ) { - changes[ rate.tax_rate_id ] = _.extend( changes[ rate.tax_rate_id ] || {}, { tax_rate_order : new_position } ); - } - } ); - - if ( _.size( changes ) ) { - model.logChanges( changes ); - } - }, sanitizePage: function( page_num ) { page_num = parseInt( page_num, 10 ); if ( page_num < 1 ) { diff --git a/assets/js/admin/settings-views-html-settings-tax.min.js b/assets/js/admin/settings-views-html-settings-tax.min.js index 13bf60693e9..39172b9bd62 100644 --- a/assets/js/admin/settings-views-html-settings-tax.min.js +++ b/assets/js/admin/settings-views-html-settings-tax.min.js @@ -1 +1 @@ -!function(a,b,c,d){a(function(){String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")});var e=c.template("wc-tax-table-row"),f=c.template("wc-tax-table-row-empty"),g=c.template("wc-tax-table-pagination"),h=a(".wc_tax_rates"),i=a("#rates"),j=a('input[name="save"]'),k=a("#rates-pagination"),l=a("#rates-search .wc-tax-rates-search-field"),m=a(".submit .button-primary[type=submit]"),n=Backbone.Model.extend({changes:{},setRateAttribute:function(a,b,c){var d=_.indexBy(this.get("rates"),"tax_rate_id"),e={};d[a][b]!==c&&(e[a]={},e[a][b]=c,d[a][b]=c),this.logChanges(e)},logChanges:function(a){var b=this.changes||{};_.each(a,function(a,c){b[c]=_.extend(b[c]||{tax_rate_id:c},a)}),this.changes=b,this.trigger("change:rates")},getFilteredRates:function(){var a=this.get("rates"),b=l.val().toLowerCase();return b.length&&(a=_.filter(a,function(a){var c=_.toArray(a).join(" ").toLowerCase();return-1!==c.indexOf(b)})),a=_.sortBy(a,function(a){return parseInt(a.tax_rate_order,10)})},block:function(){a(".wc_tax_rates").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a(".wc_tax_rates").unblock()},save:function(){var a=this;a.block(),Backbone.ajax({method:"POST",dataType:"json",url:d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_tax_rates_save_changes",data:{current_class:b.current_class,wc_tax_nonce:b.wc_tax_nonce,changes:a.changes},success:function(b,c){"success"===c&&(p.set("rates",b.data.rates),p.trigger("change:rates"),p.changes={},p.trigger("saved:rates"),q.render()),a.unblock()}})}}),o=Backbone.View.extend({rowTemplate:e,per_page:b.limit,page:b.page,initialize:function(){var c=Math.ceil(_.toArray(this.model.get("rates")).length/this.per_page);this.qty_pages=0===c?1:c,this.page=this.sanitizePage(b.page),this.listenTo(this.model,"change:rates",this.setUnloadConfirmation),this.listenTo(this.model,"saved:rates",this.clearUnloadConfirmation),i.on("change autocompletechange",":input",{view:this},this.updateModelOnChange),i.on("sortupdate",{view:this},this.updateModelOnSort),l.on("keyup search",{view:this},this.onSearchField),k.on("click","a",{view:this},this.onPageChange),k.on("change","input",{view:this},this.onPageChange),a(window).on("beforeunload",{view:this},this.unloadConfirmation),m.on("click",{view:this},this.onSubmit),j.attr("disabled","disabled"),h.find(".insert").on("click",{view:this},this.onAddNewRow),h.find(".remove_tax_rates").on("click",{view:this},this.onDeleteRow),h.find(".export").on("click",{view:this},this.onExport)},render:function(){var c=this.model.getFilteredRates(),d=_.size(c),e=Math.ceil(d/this.per_page),h=0===d?0:this.per_page*(this.page-1),j=this.per_page*this.page,m=_.toArray(c).slice(h,j),n=this;this.$el.empty(),m.length?a.each(m,function(a,b){n.$el.append(n.rowTemplate(b))}):n.$el.append(f()),this.$el.find("td.country input").autocomplete({source:b.countries,minLength:2}),this.$el.find("td.state input").autocomplete({source:b.states,minLength:3}),this.$el.find("td.postcode input, td.city input").change(function(){a(this).attr("name",a(this).data("name"))}),e>1?k.html(g({qty_rates:d,current_page:this.page,qty_pages:e})):(k.empty(),n.page=1),l.val()?i.sortable("disable"):i.sortable("enable")},updateUrl:function(){if(window.history.replaceState){var a=b.base_url,c=l.val();1e}),g=_.map(f,function(a){return a.tax_rate_order++,l[a.tax_rate_id]=_.extend(l[a.tax_rate_id]||{},{tax_rate_order:a.tax_rate_order}),a})):(n.tax_rate_order=1+_.max(_.pluck(k,"tax_rate_order"),function(a){return parseInt(a,10)}),h.page=h.qty_pages),k[n.tax_rate_id]=n,l[n.tax_rate_id]=n,j.set("rates",k),j.logChanges(l),h.render()},onDeleteRow:function(c){var d,e,f=c.data.view,g=f.model,h=_.indexBy(g.get("rates"),"tax_rate_id"),j={};c.preventDefault(),(d=i.children(".current"))?(d.each(function(){e=a(this).data("id"),delete h[e],j[e]=_.extend(j[e]||{},{deleted:"deleted"})}),g.set("rates",h),g.logChanges(j),f.render()):window.alert(b.strings.no_rows_selected)},onSearchField:function(a){a.data.view.updateUrl(),a.data.view.render()},onPageChange:function(b){var c=a(b.currentTarget);b.preventDefault(),b.data.view.page=c.data("goto")?c.data("goto"):c.val(),b.data.view.render(),b.data.view.updateUrl()},onExport:function(c){var d="data:application/csv;charset=utf-8,"+b.strings.csv_data_cols.join(",")+"\n";return a.each(c.data.view.model.getFilteredRates(),function(a,c){var e="";e+=c.tax_rate_country+",",e+=c.tax_rate_state+",",e+=(c.postcode?c.postcode.join("; "):"")+",",e+=(c.city?c.city.join("; "):"")+",",e+=c.tax_rate+",",e+=c.tax_rate_name+",",e+=c.tax_rate_priority+",",e+=c.tax_rate_compound+",",e+=c.tax_rate_shipping+",",e+=b.current_class,d+=e+"\n"}),a(this).attr("href",encodeURI(d)),!0},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,j.removeAttr("disabled")},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,j.attr("disabled","disabled")},unloadConfirmation:function(a){if(a.data.view.needsUnloadConfirm)return a.returnValue=b.strings.unload_confirmation_msg,window.event.returnValue=b.strings.unload_confirmation_msg,b.strings.unload_confirmation_msg},updateModelOnChange:function(b){var c=b.data.view.model,d=a(b.target),e=d.closest("tr").data("id"),f=d.data("attribute"),g=d.val();"city"!==f&&"postcode"!==f||(g=g.split(";"),g=a.map(g,function(a){return a.trim()})),"tax_rate_compound"!==f&&"tax_rate_shipping"!==f||(g=d.is(":checked")?1:0),c.setRateAttribute(e,f,g)},updateModelOnSort:function(a){var b=a.data.view,c=b.model,d=_.indexBy(c.get("rates"),"tax_rate_id"),e={};_.each(d,function(a){var c=0,d=parseInt(a.tax_rate_order,10);c=h.find('tr[data-id="'+a.tax_rate_id+'"]').length?parseInt(h.find('tr[data-id="'+a.tax_rate_id+'"]').index(),10)+parseInt((b.page-1)*b.per_page,10):d,d!==c&&(e[a.tax_rate_id]=_.extend(e[a.tax_rate_id]||{},{tax_rate_order:c}))}),_.size(e)&&c.logChanges(e)},sanitizePage:function(a){return a=parseInt(a,10),a<1?a=1:a>this.qty_pages&&(a=this.qty_pages),a}}),p=new n({rates:b.rates}),q=new o({model:p,el:"#rates"});q.render()})}(jQuery,htmlSettingsTaxLocalizeScript,wp,ajaxurl); \ No newline at end of file +!function(a,b,c,d){a(function(){String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")});var e=c.template("wc-tax-table-row"),f=c.template("wc-tax-table-row-empty"),g=c.template("wc-tax-table-pagination"),h=a(".wc_tax_rates"),i=a("#rates"),j=a('input[name="save"]'),k=a("#rates-pagination"),l=a("#rates-search .wc-tax-rates-search-field"),m=a(".submit .button-primary[type=submit]"),n=Backbone.Model.extend({changes:{},setRateAttribute:function(a,b,c){var d=_.indexBy(this.get("rates"),"tax_rate_id"),e={};d[a][b]!==c&&(e[a]={},e[a][b]=c,d[a][b]=c),this.logChanges(e)},logChanges:function(a){var b=this.changes||{};_.each(a,function(a,c){b[c]=_.extend(b[c]||{tax_rate_id:c},a)}),this.changes=b,this.trigger("change:rates")},getFilteredRates:function(){var a=this.get("rates"),b=l.val().toLowerCase();return b.length&&(a=_.filter(a,function(a){var c=_.toArray(a).join(" ").toLowerCase();return-1!==c.indexOf(b)})),a=_.sortBy(a,function(a){return parseInt(a.tax_rate_order,10)})},block:function(){a(".wc_tax_rates").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a(".wc_tax_rates").unblock()},save:function(){var a=this;a.block(),Backbone.ajax({method:"POST",dataType:"json",url:d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_tax_rates_save_changes",data:{current_class:b.current_class,wc_tax_nonce:b.wc_tax_nonce,changes:a.changes},success:function(b,c){"success"===c&&(p.set("rates",b.data.rates),p.trigger("change:rates"),p.changes={},p.trigger("saved:rates"),q.render()),a.unblock()}})}}),o=Backbone.View.extend({rowTemplate:e,per_page:b.limit,page:b.page,initialize:function(){var c=Math.ceil(_.toArray(this.model.get("rates")).length/this.per_page);this.qty_pages=0===c?1:c,this.page=this.sanitizePage(b.page),this.listenTo(this.model,"change:rates",this.setUnloadConfirmation),this.listenTo(this.model,"saved:rates",this.clearUnloadConfirmation),i.on("change autocompletechange",":input",{view:this},this.updateModelOnChange),l.on("keyup search",{view:this},this.onSearchField),k.on("click","a",{view:this},this.onPageChange),k.on("change","input",{view:this},this.onPageChange),a(window).on("beforeunload",{view:this},this.unloadConfirmation),m.on("click",{view:this},this.onSubmit),j.attr("disabled","disabled"),h.find(".insert").on("click",{view:this},this.onAddNewRow),h.find(".remove_tax_rates").on("click",{view:this},this.onDeleteRow),h.find(".export").on("click",{view:this},this.onExport)},render:function(){var c=this.model.getFilteredRates(),d=_.size(c),e=Math.ceil(d/this.per_page),h=0===d?0:this.per_page*(this.page-1),i=this.per_page*this.page,j=_.toArray(c).slice(h,i),l=this;this.$el.empty(),j.length?a.each(j,function(a,b){l.$el.append(l.rowTemplate(b))}):l.$el.append(f()),this.$el.find("td.country input").autocomplete({source:b.countries,minLength:2}),this.$el.find("td.state input").autocomplete({source:b.states,minLength:3}),this.$el.find("td.postcode input, td.city input").change(function(){a(this).attr("name",a(this).data("name"))}),e>1?k.html(g({qty_rates:d,current_page:this.page,qty_pages:e})):(k.empty(),l.page=1)},updateUrl:function(){if(window.history.replaceState){var a=b.base_url,c=l.val();1e}),g=_.map(f,function(a){return a.tax_rate_order++,l[a.tax_rate_id]=_.extend(l[a.tax_rate_id]||{},{tax_rate_order:a.tax_rate_order}),a})):(n.tax_rate_order=1+_.max(_.pluck(k,"tax_rate_order"),function(a){return parseInt(a,10)}),h.page=h.qty_pages),k[n.tax_rate_id]=n,l[n.tax_rate_id]=n,j.set("rates",k),j.logChanges(l),h.render()},onDeleteRow:function(c){var d,e,f=c.data.view,g=f.model,h=_.indexBy(g.get("rates"),"tax_rate_id"),j={};c.preventDefault(),(d=i.children(".current"))?(d.each(function(){e=a(this).data("id"),delete h[e],j[e]=_.extend(j[e]||{},{deleted:"deleted"})}),g.set("rates",h),g.logChanges(j),f.render()):window.alert(b.strings.no_rows_selected)},onSearchField:function(a){a.data.view.updateUrl(),a.data.view.render()},onPageChange:function(b){var c=a(b.currentTarget);b.preventDefault(),b.data.view.page=c.data("goto")?c.data("goto"):c.val(),b.data.view.render(),b.data.view.updateUrl()},onExport:function(c){var d="data:application/csv;charset=utf-8,"+b.strings.csv_data_cols.join(",")+"\n";return a.each(c.data.view.model.getFilteredRates(),function(a,c){var e="";e+=c.tax_rate_country+",",e+=c.tax_rate_state+",",e+=(c.postcode?c.postcode.join("; "):"")+",",e+=(c.city?c.city.join("; "):"")+",",e+=c.tax_rate+",",e+=c.tax_rate_name+",",e+=c.tax_rate_priority+",",e+=c.tax_rate_compound+",",e+=c.tax_rate_shipping+",",e+=b.current_class,d+=e+"\n"}),a(this).attr("href",encodeURI(d)),!0},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,j.removeAttr("disabled")},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,j.attr("disabled","disabled")},unloadConfirmation:function(a){if(a.data.view.needsUnloadConfirm)return a.returnValue=b.strings.unload_confirmation_msg,window.event.returnValue=b.strings.unload_confirmation_msg,b.strings.unload_confirmation_msg},updateModelOnChange:function(b){var c=b.data.view.model,d=a(b.target),e=d.closest("tr").data("id"),f=d.data("attribute"),g=d.val();"city"!==f&&"postcode"!==f||(g=g.split(";"),g=a.map(g,function(a){return a.trim()})),"tax_rate_compound"!==f&&"tax_rate_shipping"!==f||(g=d.is(":checked")?1:0),c.setRateAttribute(e,f,g)},sanitizePage:function(a){return a=parseInt(a,10),a<1?a=1:a>this.qty_pages&&(a=this.qty_pages),a}}),p=new n({rates:b.rates}),q=new o({model:p,el:"#rates"});q.render()})}(jQuery,htmlSettingsTaxLocalizeScript,wp,ajaxurl); \ No newline at end of file diff --git a/includes/admin/settings/views/html-settings-tax.php b/includes/admin/settings/views/html-settings-tax.php index 98dc179287c..6bd29ac5351 100644 --- a/includes/admin/settings/views/html-settings-tax.php +++ b/includes/admin/settings/views/html-settings-tax.php @@ -12,10 +12,9 @@ if ( ! defined( 'ABSPATH' ) ) {

    - +
    - @@ -29,7 +28,7 @@ if ( ! defined( 'ABSPATH' ) ) { - - +
           
    + @@ -39,15 +38,13 @@ if ( ! defined( 'ABSPATH' ) ) {
    From 0a8f3565c3bbdda37cc300b7d871be66f2c9b8eb Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 27 Jul 2016 10:28:28 +0100 Subject: [PATCH 156/298] Tidy padding --- assets/css/admin.css | 2 +- assets/css/admin.scss | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/assets/css/admin.css b/assets/css/admin.css index 973dea007aa..dcb9d725769 100644 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -1 +1 @@ -@charset "UTF-8";.button.wc-reload:after,.woocommerce-help-tip:after{speak:none;text-transform:none;-webkit-font-smoothing:antialiased}@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg)}}@-moz-keyframes spin{100%{-moz-transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}.select2-container{margin:0;position:relative;display:block!important;zoom:1;vertical-align:middle}.select2-container,.select2-drop,.select2-search,.select2-search input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{display:block;padding:0 0 0 8px;overflow:hidden;position:relative;border:1px solid #ccc;white-space:nowrap;color:#444;text-decoration:none;border-radius:3px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;font-weight:400}html[dir=rtl] .select2-container .select2-choice{padding:0 8px 0 0}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#ccc;border-radius:0 0 4px 4px}.select2-container.select2-allowclear .select2-choice .select2-chosen{margin-right:42px}.select2-container .select2-choice>.select2-chosen{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:none;width:auto}html[dir=rtl] .select2-container .select2-choice>.select2-chosen{margin-left:26px;margin-right:0}.select2-container .select2-choice abbr{display:none;width:12px;height:12px;position:absolute;right:24px;top:5px;font-size:1px;text-decoration:none;border:0;background:url(../images/select2.png) right top no-repeat;cursor:pointer;outline:0}.select2-container.select2-allowclear .select2-choice abbr{display:inline-block}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop-mask{border:0;margin:0;padding:0;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:9998;background-color:#fff;filter:alpha(opacity=0)}.select2-drop{width:100%;margin-top:-1px;position:absolute;top:100%;background:#fff;color:#000;border:1px solid #ccc;border-top:0;border-radius:0 0 3px 3px}.select2-drop.select2-drop-above{margin-top:1px;border-top:1px solid #ccc;border-bottom:0;border-radius:3px 3px 0 0}.select2-drop-active{border:1px solid #666;border-top:none}.select2-drop.select2-drop-above.select2-drop-active{border-top:1px solid #666}.select2-drop-auto-width{border-top:1px solid #ccc;width:auto}.select2-drop-auto-width .select2-search{padding-top:4px}.select2-container .select2-choice .select2-arrow{display:inline-block;width:18px;height:100%;position:absolute;right:0;top:0;border-radius:0 3px 3px 0;background-clip:padding-box}html[dir=rtl] .select2-container .select2-choice .select2-arrow{left:0;right:auto;border-radius:3px 0 0 3px}.select2-container .select2-choice .select2-arrow b{display:block;width:100%;height:100%;position:relative}.select2-container .select2-choice .select2-arrow b:after{position:absolute;display:block;content:"";top:50%;left:50%;border:4px solid transparent;border-top-color:#666;margin-left:-7px;margin-top:-2px}.select2-search{display:inline-block;width:100%;margin:0;padding-left:4px;padding-right:4px;position:relative;z-index:10000;white-space:nowrap;padding-bottom:4px}.select2-search input{width:100%;height:auto!important;padding:4px 20px 4px 5px!important;margin:0;outline:0;font-family:sans-serif;font-size:1em;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none;background:url(../images/select2.png) 100% -22px no-repeat #fff}html[dir=rtl] .select2-search input{padding:4px 5px 4px 20px;background:url(../images/select2.png) -37px -22px no-repeat #fff}.select2-drop.select2-drop-above .select2-search input{margin-top:4px}.select2-search input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff}.select2-container-active .select2-choice,.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-dropdown-open .select2-choice{border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-dropdown-open .select2-choice .select2-arrow b:after{border-top-color:transparent;border-bottom-color:#666;margin-top:-6px}.select2-dropdown-open.select2-drop-above .select2-choice,.select2-dropdown-open.select2-drop-above .select2-choices{border:1px solid #666;border-top-color:transparent}.select2-dropdown-open .select2-choice .select2-arrow{background:0 0;border-left:none;filter:none}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow{border-right:none}.select2-dropdown-open .select2-choice .select2-arrow b{background-position:-18px 1px}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow b{background-position:-16px 1px}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.select2-results{max-height:200px;padding:4px;margin:0;position:relative;overflow-x:hidden;overflow-y:auto;-webkit-tap-highlight-color:transparent;background:#fafafa}html[dir=rtl] .select2-results{padding:0 4px 0 0;margin:4px 0 4px 4px}.select2-results ul.select2-result-sub{margin:0;padding-left:0}.select2-results li{list-style:none;display:list-item;background-image:none;margin:3px 0}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:700}.select2-results .select2-result-label{padding:5px 7px;margin:0;cursor:pointer;min-height:1em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select2-results-dept-1 .select2-result-label{padding-left:20px}.select2-results-dept-2 .select2-result-label{padding-left:40px}.select2-results-dept-3 .select2-result-label{padding-left:60px}.select2-results-dept-4 .select2-result-label{padding-left:80px}.select2-results-dept-5 .select2-result-label{padding-left:100px}.select2-results-dept-6 .select2-result-label{padding-left:110px}.select2-results-dept-7 .select2-result-label{padding-left:120px}.select2-results .select2-highlighted{background:#f1f1f1;color:#000;border-radius:3px}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:0 0}.select2-results .select2-highlighted ul{background:#fff;color:#000}.select2-results .select2-ajax-error,.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item;padding-left:5px}.select2-results .select2-disabled.select2-highlighted{color:#666;background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-disabled{background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-selected{display:none}.select2-more-results.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #f4f4f4}.select2-results .select2-ajax-error{background:rgba(255,50,50,.2)}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice .select2-arrow{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container.select2-container-disabled .select2-choice abbr{display:none}.select2-container-multi .select2-choices{height:auto!important;height:1%;margin:0;padding:0 5px 0 0;position:relative;border:1px solid #ccc;cursor:text;overflow:hidden;background-color:#fff;min-height:26px}html[dir=rtl] .select2-container-multi .select2-choices{padding:0 0 0 5px}.select2-locked{padding:3px 5px!important}.select2-container-multi.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-container-multi .select2-choices li{float:left;list-style:none}html[dir=rtl] .select2-container-multi .select2-choices li{float:right}.select2-container-multi .select2-choices .select2-search-field{margin:0;padding:0;white-space:nowrap}.select2-container-multi .select2-choices .select2-search-field:first-child{width:100%}.select2-container-multi .select2-choices .select2-search-field input{margin:1px 0;outline:0;border:0;-webkit-box-shadow:none;box-shadow:none;background:0 0!important}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff!important}.select2-default{color:#999!important}.select2-container-multi .select2-choices .select2-search-choice{padding:5px 8px 5px 24px;margin:3px 0 3px 5px;position:relative;line-height:15px;color:#333;cursor:default;border-radius:2px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#e4e4e4}html[dir=rtl] .select2-container-multi .select2-choices .select2-search-choice{margin:3px 5px 3px 0;padding:5px 24px 5px 8px}.select2-container-multi .select2-choices .select2-search-choice .select2-chosen{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;width:12px;height:13px;position:absolute;right:7px;top:6px;font-size:1px;outline:0;background:url(../images/select2.png) right top no-repeat}html[dir=rtl] .select2-search-choice-close{right:auto;left:7px}.select2-container-multi .select2-search-choice-close{left:7px}html[dir=rtl] .select2-container-multi .select2-search-choice-close{left:auto;right:7px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover,.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{padding:3px 5px;border:1px solid #ddd;background-image:none;background-color:#f4f4f4}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none;background:0 0}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-match{text-decoration:underline}.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.select2-display-none{display:none}.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:2dppx){.select2-search input{background-image:url(../images/select2x2.png)!important;background-repeat:no-repeat!important;background-size:60px 40px!important;background-position:100% -21px!important}}@font-face{font-family:star;src:url(../fonts/star.eot);src:url(../fonts/star.eot?#iefix) format("embedded-opentype"),url(../fonts/star.woff) format("woff"),url(../fonts/star.ttf) format("truetype"),url(../fonts/star.svg#star) format("svg");font-weight:400;font-style:normal}@font-face{font-family:WooCommerce;src:url(../fonts/WooCommerce.eot);src:url(../fonts/WooCommerce.eot?#iefix) format("embedded-opentype"),url(../fonts/WooCommerce.woff) format("woff"),url(../fonts/WooCommerce.ttf) format("truetype"),url(../fonts/WooCommerce.svg#WooCommerce) format("svg");font-weight:400;font-style:normal}.blockUI.blockOverlay:before{height:1em;width:1em;position:absolute;top:50%;left:50%;margin-left:-.5em;margin-top:-.5em;display:block;content:"";-webkit-animation:spin 1s ease-in-out infinite;-moz-animation:spin 1s ease-in-out infinite;animation:spin 1s ease-in-out infinite;background:url(../images/icons/loader.svg) center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75)}.wc_addons_wrap .products{overflow:hidden}.wc_addons_wrap .products li{float:left;margin:0 1em 1em 0!important;padding:0;vertical-align:top;width:300px}.wc_addons_wrap .products li a{text-decoration:none;color:inherit;border:1px solid #ddd;display:block;min-height:220px;overflow:hidden;background:#f5f5f5;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1)}.wc_addons_wrap .products li a img{max-width:258px;max-height:24px;padding:17px 20px;display:block;margin:0;background:#fff;border-right:260px solid #fff}.wc_addons_wrap .products li a .price,.wc_addons_wrap .products li a img.extension-thumb+h3{display:none}.wc_addons_wrap .products li a h2,.wc_addons_wrap .products li a h3{margin:0!important;padding:20px!important;background:#fff}.wc_addons_wrap .products li a p{padding:20px!important;margin:0!important;border-top:1px solid #f1f1f1}.wc_addons_wrap .products li a:focus,.wc_addons_wrap .products li a:hover{background-color:#fff}.wc_addons_wrap .storefront{background:url(../images/storefront-bg.jpg) bottom right #f6f6f6;border:1px solid #ddd;padding:20px;overflow:hidden;zoom:1}.wc_addons_wrap .storefront img{width:278px;height:auto;float:left;margin:0 20px 0 0;box-shadow:0 1px 6px rgba(0,0,0,.1)}.wc_addons_wrap .storefront p{max-width:750px}.woocommerce-BlankState a.button-primary,.woocommerce-BlankState button.button-primary,.woocommerce-message a.button-primary,.woocommerce-message button.button-primary{background:#bb77ae;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;color:#fff;text-shadow:0 -1px 1px #A36597,1px 0 1px #A36597,0 1px 1px #A36597,-1px 0 1px #A36597}.woocommerce-BlankState a.button-primary:active,.woocommerce-BlankState a.button-primary:focus,.woocommerce-BlankState a.button-primary:hover,.woocommerce-BlankState button.button-primary:active,.woocommerce-BlankState button.button-primary:focus,.woocommerce-BlankState button.button-primary:hover,.woocommerce-message a.button-primary:active,.woocommerce-message a.button-primary:focus,.woocommerce-message a.button-primary:hover,.woocommerce-message button.button-primary:active,.woocommerce-message button.button-primary:focus,.woocommerce-message button.button-primary:hover{background:#A36597;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597}.woocommerce-message{position:relative;border-left-color:#cc99c2!important;overflow:hidden}.woocommerce-message a.docs,.woocommerce-message a.skip{text-decoration:none!important}.woocommerce-message a.woocommerce-message-close{position:absolute;top:10px;right:10px;padding:10px 15px 10px 21px;font-size:13px;line-height:1.23076923;text-decoration:none}.woocommerce-message a.woocommerce-message-close:before{position:absolute;top:8px;left:0;-webkit-transition:all .1s ease-in-out;transition:all .1s ease-in-out}.woocommerce-message .twitter-share-button{margin-top:-3px;margin-left:3px;vertical-align:middle}#variable_product_options #message,#variable_product_options .notice{margin:10px}.clear{clear:both}#woocommerce-fields-bulk.inline-edit-col label,#woocommerce-fields.inline-edit-col{clear:left}.wrap.woocommerce div.error,.wrap.woocommerce div.updated{margin-top:10px}mark.amount{background:0 0;color:inherit}.postbox,.woocommerce{input:invalid;input-border:1px solid #cc010b;input-background:#ffebe8}.simplify-commerce-banner{overflow:hidden}.simplify-commerce-banner img{float:right;padding:15px 0;margin-left:1em;width:200px}.woocommerce-help-tip{color:#666;display:inline-block;font-size:1.1em;font-style:normal;height:16px;line-height:16px;position:relative;vertical-align:middle;width:16px}.woocommerce-help-tip:after{font-family:Dashicons;font-weight:400;font-variant:normal;line-height:1;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";cursor:help}h2 .woocommerce-help-tip{margin-top:-5px;margin-left:.25em}table.wc_status_table{margin-bottom:1em}table.wc_status_table h2{font-size:14px;margin:0}table.wc_status_table tr:nth-child(2n) td,table.wc_status_table tr:nth-child(2n) th{background:#fcfcfc}table.wc_status_table th{font-weight:700;padding:9px}table.wc_status_table td:first-child{width:33%}table.wc_status_table td.help{width:1em}table.wc_status_table td{padding:9px;font-size:1.1em}table.wc_status_table td mark{background:0 0}table.wc_status_table td mark.yes{color:#7ad03a}table.wc_status_table td mark.no{color:#999}table.wc_status_table td mark.error{color:#a00}table.wc_status_table td ul{margin:0}table.wc_status_table .help_tip{cursor:help}#debug-report{display:none;margin:10px 0;padding:0;position:relative}#debug-report textarea{font-family:monospace;width:100%;margin:0;height:300px;padding:20px;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;resize:none;font-size:12px;line-height:20px;outline:0}#log-viewer-select{padding:10px 0 8px;line-height:180%}#log-viewer textarea{width:100%;resize:vertical}.inline-edit-product.quick-edit-row .inline-edit-col-center,.inline-edit-product.quick-edit-row .inline-edit-col-right{float:right!important}#woocommerce-fields.inline-edit-col label.featured,#woocommerce-fields.inline-edit-col label.manage_stock{margin-left:10px}#woocommerce-fields.inline-edit-col .dimensions div{display:block;margin:.2em 0}#woocommerce-fields.inline-edit-col .dimensions div span.title{display:block;float:left;width:5em}#woocommerce-fields.inline-edit-col .dimensions div span.input-text-wrap{display:block;margin-left:5em}#woocommerce-fields.inline-edit-col .text{box-sizing:border-box;width:99%;float:left;margin:1px 1% 1px 1px}#woocommerce-fields.inline-edit-col .height,#woocommerce-fields.inline-edit-col .length,#woocommerce-fields.inline-edit-col .width{width:32.33%}#woocommerce-fields.inline-edit-col .height{margin-right:0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group label{clear:none;width:49%;margin:.2em 0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group.dimensions label{width:75%;max-width:75%}#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .regular_price,#woocommerce-fields-bulk.inline-edit-col .sale_price,#woocommerce-fields-bulk.inline-edit-col .stock,#woocommerce-fields-bulk.inline-edit-col .weight{box-sizing:border-box;width:100%;margin-left:4.4em}#woocommerce-fields-bulk.inline-edit-col .height,#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .width{box-sizing:border-box;width:25%}.column-coupon_code{line-height:2.25em}.column-coupon_code,ul.wc_coupon_list{margin:0;overflow:hidden;zoom:1;clear:both}ul.wc_coupon_list li{margin:0}ul.wc_coupon_list li.code{display:inline-block}ul.wc_coupon_list li.code:after{content:", "}ul.wc_coupon_list li.code:last-of-type:after{display:none}ul.wc_coupon_list li.code .tips{cursor:pointer}ul.wc_coupon_list_block{margin:0;padding-bottom:2px}ul.wc_coupon_list_block li{border-top:1px solid #fff;border-bottom:1px solid #ccc;line-height:2.5em;margin:0;padding:.5em 0}ul.wc_coupon_list_block li:first-child{border-top:0;padding-top:0}ul.wc_coupon_list_block li:last-child{border-bottom:0;padding-bottom:0}.button.wc-reload{text-indent:-9999px;position:relative;padding:0;height:28px;width:28px!important;display:inline-block}.button.wc-reload:after{font-family:Dashicons;font-weight:400;font-variant:normal;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:28px}#order_data h2,#order_data p.order_number{font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif;font-weight:400}.tablenav .actions{overflow:visible}.tablenav .select2-container{float:left;max-width:200px;font-size:14px;vertical-align:middle;margin:1px 6px 1px 1px}#woocommerce-order-data .handlediv,#woocommerce-order-data .hndle{display:none}#woocommerce-order-data .inside{display:block!important}#order_data{padding:23px 24px 12px}#order_data h2{margin:0;font-size:21px;line-height:1.2;text-shadow:1px 1px 1px #fff;padding:0}#order_data h3{font-size:14px}#order_data h3,#order_data h4{color:#333;margin:1.33em 0 0}#order_data p{color:#777}#order_data p.order_number{margin:0;line-height:1.6em;font-size:16px}#order_data .order_data_column_container{clear:both}#order_data .order_data_column{width:32%;padding:0 2% 0 0;float:left}#order_data .order_data_column:last-child{padding-right:0}#order_data .order_data_column p{padding:0!important}#order_data .order_data_column .address strong{display:block}#order_data .order_data_column .form-field{float:left;width:48%;padding:0;margin:9px 0 0}#order_data .order_data_column .form-field label{display:block;padding:0 0 3px}#order_data .order_data_column .form-field input,#order_data .order_data_column .form-field select,#order_data .order_data_column .form-field textarea{width:100%}#order_data .order_data_column .form-field .select2-container{width:100%!important}#order_data .order_data_column .form-field .date-picker{width:50%}#order_data .order_data_column .form-field .hour,#order_data .order_data_column .form-field .minute{width:3em}#order_data .order_data_column .form-field small{display:block;margin:5px 0 0;color:#999}#order_data .order_data_column .form-field.last{float:right}#order_data .order_data_column .form-field-wide{width:100%;clear:both}#order_data .order_data_column .form-field-wide .wc-customer-search,#order_data .order_data_column .form-field-wide .wc-enhanced-select,#order_data .order_data_column .form-field-wide input,#order_data .order_data_column .form-field-wide select,#order_data .order_data_column .form-field-wide textarea{width:100%}#order_data .order_data_column p.none_set{color:#999}#order_data .order_data_column ._billing_address_1_field,#order_data .order_data_column ._billing_city_field,#order_data .order_data_column ._billing_country_field,#order_data .order_data_column ._billing_email_field,#order_data .order_data_column ._billing_first_name_field,#order_data .order_data_column ._shipping_address_1_field,#order_data .order_data_column ._shipping_city_field,#order_data .order_data_column ._shipping_country_field,#order_data .order_data_column ._shipping_first_name_field{float:left}#order_data .order_data_column ._billing_address_2_field,#order_data .order_data_column ._billing_last_name_field,#order_data .order_data_column ._billing_phone_field,#order_data .order_data_column ._billing_postcode_field,#order_data .order_data_column ._billing_state_field,#order_data .order_data_column ._shipping_address_2_field,#order_data .order_data_column ._shipping_last_name_field,#order_data .order_data_column ._shipping_postcode_field,#order_data .order_data_column ._shipping_state_field,#order_data .order_data_column .wc-customer-user label a,#order_data .order_data_column .wc-order-status label a{float:right}#order_data .order_data_column ._billing_company_field,#order_data .order_data_column ._shipping_company_field,#order_data .order_data_column ._transaction_id_field{clear:both;width:100%}#order_data .order_data_column ._billing_email_field{clear:left}#order_data .order_data_column div.edit_address{display:none;zoom:1;padding-right:1px}#order_data .order_data_column .billing-same-as-shipping,#order_data .order_data_column .load_customer_billing,#order_data .order_data_column .load_customer_shipping,#order_data .order_data_column a.edit_address{width:14px;height:0;padding:14px 0 0;margin:0 0 0 6px;overflow:hidden;position:relative;color:#999;border:0;float:right}#order_data .order_data_column .billing-same-as-shipping:focus,#order_data .order_data_column .billing-same-as-shipping:hover,#order_data .order_data_column .load_customer_billing:focus,#order_data .order_data_column .load_customer_billing:hover,#order_data .order_data_column .load_customer_shipping:focus,#order_data .order_data_column .load_customer_shipping:hover,#order_data .order_data_column a.edit_address:focus,#order_data .order_data_column a.edit_address:hover{color:#000}#order_data .order_data_column .billing-same-as-shipping:after,#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after,#order_data .order_data_column a.edit_address: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}#order_data .order_data_column .billing-same-as-shipping:after{content:"\e008"}#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after{content:"\e03a"}#order_data .order_data_column a.edit_address:after{font-family:Dashicons;content:"\f464"}.order_actions{margin:0;overflow:hidden;zoom:1}.order_actions li{border-top:1px solid #fff;border-bottom:1px solid #ddd;padding:6px 0;margin:0;line-height:1.6em;float:left;width:50%;text-align:center}.order_actions li a{float:none;text-align:center;text-decoration:underline}.order_actions li.wide{width:auto;float:none;clear:both;padding:6px;text-align:left;overflow:hidden}.order_actions li #delete-action{line-height:25px;vertical-align:middle;text-align:left;float:left}.order_actions li .save_order{float:right}.order_actions li#actions{overflow:hidden}.order_actions li#actions .button{width:24px;box-sizing:border-box;float:right}.order_actions li#actions select{width:225px;box-sizing:border-box;float:left}#woocommerce-order-items .inside{margin:0;padding:0;background:#fefefe}#woocommerce-order-items .wc-order-data-row{border-bottom:1px solid #DFDFDF;padding:1.5em 2em;background:#f8f8f8;line-height:2em;text-align:right}#woocommerce-order-items .wc-order-data-row:after,#woocommerce-order-items .wc-order-data-row:before{content:" ";display:table}#woocommerce-order-items .wc-order-data-row:after{clear:both}#woocommerce-order-items .wc-order-data-row p{margin:0;line-height:2em}#woocommerce-order-items .wc-order-data-row .wc-used-coupons{text-align:left}#woocommerce-order-items .wc-order-data-row .wc-used-coupons .tips{display:inline-block}#woocommerce-order-items .wc-order-add-item{background:#fff;vertical-align:top;border-top:none}#woocommerce-order-items .wc-order-add-item .add_item_id,#woocommerce-order-items .wc-order-add-item .select2-container{vertical-align:top}#woocommerce-order-items .wc-order-add-item .add_item_id .search-field input,#woocommerce-order-items .wc-order-add-item .select2-container .search-field input{min-width:100px}#woocommerce-order-items .wc-order-add-item .select2-container{width:400px!important;text-align:left}#woocommerce-order-items .wc-order-add-item .calculate-action,#woocommerce-order-items .wc-order-add-item .cancel-action,#woocommerce-order-items .wc-order-add-item .save-action{float:left;margin-right:2px}#woocommerce-order-items .wc-used-coupons{float:left;width:50%}#woocommerce-order-items .wc-order-totals{float:right;width:50%;margin:0;padding:0;text-align:right}#woocommerce-order-items .wc-order-totals .amount{font-weight:700}#woocommerce-order-items .wc-order-totals .label{vertical-align:top}#woocommerce-order-items .wc-order-totals .total{font-size:1em!important;width:10em;margin:0 0 0 .5em;box-sizing:border-box}#woocommerce-order-items .wc-order-totals .total input[type=text]{width:96%;float:right}#woocommerce-order-items .wc-order-totals .refunded-total{color:#a00}#woocommerce-order-items .refund-actions{margin-top:5px;padding-top:12px;border-top:1px solid #DFDFDF}#woocommerce-order-items .refund-actions .button{float:right;margin-left:4px}#woocommerce-order-items .refund-actions .cancel-action,#woocommerce-order-items .wc-order-item-bulk-edit .cancel-action{float:left;margin-left:0}#woocommerce-order-items .add_meta{margin-left:0!important}#woocommerce-order-items h3 small{color:#999}#woocommerce-order-items .amount{white-space:nowrap}#woocommerce-order-items .add-items .description{margin-right:10px}#woocommerce-order-items .add-items .button{float:left;margin-right:.25em}#woocommerce-order-items .add-items .button-primary{float:none;margin-right:0}#woocommerce-order-items .inside{display:block!important}#woocommerce-order-items .handlediv,#woocommerce-order-items .hndle{display:none}#woocommerce-order-items .woocommerce_order_items_wrapper{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items{width:100%;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th{text-align:left;padding:1em;font-weight:400;color:#999;background:#f8f8f8;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th.sortable{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th .wc-arrow{float:right;position:relative;margin-right:-1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td{padding:1.5em 1em 1em;text-align:left;line-height:1.5em;vertical-align:top;border-bottom:1px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td select{width:50%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{font-size:14px;padding:4px;color:#555}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr td{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected{background:#F5EBF3}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected td{border-color:#E6CCE1;opacity:.8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:last-child td{border-bottom:1px solid #dfdfdf}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:first-child td{border-top:8px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody#order_line_items tr:first-child td{border-top:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb{text-align:left;width:38px;padding-bottom:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail{width:38px;height:38px;border:2px solid #e8e8e8;background:#f8f8f8;color:#ccc;position:relative;font-size:21px;display:block;text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;height:100%;text-align:center;content:"";width:38px;line-height:38px;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail img{width:100%;height:100%;margin:0;padding:0;position:relative}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-sku,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-variation{display:block;margin-top:.5em;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item{min-width:200px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .center,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .variation-id{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class{text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label{white-space:nowrap;color:#999;font-size:.833em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label input{display:inline}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class input{width:70px;vertical-align:middle;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class select{width:85px;height:26px;vertical-align:middle;font-size:1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input{display:inline-block;background:#fff;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);margin:1px 0;min-width:80px;overflow:hidden;line-height:1em;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input{width:100%;box-sizing:border-box}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input label{font-size:.75em;padding:4px 6px 0;color:#555;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input{width:100%;box-sizing:border-box;border:0;box-shadow:none;margin:0;padding:0 6px 4px;color:#555;background:0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input::-webkit-input-placeholder{color:#ddd}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child{border-bottom:1px dashed #ddd;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child label{color:#ccc}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .view{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .edit{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes label{display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount{display:block;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{margin-right:.25em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input{text-align:center;width:50px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items span.subtotal{opacity:.5}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.tax_class,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.tax_class{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .calculated{border-color:#ae8ca2;border-style:dotted}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{margin:.5em 0 0;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{color:#ccc;top:0;left:0;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-align:center;font-family:WooCommerce}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr th{border:0;padding:0 4px .5em 0;line-height:1.5em;width:20%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td{padding:0 4px .5em 0;border:0;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input{width:100%;margin:0;position:relative;border-bottom:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .refund_by,ul.order_notes li p.meta .exact-date{border-bottom:1px dotted #999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td textarea{width:100%;height:4em;margin:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input:focus+textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input:focus+textarea{border-top-color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p{margin:0 0 .5em;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p:last-child{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method_name{width:100%;margin:0 0 .5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;float:right;font-size:14px;visibility:hidden;margin:3px -18px 0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:hover:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:hover:before{color:#a00}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax:hover .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax:hover .delete-order-tax{visibility:visible}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded{display:block;color:#a00;white-space:nowrap;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;width:100%;height:100%;text-align:center;content:"";position:relative;top:auto;left:auto;margin:-1px 4px 0 0;vertical-align:middle;line-height:1em}#woocommerce-order-items .wc-order-edit-line-item{padding-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions{width:44px;text-align:right;padding-left:0;vertical-align:middle}#woocommerce-order-items .wc-order-edit-line-item-actions a{color:#ccc;display:inline-block;cursor:pointer;padding:0 0 .5em;margin:0 0 0 12px;vertical-align:middle;text-decoration:none;line-height:16px;width:16px;overflow:hidden}#woocommerce-order-items .wc-order-edit-line-item-actions a:before{margin:0;padding:0;font-size:16px;width:16px;height:16px}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before,#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{font-family:Dashicons;-webkit-font-smoothing:antialiased;text-indent:0;top:0;left:0;width:100%;height:100%;margin:0;text-align:center;position:relative;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1}#woocommerce-order-items .wc-order-edit-line-item-actions a:hover:before{color:#999}#woocommerce-order-items .wc-order-edit-line-item-actions a:first-child{margin-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:hover:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:hover:before{color:#a00}#woocommerce-order-items tbody tr .wc-order-edit-line-item-actions{visibility:hidden}#woocommerce-order-items tbody tr:hover .wc-order-edit-line-item-actions{visibility:visible}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions{width:1.5em;visibility:visible!important}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions a{padding:0}#woocommerce-order-downloads .buttons{float:left;padding:0;margin:0;vertical-align:top}#woocommerce-order-downloads .buttons .add_item_id,#woocommerce-order-downloads .buttons .select2-container{width:400px!important;margin-right:9px;vertical-align:top;float:left}#woocommerce-order-downloads .buttons button{margin:2px 0 0}#woocommerce-order-downloads h3 small{color:#999}#poststuff #woocommerce-order-actions .inside{margin:0;padding:0}#poststuff #woocommerce-order-actions .inside ul.order_actions li{padding:6px 10px;box-sizing:border-box}#poststuff #woocommerce-order-actions .inside ul.order_actions li:last-child{border-bottom:0}#poststuff #woocommerce-order-notes .inside{margin:0;padding:0}#poststuff #woocommerce-order-notes .inside ul.order_notes li{padding:0 10px}#woocommerce_customers p.search-box{margin:6px 0 4px;float:left}#woocommerce_customers .tablenav{float:right;clear:none}.widefat.customers td{vertical-align:middle;padding:4px 7px}.widefat .column-order_title{width:15%}.widefat .column-order_title time{display:block;color:#999;margin:3px 0}.widefat .column-orders,.widefat .column-paying,.widefat .column-spent{text-align:center;width:8%}.widefat .column-last_order{width:11%}.widefat .column-order_actions,.widefat .column-user_actions,.widefat .column-wc_actions{width:110px}.widefat .column-order_actions a.button,.widefat .column-user_actions a.button,.widefat .column-wc_actions a.button{float:left;margin:0 4px 2px 0;cursor:pointer;padding:3px 4px;height:auto}.widefat .column-order_actions a.button img,.widefat .column-user_actions a.button img,.widefat .column-wc_actions a.button img{display:block;width:12px;height:auto}.widefat small.meta{display:block;color:#999;font-size:inherit;margin:3px 0}.widefat .column-order_date,.widefat .column-order_total{width:9%}.widefat .column-order_status{width:45px;text-align:center}.widefat .column-order_status mark{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;background:0 0;font-size:1.4em;margin:0 auto}.widefat .column-order_status mark.cancelled:after,.widefat .column-order_status mark.completed:after,.widefat .column-order_status mark.failed:after,.widefat .column-order_status mark.on-hold:after,.widefat .column-order_status mark.pending:after,.widefat .column-order_status mark.processing:after,.widefat .column-order_status mark.refunded:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.column-customer_message .note-on:after,.column-order_notes .note-on:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;left:0;text-align:center;line-height:16px;font-family:WooCommerce}.widefat .column-order_status mark.pending:after{content:"\e012";color:#ffba00}.widefat .column-order_status mark.completed:after{content:"\e015";color:#2ea2cc}.widefat .column-order_status mark.on-hold:after{content:"\e033";color:#999}.widefat .column-order_status mark.failed:after{content:"\e016";color:#d0c21f}.widefat .column-order_status mark.cancelled:after{content:"\e013";color:#a00}.widefat .column-order_status mark.processing:after{content:"\e011";color:#73a724}.widefat .column-order_status mark.refunded:after{content:"\e014";color:#999}.widefat td.column-order_status{padding-top:9px}.column-customer_message .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-customer_message .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.column-order_notes .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-order_notes .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.order_actions .complete,.order_actions .processing,.order_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.order_actions .processing:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.order_actions .complete:after,.order_actions .view:after{font-family:Dashicons;text-indent:0;position:absolute;width:100%;height:100%;left:0;line-height:1.85;margin:0;text-align:center;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;font-weight:400}.order_actions .complete:after{content:""}.order_actions .view:after{content:""}.user_actions .edit,.user_actions .link,.user_actions .refresh,.user_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.user_actions .edit:after,.user_actions .link:after,.user_actions .refresh:after,.user_actions .view:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.user_actions .edit:after{font-family:Dashicons;content:"\f464"}.user_actions .link:after{content:"\e00d"}.user_actions .view:after{content:"\e010"}.user_actions .refresh:after{content:"\e031"}.attributes-table td,.attributes-table th{width:15%;vertical-align:top}.attributes-table .attribute-terms{width:32%}.attributes-table .attribute-actions{width:2em}.attributes-table .attribute-actions .configure-terms{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.attributes-table .attribute-actions .configure-terms:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}ul.order_notes{padding:2px 0 0}ul.order_notes li .note_content{padding:10px;background:#efefef;position:relative}ul.order_notes li .note_content p{margin:0;padding:0;word-wrap:break-word}ul.order_notes li p.meta{padding:10px;color:#999;margin:0;font-size:11px}ul.order_notes li a.delete_note{color:#a00}table.wp-list-table .row-actions,table.wp-list-table span.na{color:#999}ul.order_notes li .note_content:after{content:"";display:block;position:absolute;bottom:-10px;left:20px;width:0;height:0;border-width:10px 10px 0 0;border-style:solid;border-color:#efefef transparent}ul.order_notes li.customer-note .note_content{background:#A7CEDC}ul.order_notes li.customer-note .note_content:after{border-color:#A7CEDC transparent}ul.order_notes li.system-note .note_content{background:#d7cad2}ul.order_notes li.system-note .note_content:after{border-color:#d7cad2 transparent}.add_note{border-top:1px solid #ddd;padding:10px 10px 0}.add_note h4{margin-top:5px!important}.add_note #add_order_note{width:100%;height:50px}table.wp-list-table .column-thumb{width:52px;text-align:center;white-space:nowrap}table.wp-list-table .column-name{width:22%}table.wp-list-table .column-product_cat,table.wp-list-table .column-product_tag{width:11%!important}table.wp-list-table .column-featured,table.wp-list-table .column-product_type{width:48px;text-align:left!important}table.wp-list-table .column-customer_message,table.wp-list-table .column-order_notes{width:48px;text-align:center}table.wp-list-table .column-customer_message img,table.wp-list-table .column-order_notes img{margin:0 auto;padding-top:0!important}table.wp-list-table .manage-column.column-featured img,table.wp-list-table .manage-column.column-product_type img{padding-left:2px}table.wp-list-table .column-price .woocommerce-price-suffix{display:none}table.wp-list-table img{margin:1px 2px}table.wp-list-table td.column-thumb img{margin:0;width:auto;height:auto;max-width:40px;max-height:40px;vertical-align:middle}table.wp-list-table .column-is_in_stock{text-align:left!important}table.wp-list-table span.wc-featured,table.wp-list-table span.wc-image,table.wp-list-table span.wc-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table span.wc-featured:before,table.wp-list-table span.wc-image:before,table.wp-list-table span.wc-type:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:""}table.wp-list-table span.wc-featured{margin:0;cursor:pointer}table.wp-list-table span.wc-featured:before{content:"\f155"}table.wp-list-table span.wc-featured.not-featured:before{content:"\f154"}table.wp-list-table td.column-featured span.wc-featured{font-size:1.6em}table.wp-list-table span.wc-type{margin:0}table.wp-list-table span.wc-type:before{font-family:WooCommerce;content:"\e006"}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after,table.wp-list-table span.product-type:before{font-family:WooCommerce;text-align:center;line-height:1;top:0;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;left:0}table.wp-list-table span.product-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.6em}table.wp-list-table span.product-type:before{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}table.wp-list-table span.product-type.grouped:before{content:"\e002"}table.wp-list-table span.product-type.external:before{content:"\e034"}table.wp-list-table span.product-type.variable:before{content:"\e003"}table.wp-list-table span.product-type.downloadable:before{content:"\e001"}table.wp-list-table span.product-type.virtual:before{content:"\e000"}table.wp-list-table mark.instock{font-weight:700;color:#7ad03a;background:0 0;line-height:1}table.wp-list-table mark.outofstock{font-weight:700;color:#a44;background:0 0;line-height:1}table.wp-list-table .notes_head,table.wp-list-table .order-notes_head,table.wp-list-table .status_head{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%}table.wc_emails .wc-email-settings-table-name,table.wc_emails td.name,table.wc_gateways .wc-email-settings-table-name,table.wc_gateways td.name,table.wc_shipping .wc-email-settings-table-name,table.wc_shipping td.name{font-weight:700}table.wp-list-table .order-notes_head:after{content:"\e028"}table.wp-list-table .notes_head:after{content:"\e026"}table.wp-list-table .status_head:after{content:"\e011"}table.wp-list-table .column-order_items{width:12%}table.wp-list-table .column-order_items table.order_items{width:100%;margin:3px 0 0;padding:0;display:none}table.wp-list-table .column-order_items table.order_items td{border:0;margin:0;padding:0 0 3px}table.wp-list-table .column-order_items table.order_items td.qty{color:#999;padding-right:6px;text-align:left}mark.notice{background:#fff;color:#a00;margin:0 0 0 10px}a.export_rates,a.import_rates{float:right;margin-left:9px;margin-top:-2px;margin-bottom:0}#rates-search{float:right}#rates-search input.wc-tax-rates-search-field{padding:4px 8px;font-size:1.2em}#rates-pagination{float:right;margin-right:.5em}#rates-pagination .tablenav{margin:0}table.wc_input_table,table.wc_tax_rates{width:100%}table.wc_input_table span.tips,table.wc_tax_rates span.tips{color:#2ea2cc}table.wc_input_table td,table.wc_tax_rates td{padding:0;border-right:1px solid #DFDFDF;border-bottom:1px solid #DFDFDF;border-top:0;background:#fff}table.wc_input_table td input[type=text],table.wc_input_table td input[type=number],table.wc_tax_rates td input[type=text],table.wc_tax_rates td input[type=number]{width:100%;padding:5px 7px;margin:0;border:0;background:0 0}table.wc_input_table td.apply_to_shipping,table.wc_input_table td.compound,table.wc_tax_rates td.apply_to_shipping,table.wc_tax_rates td.compound{padding:5px 7px;vertical-align:middle}table.wc_input_table td.apply_to_shipping input,table.wc_input_table td.compound input,table.wc_tax_rates td.apply_to_shipping input,table.wc_tax_rates td.compound input{width:auto;padding:0}table.wc_input_table td:last-child,table.wc_tax_rates td:last-child{border-right:0}table.wc_input_table tr.current td,table.wc_tax_rates tr.current td{background-color:#fefbcc}table.wc_input_table .cost,table.wc_input_table .cost input,table.wc_input_table .item_cost,table.wc_input_table .item_cost input,table.wc_tax_rates .cost,table.wc_tax_rates .cost input,table.wc_tax_rates .item_cost,table.wc_tax_rates .item_cost input{text-align:right}table.wc_input_table th.sort,table.wc_tax_rates th.sort{width:17px;padding:0 4px}table.wc_input_table td.sort,table.wc_tax_rates td.sort{padding:0 4px}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort{cursor:move;font-size:15px;background:#f9f9f9;text-align:center;vertical-align:middle}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before{color:#333}table.wc_input_table .button,table.wc_tax_rates .button{float:left;margin-right:5px}table.wc_input_table .export,table.wc_input_table .import,table.wc_tax_rates .export,table.wc_tax_rates .import{float:right;margin-right:0;margin-left:5px}table.wc_input_table span.tips,table.wc_tax_rates span.tips{padding:0 3px}table.wc_input_table .pagination,table.wc_tax_rates .pagination{float:right}table.wc_input_table .pagination .button,table.wc_tax_rates .pagination .button{margin-left:5px;margin-right:0}table.wc_input_table .pagination .current,table.wc_tax_rates .pagination .current{background:#bbb;text-shadow:none}table.wc_input_table tfoot th,table.wc_tax_rates tfoot th{padding-left:20px;padding-right:20px}table.wc_input_table tr:last-child td,table.wc_tax_rates tr:last-child td{border-bottom:0}table.wc_emails,table.wc_gateways,table.wc_shipping{position:relative}table.wc_emails td,table.wc_gateways td,table.wc_shipping td{vertical-align:middle;padding:7px;line-height:2em}table.wc_emails tr:nth-child(odd) td,table.wc_gateways tr:nth-child(odd) td,table.wc_shipping tr:nth-child(odd) td{background:#f9f9f9}table.wc_emails th,table.wc_gateways th,table.wc_shipping th{padding:9px 7px!important;vertical-align:middle}table.wc_emails .settings,table.wc_gateways .settings,table.wc_shipping .settings{text-align:right}table.wc_emails .default,table.wc_emails .radio,table.wc_emails .status,table.wc_gateways .default,table.wc_gateways .radio,table.wc_gateways .status,table.wc_shipping .default,table.wc_shipping .radio,table.wc_shipping .status{text-align:center}table.wc_emails .default .tips,table.wc_emails .radio .tips,table.wc_emails .status .tips,table.wc_gateways .default .tips,table.wc_gateways .radio .tips,table.wc_gateways .status .tips,table.wc_shipping .default .tips,table.wc_shipping .radio .tips,table.wc_shipping .status .tips{margin:0 auto}table.wc_emails .default input,table.wc_emails .radio input,table.wc_emails .status input,table.wc_gateways .default input,table.wc_gateways .radio input,table.wc_gateways .status input,table.wc_shipping .default input,table.wc_shipping .radio input,table.wc_shipping .status input{margin:0}table.wc_emails th.sort,table.wc_gateways th.sort,table.wc_shipping th.sort{width:28px;padding:0}table.wc_emails td.sort,table.wc_gateways td.sort,table.wc_shipping td.sort{padding:0 7px;cursor:move;font-size:15px;text-align:center;vertical-align:middle}table.wc_emails td.sort:before,table.wc_gateways td.sort:before,table.wc_shipping td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_emails .wc-email-settings-table-name span,table.wc_gateways .wc-email-settings-table-name span,table.wc_shipping .wc-email-settings-table-name span{font-weight:400;color:#999;margin:0 0 0 4px!important}table.wc_emails .wc-email-settings-table-status,table.wc_gateways .wc-email-settings-table-status,table.wc_shipping .wc-email-settings-table-status{text-align:center;width:1em}table.wc_emails .wc-email-settings-table-status .tips,table.wc_gateways .wc-email-settings-table-status .tips,table.wc_shipping .wc-email-settings-table-status .tips{margin:0 auto}table.wc_emails .wc-email-settings-table-actions a,table.wc_gateways .wc-email-settings-table-actions a,table.wc_shipping .wc-email-settings-table-actions a{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}table.wc_emails .wc-email-settings-table-actions a:after,table.wc_gateways .wc-email-settings-table-actions a:after,table.wc_shipping .wc-email-settings-table-actions a:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}table.wc-shipping-classes td,table.wc-shipping-classes th,table.wc-shipping-zone-methods td,table.wc-shipping-zone-methods th,table.wc-shipping-zones td,table.wc-shipping-zones th{vertical-align:top;line-height:24px;padding:1em;font-size:14px;background:#fff}table.wc-shipping-classes td li,table.wc-shipping-classes th li,table.wc-shipping-zone-methods td li,table.wc-shipping-zone-methods th li,table.wc-shipping-zones td li,table.wc-shipping-zones th li{line-height:24px;font-size:14px}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state,table.wc-shipping-classes td.wc-shipping-zones-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state,table.wc-shipping-zones td.wc-shipping-zones-blank-state{background:#F7F1F6!important;overflow:hidden;position:relative;padding:7.5em 7.5%;border-bottom:2px solid #EEE2EC}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zones td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state p{color:#a46497;font-size:1.5em;line-height:1.5em;margin:0 0 1em;position:relative;z-index:1;text-shadow:1px 1px 1px #fff}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state p.main{font-size:2em}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state li{margin-left:1em;list-style:circle inside}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-classes td.wc-shipping-zones-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state:before,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zones td.wc-shipping-zones-blank-state:before{content:"\e01b";font-family:WooCommerce;text-align:center;line-height:1;color:#EEE2EC;display:block;width:1em;font-size:40em;top:50%;right:-3.75%;margin-top:-.1875em;position:absolute}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-classes td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zones-blank-state .button-primary{background-color:#804877;border-color:#804877;-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);margin:0;opacity:1;text-shadow:0 -1px 1px #8a4f7f,1px 0 1px #8a4f7f,0 1px 1px #8a4f7f,-1px 0 1px #8a4f7f;font-size:1.5em;padding:.75em 1em;height:auto;position:relative;z-index:1}table.wc-shipping-classes .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-classes .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-classes tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-classes tr.odd td,table.wc-shipping-zone-methods .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tr.odd td,table.wc-shipping-zones .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zones .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zones tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zones tr.odd td{background:#f9f9f9}table.wc-shipping-classes p,table.wc-shipping-classes ul,table.wc-shipping-zone-methods p,table.wc-shipping-zone-methods ul,table.wc-shipping-zones p,table.wc-shipping-zones ul{margin:0}table.wc-shipping-classes td.wc-shipping-zone-method-sort,table.wc-shipping-classes td.wc-shipping-zone-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-sort,table.wc-shipping-zones td.wc-shipping-zone-method-sort,table.wc-shipping-zones td.wc-shipping-zone-sort{cursor:move;font-size:15px;text-align:center}table.wc-shipping-classes td.wc-shipping-zone-method-sort:before,table.wc-shipping-classes td.wc-shipping-zone-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:before,table.wc-shipping-zones td.wc-shipping-zone-sort:before{content:"\f333";font-family:Dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-classes td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-sort:hover:before{color:#333}table.wc-shipping-classes td.wc-shipping-zone-worldwide,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide,table.wc-shipping-zones td.wc-shipping-zone-worldwide{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-worldwide:before,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide:before,table.wc-shipping-zones td.wc-shipping-zone-worldwide:before{content:"\f319";font-family:dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes .wc-shipping-zone-methods,table.wc-shipping-classes .wc-shipping-zone-name,table.wc-shipping-zone-methods .wc-shipping-zone-methods,table.wc-shipping-zone-methods .wc-shipping-zone-name,table.wc-shipping-zones .wc-shipping-zone-methods,table.wc-shipping-zones .wc-shipping-zone-name{width:25%}table.wc-shipping-classes .wc-shipping-class-description input,table.wc-shipping-classes .wc-shipping-class-description select,table.wc-shipping-classes .wc-shipping-class-description textarea,table.wc-shipping-classes .wc-shipping-class-name input,table.wc-shipping-classes .wc-shipping-class-name select,table.wc-shipping-classes .wc-shipping-class-name textarea,table.wc-shipping-classes .wc-shipping-class-slug input,table.wc-shipping-classes .wc-shipping-class-slug select,table.wc-shipping-classes .wc-shipping-class-slug textarea,table.wc-shipping-classes .wc-shipping-zone-name input,table.wc-shipping-classes .wc-shipping-zone-name select,table.wc-shipping-classes .wc-shipping-zone-name textarea,table.wc-shipping-classes .wc-shipping-zone-region input,table.wc-shipping-classes .wc-shipping-zone-region select,table.wc-shipping-classes .wc-shipping-zone-region textarea,table.wc-shipping-zone-methods .wc-shipping-class-description input,table.wc-shipping-zone-methods .wc-shipping-class-description select,table.wc-shipping-zone-methods .wc-shipping-class-description textarea,table.wc-shipping-zone-methods .wc-shipping-class-name input,table.wc-shipping-zone-methods .wc-shipping-class-name select,table.wc-shipping-zone-methods .wc-shipping-class-name textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug input,table.wc-shipping-zone-methods .wc-shipping-class-slug select,table.wc-shipping-zone-methods .wc-shipping-class-slug textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name input,table.wc-shipping-zone-methods .wc-shipping-zone-name select,table.wc-shipping-zone-methods .wc-shipping-zone-name textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region input,table.wc-shipping-zone-methods .wc-shipping-zone-region select,table.wc-shipping-zone-methods .wc-shipping-zone-region textarea,table.wc-shipping-zones .wc-shipping-class-description input,table.wc-shipping-zones .wc-shipping-class-description select,table.wc-shipping-zones .wc-shipping-class-description textarea,table.wc-shipping-zones .wc-shipping-class-name input,table.wc-shipping-zones .wc-shipping-class-name select,table.wc-shipping-zones .wc-shipping-class-name textarea,table.wc-shipping-zones .wc-shipping-class-slug input,table.wc-shipping-zones .wc-shipping-class-slug select,table.wc-shipping-zones .wc-shipping-class-slug textarea,table.wc-shipping-zones .wc-shipping-zone-name input,table.wc-shipping-zones .wc-shipping-zone-name select,table.wc-shipping-zones .wc-shipping-zone-name textarea,table.wc-shipping-zones .wc-shipping-zone-region input,table.wc-shipping-zones .wc-shipping-zone-region select,table.wc-shipping-zones .wc-shipping-zone-region textarea{width:100%}table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-zone-delete{color:red}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle{float:right;margin:0;font-size:.9em;text-decoration:underline}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes{display:none}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea{margin-top:1em}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes .description{font-size:.9em;color:#999}table.wc-shipping-classes .wc-shipping-class-count,table.wc-shipping-zone-methods .wc-shipping-class-count,table.wc-shipping-zones .wc-shipping-class-count{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-methods,table.wc-shipping-zone-methods td.wc-shipping-zone-methods,table.wc-shipping-zones td.wc-shipping-zone-methods{color:#999}table.wc-shipping-classes td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .method_disabled{text-decoration:line-through}table.wc-shipping-classes td.wc-shipping-zone-methods ul,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul,table.wc-shipping-zones td.wc-shipping-zone-methods ul{color:#999;position:relative;padding-right:32px}table.wc-shipping-classes td.wc-shipping-zone-methods ul li,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li,table.wc-shipping-zones td.wc-shipping-zone-methods ul li{display:inline;margin:0}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:before{content:", "}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-classes td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:nth-child(2):before{content:""}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child{display:block}table.wc-shipping-classes td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zones td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row{position:absolute;right:0;top:0}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method{display:block;width:24px;padding:24px 0 0;height:0;overflow:hidden;cursor:pointer}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method:before{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;font-family:Dashicons;content:"\f502";color:#999;vertical-align:middle;line-height:24px;font-size:16px;margin:0}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled:before{line-height:inherit}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled{margin-top:1px;display:inline-block}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled{cursor:not-allowed}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled:before{color:#ccc}table.wc-shipping-classes .wc-shipping-zone-method-title,table.wc-shipping-zone-methods .wc-shipping-zone-method-title,table.wc-shipping-zones .wc-shipping-zone-method-title{width:33%}table.wc-shipping-classes .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zone-methods .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zones .wc-shipping-zone-method-title .wc-shipping-zone-method-delete{color:red}table.wc-shipping-classes .wc-shipping-zone-method-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled{text-align:center}table.wc-shipping-classes tfoot input,table.wc-shipping-classes tfoot select,table.wc-shipping-zone-methods tfoot input,table.wc-shipping-zone-methods tfoot select,table.wc-shipping-zones tfoot input,table.wc-shipping-zones tfoot select{vertical-align:middle!important}table.wc-shipping-classes tfoot .button-secondary,table.wc-shipping-zone-methods tfoot .button-secondary,table.wc-shipping-zones tfoot .button-secondary{float:right}table.wc-shipping-classes .editing .wc-shipping-zone-edit,table.wc-shipping-classes .editing .wc-shipping-zone-view,table.wc-shipping-zone-methods .editing .wc-shipping-zone-edit,table.wc-shipping-zone-methods .editing .wc-shipping-zone-view,table.wc-shipping-zones .editing .wc-shipping-zone-edit,table.wc-shipping-zones .editing .wc-shipping-zone-view{display:none}.wc-modal-shipping-method-settings{background:#f8f8f8;padding:1em!important}.wc-modal-shipping-method-settings form .form-table{width:100%;background:#fff;margin:0 0 1.5em}.wc-modal-shipping-method-settings form .form-table tr th{width:30%;position:relative}.wc-modal-shipping-method-settings form .form-table tr th .woocommerce-help-tip{float:right;margin:-8px -.5em 0 0;vertical-align:middle;right:0;top:50%;position:absolute}.wc-modal-shipping-method-settings form .form-table tr td input,.wc-modal-shipping-method-settings form .form-table tr td select,.wc-modal-shipping-method-settings form .form-table tr td textarea{width:50%;min-width:250px}.wc-modal-shipping-method-settings form .form-table tr td input[type=checkbox]{width:auto;min-width:16px}.wc-modal-shipping-method-settings form .form-table tr td,.wc-modal-shipping-method-settings form .form-table tr th{vertical-align:middle;margin:0;line-height:24px;padding:1em;border-bottom:1px solid #f8f8f8}.wc-modal-shipping-method-settings form .form-table:last-of-type{margin-bottom:0}.wc-backbone-modal .wc-shipping-zone-method-selector p{margin-top:0}.wc-backbone-modal .wc-shipping-zone-method-selector .wc-shipping-zone-method-description{margin:.75em 1px 0;line-height:1.5em;color:#999;font-style:italic}.wc-backbone-modal .wc-shipping-zone-method-selector select{width:100%;cursor:pointer}img.help_tip{margin:0 0 0 9px;vertical-align:middle}.postbox img.help_tip{margin-top:0}.postbox .woocommerce-help-tip{margin:0 0 0 9px}.status-disabled,.status-enabled,.status-manual{font-size:1.4em;display:block;text-indent:-9999px;position:relative;height:1em;width:1em}.status-disabled:before,.status-enabled:before,.status-manual:before{font-family:WooCommerce;line-height:1;margin:0;position:absolute;width:100%;height:100%;text-indent:0;top:0;font-variant:normal;-webkit-font-smoothing:antialiased;font-weight:400;text-align:center;left:0;speak:none;text-transform:none}.status-manual:before{content:"";color:#999}.status-enabled:before{content:"";color:#a46497}.status-disabled:before{content:"";color:#ccc}.woocommerce h2.woo-nav-tab-wrapper{margin-bottom:1em}.woocommerce nav.woo-nav-tab-wrapper{margin:1.5em 0 1em;border-bottom:1px solid #ccc}.woocommerce .subsubsub{margin:-8px 0 0}.woocommerce .wc-admin-breadcrumb{margin-left:.5em}.woocommerce .wc-admin-breadcrumb a{color:#a46497}.woocommerce #template div{margin:0}.woocommerce #template div p .button{float:right;margin-left:10px;margin-top:-4px}.woocommerce #template div .editor textarea{margin-bottom:8px}.woocommerce textarea[disabled=disabled]{background:#DFDFDF!important}.woocommerce table.form-table{margin:0;position:relative}.woocommerce table.form-table .forminp-radio ul{margin:0}.woocommerce table.form-table .forminp-radio ul li{line-height:1.4em}.woocommerce table.form-table textarea.input-text{height:100%;min-width:150px;display:block}.woocommerce table.form-table input.regular-input{width:25em}.woocommerce table.form-table textarea.wide-input{width:100%}.woocommerce table.form-table .woocommerce-help-tip,.woocommerce table.form-table img.help_tip{padding:0;margin:-4px 0 0 5px;vertical-align:middle;cursor:help;line-height:1}.woocommerce table.form-table span.help_tip{cursor:help;color:#2ea2cc}.woocommerce table.form-table th{position:relative;padding-right:24px}.woocommerce table.form-table .select2-container{display:block;max-width:350px;vertical-align:top;margin-bottom:3px}.woocommerce table.form-table table.widefat th{padding-right:inherit}.woocommerce table.form-table th .woocommerce-help-tip,.woocommerce table.form-table th img.help_tip{margin:0 -24px 0 0;float:right}.woocommerce table.form-table .wp-list-table .woocommerce-help-tip{float:none}.woocommerce table.form-table fieldset{margin-top:4px}.woocommerce table.form-table fieldset .woocommerce-help-tip,.woocommerce table.form-table fieldset img.help_tip{margin:-3px 0 0 5px}.woocommerce table.form-table fieldset p.description{margin-bottom:8px}.woocommerce table.form-table fieldset:first-child{margin-top:0}.woocommerce table.form-table .iris-picker{z-index:100;display:none;position:absolute;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,.2)}.woocommerce table.form-table .iris-picker .ui-slider{border:0!important;margin:0!important;width:auto!important;height:auto!important;background:none!important}.woocommerce table.form-table .iris-picker .ui-slider .ui-slider-handle{margin-bottom:0!important}.woocommerce table.form-table .colorpickpreview{padding:3px 3px 3px 20px;border:1px solid #ddd;border-right:0}.woocommerce table.form-table .colorpick{border-left:0}.woocommerce table.form-table .image_width_settings{vertical-align:middle}.woocommerce table.form-table .image_width_settings label{margin-left:10px}.woocommerce table.form-table .wc_emails_wrapper{padding:0 15px 10px 0}.woocommerce #tabs-wrap table a.remove{margin-left:4px}.woocommerce #tabs-wrap table p{margin:0 0 4px!important;overflow:hidden;zoom:1}.woocommerce #tabs-wrap table p a.add{float:left}#wp-excerpt-editor-container{background:#fff}#product_variation-parent #parent_id{width:100%}#postimagediv img{border:1px solid #d5d5d5;max-width:100%}#woocommerce-product-images .inside{margin:0;padding:0}#woocommerce-product-images .inside .add_product_images{padding:0 12px 12px}#woocommerce-product-images .inside #product_images_container{padding:0 0 0 9px}#woocommerce-product-images .inside #product_images_container ul{margin:0;padding:0}#woocommerce-product-images .inside #product_images_container ul:after,#woocommerce-product-images .inside #product_images_container ul:before{content:" ";display:table}#woocommerce-product-images .inside #product_images_container ul:after{clear:both}#woocommerce-product-images .inside #product_images_container ul li.add,#woocommerce-product-images .inside #product_images_container ul li.image,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{width:80px;float:left;cursor:move;border:1px solid #d5d5d5;margin:9px 9px 0 0;background:#f7f7f7;border-radius:2px;position:relative;box-sizing:border-box}#woocommerce-product-images .inside #product_images_container ul li.add img,#woocommerce-product-images .inside #product_images_container ul li.image img,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder img{width:100%;height:auto;display:block}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{border:3px dashed #ddd;position:relative}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-size:2.618em;line-height:72px;color:#ddd}#woocommerce-product-images .inside #product_images_container ul ul.actions{position:absolute;top:-8px;right:-8px;padding:2px;display:none}#woocommerce-product-images .inside #product_images_container ul ul.actions li{float:right;margin:0 0 0 2px}#woocommerce-product-images .inside #product_images_container ul ul.actions li a{width:1em;margin:0;height:0;display:block;overflow:hidden}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.tips{cursor:pointer}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.4em}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:hover:before{color:#a00}#woocommerce-product-images .inside #product_images_container ul li:hover ul.actions{display:block}#woocommerce-product-data .hndle{padding:10px}#woocommerce-product-data .hndle span{display:block;vertical-align:middle;line-height:24px}#woocommerce-product-data .hndle span span{display:inline;line-height:inherit;vertical-align:baseline}#woocommerce-product-data .hndle label{padding-right:1em;font-size:12px;vertical-align:baseline}#woocommerce-product-data .hndle label:first-child{margin-right:1em;border-right:1px solid #dfdfdf}#woocommerce-product-data .hndle input,#woocommerce-product-data .hndle select{margin:-3px 0 0 .5em;vertical-align:middle}#woocommerce-product-data>.handlediv{margin-top:4px}#woocommerce-product-data .wrap{margin:0}#woocommerce-coupon-description{padding:3px 8px;font-size:1.7em;line-height:1.42em;height:auto;width:100%;outline:0;margin:10px 0;display:block}#woocommerce-coupon-description::-webkit-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description::-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-ms-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap{background:#fff}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{float:left;width:80%}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-product-data .woocommerce_options_panel .wc-radios{display:block;float:left;margin:0}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-product-data .woocommerce_options_panel .wc-radios li{display:block;padding:0 0 10px}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li input,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-product-data .woocommerce_options_panel .wc-radios li input{width:auto}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap,.woocommerce .panel-wrap{overflow:hidden}#woocommerce-coupon-data ul.wc-tabs,#woocommerce-product-data ul.wc-tabs,.woocommerce ul.wc-tabs{margin:0;width:20%;float:left;line-height:1em;padding:0 0 10px;position:relative;background-color:#fafafa;border-right:1px solid #eee;box-sizing:border-box}#woocommerce-coupon-data ul.wc-tabs:after,#woocommerce-product-data ul.wc-tabs:after,.woocommerce ul.wc-tabs:after{content:"";display:block;width:100%;height:9999em;position:absolute;bottom:-9999em;left:0;background-color:#fafafa;border-right:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li,#woocommerce-product-data ul.wc-tabs li,.woocommerce ul.wc-tabs li{margin:0;padding:0;display:block;position:relative}#woocommerce-coupon-data ul.wc-tabs li a,#woocommerce-product-data ul.wc-tabs li a,.woocommerce ul.wc-tabs li a{margin:0;padding:10px;display:block;box-shadow:none;text-decoration:none;line-height:20px!important;border-bottom:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li a:before,#woocommerce-product-data ul.wc-tabs li a:before,.woocommerce ul.wc-tabs li a:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}#woocommerce-coupon-data ul.wc-tabs li.general_options a:before,#woocommerce-product-data ul.wc-tabs li.general_options a:before,.woocommerce ul.wc-tabs li.general_options a:before{content:"\f107"}#woocommerce-coupon-data ul.wc-tabs li.inventory_options a:before,#woocommerce-product-data ul.wc-tabs li.inventory_options a:before,.woocommerce ul.wc-tabs li.inventory_options a:before{content:"\f481"}#woocommerce-coupon-data ul.wc-tabs li.shipping_options a:before,#woocommerce-product-data ul.wc-tabs li.shipping_options a:before,.woocommerce ul.wc-tabs li.shipping_options a:before{font-family:WooCommerce;content:"\e01a"}#woocommerce-coupon-data ul.wc-tabs li.linked_product_options a:before,#woocommerce-product-data ul.wc-tabs li.linked_product_options a:before,.woocommerce ul.wc-tabs li.linked_product_options a:before{content:"\f103"}#woocommerce-coupon-data ul.wc-tabs li.attribute_options a:before,#woocommerce-product-data ul.wc-tabs li.attribute_options a:before,.woocommerce ul.wc-tabs li.attribute_options a:before{content:"\f175"}#woocommerce-coupon-data ul.wc-tabs li.advanced_options a:before,#woocommerce-product-data ul.wc-tabs li.advanced_options a:before,.woocommerce ul.wc-tabs li.advanced_options a:before{font-family:Dashicons;content:"\f111"}#woocommerce-coupon-data ul.wc-tabs li.variations_options a:before,#woocommerce-product-data ul.wc-tabs li.variations_options a:before,.woocommerce ul.wc-tabs li.variations_options a:before{content:"\f509"}#woocommerce-coupon-data ul.wc-tabs li.usage_restriction_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_restriction_options a:before,.woocommerce ul.wc-tabs li.usage_restriction_options a:before{font-family:WooCommerce;content:"\e602"}#woocommerce-coupon-data ul.wc-tabs li.usage_limit_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_limit_options a:before,.woocommerce ul.wc-tabs li.usage_limit_options a:before{font-family:WooCommerce;content:"\e601"}#woocommerce-coupon-data ul.wc-tabs li.general_coupon_data a:before,#woocommerce-product-data ul.wc-tabs li.general_coupon_data a:before,.woocommerce ul.wc-tabs li.general_coupon_data a:before{font-family:WooCommerce;content:"\e600"}#woocommerce-coupon-data ul.wc-tabs li.active a,#woocommerce-product-data ul.wc-tabs li.active a,.woocommerce ul.wc-tabs li.active a{color:#555;position:relative;background-color:#eee}.woocommerce_page_wc-settings .shippingrows th.check-column{padding-top:20px}.woocommerce_page_wc-settings .shippingrows tfoot th{padding-left:10px}.woocommerce_page_wc-settings .shippingrows .add.button:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}.woocommerce_page_wc-settings h3.wc-settings-sub-title{font-size:1.2em}#woocommerce-coupon-data .inside,#woocommerce-order-data .inside,#woocommerce-order-downloads .inside,#woocommerce-product-data .inside,#woocommerce-product-type-options .inside{margin:0;padding:0}.panel,.woocommerce_options_panel{padding:9px;color:#555}.panel .form-field .woocommerce-help-tip,.woocommerce_options_panel .form-field .woocommerce-help-tip{font-size:1.4em}.panel,.woocommerce_page_settings .woocommerce_options_panel{padding:0}#woocommerce-product-specs .inside,#woocommerce-product-type-options .panel{margin:0;padding:9px}#woocommerce-product-type-options .panel p,.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p{margin:0 0 9px;font-size:12px;padding:5px 9px;line-height:24px}#woocommerce-product-type-options .panel p:after,.woocommerce_options_panel fieldset.form-field:after,.woocommerce_options_panel p:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce_options_panel .checkbox,.woocommerce_variable_attributes .checkbox{width:auto;margin:3px 0;vertical-align:middle}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{width:100%;padding:0!important}.woocommerce_options_panel .downloadable_files table th,.woocommerce_variations .downloadable_files table th{padding:7px 0 7px 7px!important}.woocommerce_options_panel .downloadable_files table th.sort,.woocommerce_variations .downloadable_files table th.sort{width:17px;padding:7px!important}.woocommerce_options_panel .downloadable_files table th .woocommerce-help-tip,.woocommerce_variations .downloadable_files table th .woocommerce-help-tip{font-size:1.1em;margin-left:0}.woocommerce_options_panel .downloadable_files table td,.woocommerce_variations .downloadable_files table td{vertical-align:middle!important;padding:4px 0 4px 7px!important;position:relative}.woocommerce_options_panel .downloadable_files table td:last-child,.woocommerce_variations .downloadable_files table td:last-child{padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td input.input_text,.woocommerce_variations .downloadable_files table td input.input_text{width:100%;float:none;min-width:0;margin:1px 0}.woocommerce_options_panel .downloadable_files table td .upload_file_button,.woocommerce_variations .downloadable_files table td .upload_file_button{width:auto;float:right;cursor:pointer}.woocommerce_options_panel .downloadable_files table td .delete,.woocommerce_variations .downloadable_files table td .delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.2em}.woocommerce_options_panel .downloadable_files table td .delete:before,.woocommerce_variations .downloadable_files table td .delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}.woocommerce_options_panel .downloadable_files table td .delete:hover:before,.woocommerce_variations .downloadable_files table td .delete:hover:before{color:#a00}.woocommerce_options_panel .downloadable_files table td.sort,.woocommerce_variations .downloadable_files table td.sort{width:17px;cursor:move;font-size:15px;text-align:center;background:#f9f9f9;padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td.sort:before,.woocommerce_variations .downloadable_files table td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_options_panel .downloadable_files table td.sort:hover:before,.woocommerce_variations .downloadable_files table td.sort:hover:before{color:#333}.woocommerce_variation h3 .sort{width:17px;height:26px;cursor:move;float:right;font-size:15px;font-weight:400;margin-right:.5em;visibility:hidden;text-align:center;vertical-align:middle}.woocommerce_variation h3 .sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:28px;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_variation h3 .sort:hover:before{color:#777}.woocommerce_variation h3:hover .sort,.woocommerce_variation.ui-sortable-helper .sort{visibility:visible}.woocommerce_options_panel{min-height:175px;box-sizing:border-box}.woocommerce_options_panel .downloadable_files{padding:0 9px 0 162px;position:relative;margin:9px 0}.woocommerce_options_panel .downloadable_files label{position:absolute;left:0;margin:0 0 0 12px;line-height:24px}.woocommerce_options_panel p{margin:9px 0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px 5px 162px!important}.woocommerce_options_panel .sale_price_dates_fields .short:first-of-type{margin-bottom:1em}.woocommerce_options_panel .sale_price_dates_fields .short:nth-of-type(2){clear:left}.woocommerce_options_panel label,.woocommerce_options_panel legend{float:left;width:150px;padding:0;margin:0 0 0 -150px}.woocommerce_options_panel label .req,.woocommerce_options_panel legend .req{font-weight:700;font-style:normal;color:#a00}.woocommerce_options_panel .description{padding:0;margin:0 0 0 7px;clear:none;display:inline}.woocommerce_options_panel .description-block{margin-left:0;display:block}.woocommerce_options_panel input,.woocommerce_options_panel select,.woocommerce_options_panel textarea{margin:0}.woocommerce_options_panel textarea{height:3.5em;line-height:1.5em;vertical-align:top}.woocommerce_options_panel input[type=text],.woocommerce_options_panel input[type=number],.woocommerce_options_panel input[type=email],.woocommerce_options_panel input[type=password]{width:50%;float:left}.woocommerce_options_panel input.button{width:auto;margin-left:8px}.woocommerce_options_panel select{float:left}.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:50%}.woocommerce_options_panel .sized{width:auto!important;margin-right:6px}.woocommerce_options_panel .options_group{border-top:1px solid #fff;border-bottom:1px solid #eee}.woocommerce_options_panel .options_group:first-child{border-top:0}.woocommerce_options_panel .options_group:last-child{border-bottom:0}.woocommerce_options_panel .options_group fieldset{margin:9px 0;font-size:12px;padding:5px 9px;line-height:24px}.woocommerce_options_panel .options_group fieldset label{width:auto;float:none}.woocommerce_options_panel .options_group fieldset ul{float:left;width:50%;margin:0;padding:0}.woocommerce_options_panel .options_group fieldset ul li{margin:0;width:auto}.woocommerce_options_panel .options_group fieldset ul li input{width:auto;float:none;margin-right:4px}.woocommerce_options_panel .options_group fieldset ul.wc-radios label{margin-left:0}.woocommerce_options_panel .dimensions_field .wrap{display:block;width:50%}.woocommerce_options_panel .dimensions_field .wrap input{width:30.75%;margin-right:3.8%}.woocommerce_options_panel .dimensions_field .wrap .last{margin-right:0}.woocommerce_options_panel.padded{padding:1em}#woocommerce-product-data input.dp-applied,.woocommerce_options_panel .select2-container{float:left}#grouped_product_options,#simple_product_options,#virtual_product_options{padding:12px;font-style:italic;color:#666}.wc-metaboxes-wrapper .toolbar{margin:0!important;border-top:1px solid #fff;border-bottom:1px solid #eee;padding:9px 12px!important}.wc-metaboxes-wrapper .toolbar:first-child{border-top:0}.wc-metaboxes-wrapper .toolbar:last-child{border-bottom:0}.wc-metaboxes-wrapper .toolbar .add_variation{float:right;margin-left:5px}.wc-metaboxes-wrapper .toolbar .cancel-variation-changes,.wc-metaboxes-wrapper .toolbar .save-variation-changes{float:left;margin-right:5px}.wc-metaboxes-wrapper p.toolbar{overflow:hidden;zoom:1}.wc-metaboxes-wrapper .expand-close{margin-right:2px;color:#777;font-size:12px;font-style:italic}.wc-metaboxes-wrapper .expand-close a{background:0 0;padding:0;font-size:12px;text-decoration:none}.wc-metaboxes-wrapper#product_attributes .expand-close{float:right;line-height:28px}.wc-metaboxes-wrapper .fr,.wc-metaboxes-wrapper button.add_variable_attribute{float:right;margin:0 0 0 6px}.wc-metaboxes-wrapper .wc-metaboxes{border-bottom:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox-sortable-placeholder{border-color:#bbb;background-color:#f5f5f5;margin-bottom:9px;border-width:1px;border-style:dashed}.wc-metaboxes-wrapper .wc-metabox{background:#fff;border-bottom:1px solid #eee;margin:0!important}.wc-metaboxes-wrapper .wc-metabox select{font-weight:400}.wc-metaboxes-wrapper .wc-metabox:last-of-type{border-bottom:0}.wc-metaboxes-wrapper .wc-metabox .handlediv{width:27px}.wc-metaboxes-wrapper .wc-metabox .handlediv:before{content:"\f142"!important;cursor:pointer;display:inline-block;font:400 20px/1 Dashicons;line-height:.5!important;padding:8px 10px;position:relative;right:12px;top:0}.wc-metaboxes-wrapper .wc-metabox.closed{border-radius:3px}.wc-metaboxes-wrapper .wc-metabox.closed .handlediv:before{content:"\f140"!important}.wc-metaboxes-wrapper .wc-metabox.closed h3{border:0}.wc-metaboxes-wrapper .wc-metabox h3{margin:0!important;padding:.75em .75em .75em 1em!important;font-size:1em!important;overflow:hidden;zoom:1;cursor:move}.wc-metaboxes-wrapper .wc-metabox h3 a.delete,.wc-metaboxes-wrapper .wc-metabox h3 button{float:right}.wc-metaboxes-wrapper .wc-metabox h3 a.delete{color:red;font-weight:400;line-height:26px;text-decoration:none;position:relative;visibility:hidden}.wc-metaboxes-wrapper .wc-metabox h3 strong{line-height:26px;font-weight:700}.wc-metaboxes-wrapper .wc-metabox h3 select{font-family:sans-serif;max-width:20%;margin:.25em .25em .25em 0}.wc-metaboxes-wrapper .wc-metabox h3 .handlediv{background-position:6px 5px!important;visibility:hidden;height:26px}.wc-metaboxes-wrapper .wc-metabox h3.fixed{cursor:pointer!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3{cursor:pointer;padding:.5em .75em .5em 1em!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .handlediv,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .sort,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 a.delete{margin-top:.25em}.wc-metaboxes-wrapper .wc-metabox h3:hover .handlediv,.wc-metaboxes-wrapper .wc-metabox h3:hover a.delete,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper .handlediv,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper a.delete{visibility:visible}.wc-metaboxes-wrapper .wc-metabox table{width:100%;position:relative;background-color:#fdfdfd;padding:1em;border-top:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox table td{text-align:left;padding:0 6px 1em 0;vertical-align:top;border:0}.wc-metaboxes-wrapper .wc-metabox table td label{text-align:left;display:block;line-height:21px}.wc-metaboxes-wrapper .wc-metabox table td input{float:left;min-width:200px}.wc-metaboxes-wrapper .wc-metabox table td input,.wc-metaboxes-wrapper .wc-metabox table td textarea{width:100%;margin:0;display:block;font-size:14px;padding:4px;color:#555}.wc-metaboxes-wrapper .wc-metabox table td .select2-container,.wc-metaboxes-wrapper .wc-metabox table td select{width:100%!important}.wc-metaboxes-wrapper .wc-metabox table td input.short{width:200px}.wc-metaboxes-wrapper .wc-metabox table td input.checkbox{width:16px;min-width:inherit;vertical-align:text-bottom;display:inline-block;float:none}.wc-metaboxes-wrapper .wc-metabox table td.attribute_name{width:200px}.wc-metaboxes-wrapper .wc-metabox table .minus,.wc-metaboxes-wrapper .wc-metabox table .plus{margin-top:6px}.wc-metaboxes-wrapper .wc-metabox table .fl{float:left}.wc-metaboxes-wrapper .wc-metabox table .fr{float:right}.variations-pagenav{float:right;line-height:24px}.variations-pagenav .displaying-num{color:#777;font-size:12px;font-style:italic}.variations-pagenav a{padding:0 10px 3px;background:rgba(0,0,0,.05);font-size:16px;font-weight:400;text-decoration:none}.variations-pagenav a.disabled,.variations-pagenav a.disabled:active,.variations-pagenav a.disabled:focus,.variations-pagenav a.disabled:hover{color:#A0A5AA;background:rgba(0,0,0,.05)}.variations-defaults{float:left}.variations-defaults select{margin:.25em .25em .25em 0}.woocommerce_variable_attributes{background-color:#fdfdfd;border-top:1px solid #eee}.woocommerce_variable_attributes .data{padding:1em 2em}.woocommerce_variable_attributes .data:after,.woocommerce_variable_attributes .data:before{content:" ";display:table}.woocommerce_variable_attributes .data:after{clear:both}.woocommerce_variable_attributes .upload_image_button{display:block;width:48px;height:48px;float:left;margin-right:20px;position:relative;cursor:pointer}.woocommerce_variable_attributes .upload_image_button img{width:100%;height:auto;display:none}.woocommerce_variable_attributes .upload_image_button:before{content:"\f128";font-family:Dashicons;position:absolute;top:0;left:0;right:0;bottom:0;text-align:center;line-height:48px;font-size:48px;font-weight:400;-webkit-font-smoothing:antialiased}.woocommerce_variable_attributes .upload_image_button.remove img{display:block}.woocommerce_variable_attributes .upload_image_button.remove:before{content:"\f335";display:none}.woocommerce_variable_attributes .upload_image_button.remove:hover:before{display:block}.woocommerce_variable_attributes .options{border:1px solid #eee;border-width:1px 0;padding:.25em 0}.woocommerce_variable_attributes .options label{display:inline-block;padding:4px 1em 2px 0}.woocommerce_variable_attributes .options input[type=checkbox]{margin-top:5px;margin-right:3px}.form-row label{display:block}.form-row input[type=number],.form-row input[type=text],.form-row select{width:100%}.form-row.dimensions_field input{width:25%;float:left;margin-right:1%}.form-row.dimensions_field input:last-of-type{margin-right:0}.form-row-first,.form-row-last{width:48%;float:right}.form-row-first{clear:both;float:left}.form-row-full{clear:both}.tips{cursor:help;text-decoration:none}img.tips{padding:5px 0 0}#tiptip_holder{display:none;position:absolute;top:0;left:0;z-index:9999999}#tiptip_holder.tip_top{padding-bottom:5px}#tiptip_holder.tip_top #tiptip_arrow_inner{margin-top:-7px;margin-left:-6px;border-top-color:#333}#tiptip_holder.tip_bottom{padding-top:5px}#tiptip_holder.tip_bottom #tiptip_arrow_inner{margin-top:-5px;margin-left:-6px;border-bottom-color:#333}#tiptip_holder.tip_right{padding-left:5px}#tiptip_holder.tip_right #tiptip_arrow_inner{margin-top:-6px;margin-left:-5px;border-right-color:#333}#tiptip_holder.tip_left{padding-right:5px}#tiptip_holder.tip_left #tiptip_arrow_inner{margin-top:-6px;margin-left:-7px;border-left-color:#333}#tiptip_content,.chart-tooltip,.wc_error_tip{color:#fff;font-size:.8em;max-width:150px;background:#333;text-align:center;border-radius:3px;padding:.618em 1em;box-shadow:0 1px 3px rgba(0,0,0,.2)}#tiptip_content code,.chart-tooltip code,.wc_error_tip code{padding:1px;background:#888}#tiptip_arrow,#tiptip_arrow_inner{position:absolute;border-color:transparent;border-style:solid;border-width:6px;height:0;width:0}.wc_error_tip{max-width:20em;line-height:1.8em;position:absolute;white-space:normal;background:#d82223;margin:1.5em 1px 0 -1em;z-index:9999999}.wc_error_tip:after{content:"";display:block;border:8px solid #d82223;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-3px;left:50%;margin:-1em 0 0 -3px}img.ui-datepicker-trigger{vertical-align:middle;margin-top:-1px;cursor:pointer}.wc-metabox-content img.ui-datepicker-trigger,.woocommerce_options_panel img.ui-datepicker-trigger{float:left;margin-right:8px;margin-top:4px;margin-left:4px}#ui-datepicker-div{display:none}.woocommerce-reports-wide.woocommerce-reports-wrap,.woocommerce-reports-wrap.woocommerce-reports-wrap{margin-left:300px;padding-top:18px}.woocommerce-reports-wide.halved,.woocommerce-reports-wrap.halved{margin:0;overflow:hidden;zoom:1}.woocommerce-reports-wide .widefat td,.woocommerce-reports-wrap .widefat td{vertical-align:top;padding:7px}.woocommerce-reports-wide .widefat td .description,.woocommerce-reports-wrap .widefat td .description{margin:4px 0 0}.woocommerce-reports-wide .postbox:after,.woocommerce-reports-wrap .postbox:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox h3,.woocommerce-reports-wrap .postbox h3{cursor:default!important}.woocommerce-reports-wide .postbox .inside,.woocommerce-reports-wrap .postbox .inside{padding:10px;margin:0!important}.woocommerce-reports-wide .postbox div.stats_range,.woocommerce-reports-wide .postbox h3.stats_range,.woocommerce-reports-wrap .postbox div.stats_range,.woocommerce-reports-wrap .postbox h3.stats_range{border-bottom-color:#dfdfdf;margin:0;padding:0!important}.woocommerce-reports-wide .postbox div.stats_range .export_csv,.woocommerce-reports-wide .postbox h3.stats_range .export_csv,.woocommerce-reports-wrap .postbox div.stats_range .export_csv,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv{float:right;line-height:26px;border-left:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range .export_csv:before,.woocommerce-reports-wide .postbox h3.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox div.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;content:"";text-decoration:none;margin-right:4px}.woocommerce-reports-wide .postbox div.stats_range ul,.woocommerce-reports-wide .postbox h3.stats_range ul,.woocommerce-reports-wrap .postbox div.stats_range ul,.woocommerce-reports-wrap .postbox h3.stats_range ul{list-style:none;margin:0;padding:0;zoom:1;background:#f5f5f5;border-bottom:1px solid #ccc}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox div.stats_range ul:before,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:before,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:before,.woocommerce-reports-wrap .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:before{content:" ";display:table}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:after{clear:both}.woocommerce-reports-wide .postbox div.stats_range ul li,.woocommerce-reports-wide .postbox h3.stats_range ul li,.woocommerce-reports-wrap .postbox div.stats_range ul li,.woocommerce-reports-wrap .postbox h3.stats_range ul li{float:left;margin:0;padding:0;line-height:26px;font-weight:700;font-size:14px}.woocommerce-reports-wide .postbox div.stats_range ul li a,.woocommerce-reports-wide .postbox h3.stats_range ul li a,.woocommerce-reports-wrap .postbox div.stats_range ul li a,.woocommerce-reports-wrap .postbox h3.stats_range ul li a{border-right:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range ul li.active,.woocommerce-reports-wide .postbox h3.stats_range ul li.active,.woocommerce-reports-wrap .postbox div.stats_range ul li.active,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active{background:#fff;-webkit-box-shadow:0 4px 0 0 #fff;box-shadow:0 4px 0 0 #fff}.woocommerce-reports-wide .postbox div.stats_range ul li.active a,.woocommerce-reports-wide .postbox h3.stats_range ul li.active a,.woocommerce-reports-wrap .postbox div.stats_range ul li.active a,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active a{color:#777}.woocommerce-reports-wide .postbox div.stats_range ul li.custom,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom{padding:9px 10px;vertical-align:middle}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form{display:inline;margin:0}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form input.range_datepicker{padding:0;margin:0 10px 0 0;background:0 0;border:0;color:#777;text-align:center;-webkit-box-shadow:none;box-shadow:none}.woocommerce-reports-wide .postbox .chart-with-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar{padding:12px 12px 12px 249px;margin:0!important}.woocommerce-reports-wide .postbox .chart-with-sidebar .chart-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar .chart-sidebar{width:225px;margin-left:-237px;float:left}.woocommerce-reports-wide .postbox .chart-widgets,.woocommerce-reports-wrap .postbox .chart-widgets{margin:0;padding:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget{margin:0 0 1em;background:#fafafa;border:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4{background:#fff;border:1px solid #dfdfdf;border-left-width:0;border-right-width:0;padding:10px;margin:0;color:#2ea2cc;border-top-width:0;background-image:-webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9));background-image:-webkit-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-moz-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-o-linear-gradient(bottom,#ececec,#f9f9f9);background-image:linear-gradient(to top,#ececec,#f9f9f9)}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr.active td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr.active td{background:#f5f5f5}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4.section_title:hover,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4.section_title:hover{color:#a00}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title{cursor:pointer}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span{display:block}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin-left:.618em;content:"";text-decoration:none;float:right;font-size:.9em;line-height:1.618}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open{color:#333}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open span:after{display:none}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section{border-bottom:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section .select2-container,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section .select2-container{width:100%!important}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section:last-of-type,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section:last-of-type{border-radius:0 0 3px 3px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td{padding:7px 10px;vertical-align:top;border-top:1px solid #e5e5e5;line-height:1.4em}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.sparkline,form.report_filters div,form.report_filters input,form.report_filters label,form.report_filters p{vertical-align:middle}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr:first-child td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr:first-child td{border-top:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name{max-width:175px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name a,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name a{word-wrap:break-word}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table .wc_sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table .wc_sparkline{width:32px;height:1em;display:block;float:right}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p{margin:0;padding:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p .submit{margin-top:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget #product_ids,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget #product_ids{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_none,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_none{float:right;color:#999;margin-left:4px;margin-top:10px}.woocommerce-reports-wide .postbox .chart-legend,.woocommerce-reports-wrap .postbox .chart-legend{list-style:none;margin:0 0 1em;padding:0;border:1px solid #dfdfdf;border-right-width:0;border-bottom-width:0;background:#fff}.woocommerce-reports-wide .postbox .chart-legend li,.woocommerce-reports-wrap .postbox .chart-legend li{border-right:5px solid #aaa;color:#aaa;padding:1em;display:block;margin:0;-webkit-transition:all ease .5s;box-shadow:inset 0 -1px 0 0 #dfdfdf}.woocommerce-reports-wide .postbox .chart-legend li strong,.woocommerce-reports-wrap .postbox .chart-legend li strong{font-size:1.618em;line-height:1.2em;color:#464646;font-weight:400;display:block;font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif}.woocommerce-reports-wide .postbox .chart-legend li strong del,.woocommerce-reports-wrap .postbox .chart-legend li strong del{color:#e74c3c;font-weight:400}.woocommerce-reports-wide .postbox .chart-legend li:hover,.woocommerce-reports-wrap .postbox .chart-legend li:hover{box-shadow:inset 0 -1px 0 0 #dfdfdf,inset 300px 0 0 rgba(156,93,144,.1);border-right:5px solid #9c5d90!important;padding-left:1.5em;color:#9c5d90}.woocommerce-reports-wide .postbox .pie-chart-legend,.woocommerce-reports-wrap .postbox .pie-chart-legend{margin:12px 0 0;overflow:hidden}.woocommerce-reports-wide .postbox .pie-chart-legend li,.woocommerce-reports-wrap .postbox .pie-chart-legend li{float:left;margin:0;padding:6px 0 0;border-top:4px solid #999;text-align:center;box-sizing:border-box;width:50%}.woocommerce-reports-wide .postbox .stat,.woocommerce-reports-wrap .postbox .stat{font-size:1.5em!important;font-weight:700;text-align:center}.woocommerce-reports-wide .postbox .chart-placeholder,.woocommerce-reports-wrap .postbox .chart-placeholder{width:100%;height:650px;overflow:hidden;position:relative}.woocommerce-reports-wide .postbox .chart-prompt,.woocommerce-reports-wrap .postbox .chart-prompt{line-height:650px;margin:0;color:#999;font-size:1.2em;font-style:italic;text-align:center}.woocommerce-reports-wide .postbox .chart-container,.woocommerce-reports-wrap .postbox .chart-container{background:#fff;padding:12px;position:relative;border:1px solid #dfdfdf;border-radius:3px}.woocommerce-reports-wide .postbox .main .chart-legend,.woocommerce-reports-wrap .postbox .main .chart-legend{margin-top:12px}.woocommerce-reports-wide .postbox .main .chart-legend li,.woocommerce-reports-wrap .postbox .main .chart-legend li{border-right:0;margin:0 8px 0 0;float:left;border-top:4px solid #aaa}.woocommerce-reports-wide .woocommerce-reports-main,.woocommerce-reports-wrap .woocommerce-reports-main{float:left;min-width:100%}.woocommerce-reports-wide .woocommerce-reports-main table td,.woocommerce-reports-wrap .woocommerce-reports-main table td{padding:9px}.woocommerce-reports-wide .woocommerce-reports-sidebar,.woocommerce-reports-wrap .woocommerce-reports-sidebar{display:inline;width:281px;margin-left:-300px;clear:both;float:left}.woocommerce-reports-wide .woocommerce-reports-left,.woocommerce-reports-wrap .woocommerce-reports-left{width:49.5%;float:left}.woocommerce-reports-wide .woocommerce-reports-right,.woocommerce-reports-wrap .woocommerce-reports-right{width:49.5%;float:right}.woocommerce-reports-wide .column-wc_actions a.edit,.woocommerce-reports-wide .column-wc_actions a.view,.woocommerce-reports-wrap .column-wc_actions a.edit,.woocommerce-reports-wrap .column-wc_actions a.view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;line-height:1.85}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after{content:"\f464"}.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{content:"\f177"}.woocommerce-wide-reports-wrap{padding-bottom:11px}.woocommerce-wide-reports-wrap .widefat .export-data{float:right}.woocommerce-wide-reports-wrap .widefat td,.woocommerce-wide-reports-wrap .widefat th{vertical-align:middle;padding:7px}.chart-tooltip{position:absolute;display:none;line-height:1}table.bar_chart{width:100%}table.bar_chart thead th{text-align:left;color:#ccc;padding:6px 0}table.bar_chart tbody th{padding:6px 0;width:25%;text-align:left!important;font-weight:400!important;border-bottom:1px solid #fee}table.bar_chart tbody td{text-align:right;line-height:24px;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td span{color:#8a4b75;display:block}table.bar_chart tbody td span.alt{color:#47a03e;margin-top:6px}table.bar_chart tbody td.bars{position:relative;text-align:left;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td.bars a,table.bar_chart tbody td.bars span{text-decoration:none;clear:both;background:#8a4b75;float:left;display:block;line-height:24px;height:24px;-moz-border-radius:3px;-webkit-border-radius:3px;-o-border-radius:3px;-khtml-border-radius:3px;border-radius:3px}.post-type-product .woocommerce-BlankState-message:before,.post-type-shop_coupon .woocommerce-BlankState-message:before,.post-type-shop_order .woocommerce-BlankState-message:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}table.bar_chart tbody td.bars span.alt{clear:both;background:#47a03e}table.bar_chart tbody td.bars span.alt span{margin:0;color:#c5dec2!important;text-shadow:0 1px 0 #47a03e;background:0 0}.post-type-shop_order .woocommerce-BlankState-message:before{content:""}.post-type-shop_coupon .woocommerce-BlankState-message:before{content:""}.post-type-product .woocommerce-BlankState-message:before{content:""}.woocommerce-BlankState{text-align:center;padding:5em 0 0}.woocommerce-BlankState .woocommerce-BlankState-message{color:#aaa;margin:0 auto 1.5em;line-height:1.5em;font-size:1.2em;max-width:500px}.woocommerce-BlankState .woocommerce-BlankState-message:before{color:#ddd;text-shadow:0 -1px 1px rgba(0,0,0,.2),0 1px 0 rgba(255,255,255,.8);font-size:8em;display:block;position:relative!important;top:auto;left:auto;line-height:1em;margin:0 0 .1875em}.woocommerce-BlankState .woocommerce-BlankState-cta{font-size:1.2em;padding:.75em 1.5em;height:auto}@media only screen and (max-width:1280px){#order_data .order_data_column{width:48%}#order_data .order_data_column:first-child{width:100%}.woocommerce_options_panel .description{display:block;clear:both;margin-left:0}.woocommerce_options_panel .dimensions_field .wrap,.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:80%}.woocommerce_options_panel .downloadable_files,.woocommerce_variations .downloadable_files{padding:0;clear:both}.woocommerce_options_panel .downloadable_files label,.woocommerce_variations .downloadable_files label{position:static}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{margin:0 12px 24px;width:94%}.woocommerce_options_panel .downloadable_files table .sort,.woocommerce_variations .downloadable_files table .sort{visibility:hidden}.woocommerce_options_panel .woocommerce_variable_attributes .downloadable_files table,.woocommerce_variations .woocommerce_variable_attributes .downloadable_files table{margin:0 0 1em;width:100%}}@media only screen and (max-width:900px){#woocommerce-coupon-data ul.coupon_data_tabs,#woocommerce-product-data .wc-tabs-back,#woocommerce-product-data ul.product_data_tabs{width:10%}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{width:90%}#woocommerce-coupon-data ul.coupon_data_tabs li a,#woocommerce-product-data ul.product_data_tabs li a{position:relative;text-indent:-999px;padding:10px}#woocommerce-coupon-data ul.coupon_data_tabs li a:before,#woocommerce-product-data ul.product_data_tabs li a:before{position:absolute;top:0;right:0;bottom:0;left:0;text-indent:0;text-align:center;line-height:40px;width:100%;height:40px}}@media only screen and (max-width:782px){#wp-excerpt-media-buttons a{font-size:16px;line-height:37px;height:39px;padding:0 20px 0 15px}#wp-excerpt-editor-tools{padding-top:20px;padding-right:15px;overflow:hidden;margin-bottom:-1px}.post-type-product .wp-list-table .is-expanded td:not(.hidden),.post-type-shop_order .wp-list-table .is-expanded td:not(.hidden){overflow:visible}#woocommerce-product-data .checkbox{width:25px}.variations-pagenav{float:none;text-align:center;font-size:18px}.variations-pagenav .displaying-num{font-size:16px}.variations-pagenav a{padding:8px 20px 11px;font-size:18px}.variations-pagenav select{padding:0 20px}.variations-defaults{float:none;text-align:center;margin-top:10px}.post-type-product .wp-list-table .column-thumb{display:none;text-align:left;padding-bottom:0}.post-type-product .wp-list-table .column-thumb:before{display:none!important}.post-type-product .wp-list-table .column-thumb img{max-width:32px}.post-type-product .wp-list-table .toggle-row{top:-28px}.post-type-shop_order .wp-list-table .column-order_status{display:none;text-align:left;padding-bottom:0}.post-type-shop_order .wp-list-table .column-order_status mark{margin:0}.post-type-shop_order .wp-list-table .column-order_status:before{display:none!important}.post-type-shop_order .wp-list-table .column-customer_message,.post-type-shop_order .wp-list-table .column-order_notes{text-align:inherit}.post-type-shop_order .wp-list-table .column-order_notes .note-on{font-size:1.3em;margin:0}.post-type-shop_order .wp-list-table .toggle-row{top:-15px}}@media only screen and (max-width:500px){.woocommerce_options_panel label,.woocommerce_options_panel legend{float:none;width:auto;display:block;margin:0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px!important}}.wc-backbone-modal *{box-sizing:border-box}.wc-backbone-modal .wc-backbone-modal-content{position:fixed;background:#fff;z-index:100000;left:50%;top:50%;transform:translate(-50%,-50%);width:500px}.wc-backbone-modal .wc-backbone-modal-content article{overflow:auto}.wc-backbone-modal.wc-backbone-modal-shipping-method-settings .wc-backbone-modal-content{width:75%;min-width:500px}.wc-backbone-modal-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;min-height:360px;background:#000;opacity:.7;z-index:99900}.wc-backbone-modal-main{padding-bottom:55px}.wc-backbone-modal-main article,.wc-backbone-modal-main header{display:block;position:relative}.wc-backbone-modal-main .wc-backbone-modal-header{height:auto;background:#fcfcfc;padding:1em 1.5em;border-bottom:1px solid #ddd}.wc-backbone-modal-main .wc-backbone-modal-header h1{margin:0;font-size:18px;font-weight:700;line-height:1.5em}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link{cursor:pointer;color:#777;height:54px;width:54px;padding:0;position:absolute;top:0;right:0;text-align:center;border:0;border-left:1px solid #ddd;background-color:transparent;-webkit-transition:color .1s ease-in-out,background .1s ease-in-out;transition:color .1s ease-in-out,background .1s ease-in-out}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:before{font:400 22px/50px dashicons!important;color:#666;display:block;content:'\f335';font-weight:300}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus,.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:hover{background:#ddd;border-color:#ccc;color:#000}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus{outline:0}.wc-backbone-modal-main article{padding:1.5em}.wc-backbone-modal-main article p{margin:1.5em 0}.wc-backbone-modal-main article p:last-child,.wc-backbone-modal-main footer .inner .button{margin-bottom:0}.wc-backbone-modal-main article p:first-child{margin-top:0}.wc-backbone-modal-main article .pagination{padding:10px 0 0;text-align:center}.wc-backbone-modal-main footer{position:absolute;left:0;right:0;bottom:0;z-index:100;padding:1em 1.5em;background:#fcfcfc;border-top:1px solid #dfdfdf;box-shadow:0 -4px 4px -4px rgba(0,0,0,.1)}.wc-backbone-modal-main footer .inner{float:right;line-height:23px}.select2-drop{z-index:999999!important}.select2-container-multi .select2-choices .select2-search-field input{font-family:inherit;font-size:inherit;font-weight:inherit;padding:3px 5px}.select2-container{line-height:1.85em;font-size:14px} \ No newline at end of file +@charset "UTF-8";.button.wc-reload:after,.woocommerce-help-tip:after{speak:none;text-transform:none;-webkit-font-smoothing:antialiased}@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg)}}@-moz-keyframes spin{100%{-moz-transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}.select2-container{margin:0;position:relative;display:block!important;zoom:1;vertical-align:middle}.select2-container,.select2-drop,.select2-search,.select2-search input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{display:block;padding:0 0 0 8px;overflow:hidden;position:relative;border:1px solid #ccc;white-space:nowrap;color:#444;text-decoration:none;border-radius:3px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;font-weight:400}html[dir=rtl] .select2-container .select2-choice{padding:0 8px 0 0}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#ccc;border-radius:0 0 4px 4px}.select2-container.select2-allowclear .select2-choice .select2-chosen{margin-right:42px}.select2-container .select2-choice>.select2-chosen{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:none;width:auto}html[dir=rtl] .select2-container .select2-choice>.select2-chosen{margin-left:26px;margin-right:0}.select2-container .select2-choice abbr{display:none;width:12px;height:12px;position:absolute;right:24px;top:5px;font-size:1px;text-decoration:none;border:0;background:url(../images/select2.png) right top no-repeat;cursor:pointer;outline:0}.select2-container.select2-allowclear .select2-choice abbr{display:inline-block}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop-mask{border:0;margin:0;padding:0;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:9998;background-color:#fff;filter:alpha(opacity=0)}.select2-drop{width:100%;margin-top:-1px;position:absolute;top:100%;background:#fff;color:#000;border:1px solid #ccc;border-top:0;border-radius:0 0 3px 3px}.select2-drop.select2-drop-above{margin-top:1px;border-top:1px solid #ccc;border-bottom:0;border-radius:3px 3px 0 0}.select2-drop-active{border:1px solid #666;border-top:none}.select2-drop.select2-drop-above.select2-drop-active{border-top:1px solid #666}.select2-drop-auto-width{border-top:1px solid #ccc;width:auto}.select2-drop-auto-width .select2-search{padding-top:4px}.select2-container .select2-choice .select2-arrow{display:inline-block;width:18px;height:100%;position:absolute;right:0;top:0;border-radius:0 3px 3px 0;background-clip:padding-box}html[dir=rtl] .select2-container .select2-choice .select2-arrow{left:0;right:auto;border-radius:3px 0 0 3px}.select2-container .select2-choice .select2-arrow b{display:block;width:100%;height:100%;position:relative}.select2-container .select2-choice .select2-arrow b:after{position:absolute;display:block;content:"";top:50%;left:50%;border:4px solid transparent;border-top-color:#666;margin-left:-7px;margin-top:-2px}.select2-search{display:inline-block;width:100%;margin:0;padding-left:4px;padding-right:4px;position:relative;z-index:10000;white-space:nowrap;padding-bottom:4px}.select2-search input{width:100%;height:auto!important;padding:4px 20px 4px 5px!important;margin:0;outline:0;font-family:sans-serif;font-size:1em;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none;background:url(../images/select2.png) 100% -22px no-repeat #fff}html[dir=rtl] .select2-search input{padding:4px 5px 4px 20px;background:url(../images/select2.png) -37px -22px no-repeat #fff}.select2-drop.select2-drop-above .select2-search input{margin-top:4px}.select2-search input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff}.select2-container-active .select2-choice,.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-dropdown-open .select2-choice{border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-dropdown-open .select2-choice .select2-arrow b:after{border-top-color:transparent;border-bottom-color:#666;margin-top:-6px}.select2-dropdown-open.select2-drop-above .select2-choice,.select2-dropdown-open.select2-drop-above .select2-choices{border:1px solid #666;border-top-color:transparent}.select2-dropdown-open .select2-choice .select2-arrow{background:0 0;border-left:none;filter:none}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow{border-right:none}.select2-dropdown-open .select2-choice .select2-arrow b{background-position:-18px 1px}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow b{background-position:-16px 1px}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.select2-results{max-height:200px;padding:4px;margin:0;position:relative;overflow-x:hidden;overflow-y:auto;-webkit-tap-highlight-color:transparent;background:#fafafa}html[dir=rtl] .select2-results{padding:0 4px 0 0;margin:4px 0 4px 4px}.select2-results ul.select2-result-sub{margin:0;padding-left:0}.select2-results li{list-style:none;display:list-item;background-image:none;margin:3px 0}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:700}.select2-results .select2-result-label{padding:5px 7px;margin:0;cursor:pointer;min-height:1em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select2-results-dept-1 .select2-result-label{padding-left:20px}.select2-results-dept-2 .select2-result-label{padding-left:40px}.select2-results-dept-3 .select2-result-label{padding-left:60px}.select2-results-dept-4 .select2-result-label{padding-left:80px}.select2-results-dept-5 .select2-result-label{padding-left:100px}.select2-results-dept-6 .select2-result-label{padding-left:110px}.select2-results-dept-7 .select2-result-label{padding-left:120px}.select2-results .select2-highlighted{background:#f1f1f1;color:#000;border-radius:3px}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:0 0}.select2-results .select2-highlighted ul{background:#fff;color:#000}.select2-results .select2-ajax-error,.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item;padding-left:5px}.select2-results .select2-disabled.select2-highlighted{color:#666;background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-disabled{background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-selected{display:none}.select2-more-results.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #f4f4f4}.select2-results .select2-ajax-error{background:rgba(255,50,50,.2)}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice .select2-arrow{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container.select2-container-disabled .select2-choice abbr{display:none}.select2-container-multi .select2-choices{height:auto!important;height:1%;margin:0;padding:0 5px 0 0;position:relative;border:1px solid #ccc;cursor:text;overflow:hidden;background-color:#fff;min-height:26px}html[dir=rtl] .select2-container-multi .select2-choices{padding:0 0 0 5px}.select2-locked{padding:3px 5px!important}.select2-container-multi.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-container-multi .select2-choices li{float:left;list-style:none}html[dir=rtl] .select2-container-multi .select2-choices li{float:right}.select2-container-multi .select2-choices .select2-search-field{margin:0;padding:0;white-space:nowrap}.select2-container-multi .select2-choices .select2-search-field:first-child{width:100%}.select2-container-multi .select2-choices .select2-search-field input{margin:1px 0;outline:0;border:0;-webkit-box-shadow:none;box-shadow:none;background:0 0!important}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff!important}.select2-default{color:#999!important}.select2-container-multi .select2-choices .select2-search-choice{padding:5px 8px 5px 24px;margin:3px 0 3px 5px;position:relative;line-height:15px;color:#333;cursor:default;border-radius:2px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#e4e4e4}html[dir=rtl] .select2-container-multi .select2-choices .select2-search-choice{margin:3px 5px 3px 0;padding:5px 24px 5px 8px}.select2-container-multi .select2-choices .select2-search-choice .select2-chosen{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;width:12px;height:13px;position:absolute;right:7px;top:6px;font-size:1px;outline:0;background:url(../images/select2.png) right top no-repeat}html[dir=rtl] .select2-search-choice-close{right:auto;left:7px}.select2-container-multi .select2-search-choice-close{left:7px}html[dir=rtl] .select2-container-multi .select2-search-choice-close{left:auto;right:7px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover,.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{padding:3px 5px;border:1px solid #ddd;background-image:none;background-color:#f4f4f4}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none;background:0 0}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-match{text-decoration:underline}.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.select2-display-none{display:none}.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:2dppx){.select2-search input{background-image:url(../images/select2x2.png)!important;background-repeat:no-repeat!important;background-size:60px 40px!important;background-position:100% -21px!important}}@font-face{font-family:star;src:url(../fonts/star.eot);src:url(../fonts/star.eot?#iefix) format("embedded-opentype"),url(../fonts/star.woff) format("woff"),url(../fonts/star.ttf) format("truetype"),url(../fonts/star.svg#star) format("svg");font-weight:400;font-style:normal}@font-face{font-family:WooCommerce;src:url(../fonts/WooCommerce.eot);src:url(../fonts/WooCommerce.eot?#iefix) format("embedded-opentype"),url(../fonts/WooCommerce.woff) format("woff"),url(../fonts/WooCommerce.ttf) format("truetype"),url(../fonts/WooCommerce.svg#WooCommerce) format("svg");font-weight:400;font-style:normal}.blockUI.blockOverlay:before{height:1em;width:1em;position:absolute;top:50%;left:50%;margin-left:-.5em;margin-top:-.5em;display:block;content:"";-webkit-animation:spin 1s ease-in-out infinite;-moz-animation:spin 1s ease-in-out infinite;animation:spin 1s ease-in-out infinite;background:url(../images/icons/loader.svg) center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75)}.wc_addons_wrap .products{overflow:hidden}.wc_addons_wrap .products li{float:left;margin:0 1em 1em 0!important;padding:0;vertical-align:top;width:300px}.wc_addons_wrap .products li a{text-decoration:none;color:inherit;border:1px solid #ddd;display:block;min-height:220px;overflow:hidden;background:#f5f5f5;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1)}.wc_addons_wrap .products li a img{max-width:258px;max-height:24px;padding:17px 20px;display:block;margin:0;background:#fff;border-right:260px solid #fff}.wc_addons_wrap .products li a .price,.wc_addons_wrap .products li a img.extension-thumb+h3{display:none}.wc_addons_wrap .products li a h2,.wc_addons_wrap .products li a h3{margin:0!important;padding:20px!important;background:#fff}.wc_addons_wrap .products li a p{padding:20px!important;margin:0!important;border-top:1px solid #f1f1f1}.wc_addons_wrap .products li a:focus,.wc_addons_wrap .products li a:hover{background-color:#fff}.wc_addons_wrap .storefront{background:url(../images/storefront-bg.jpg) bottom right #f6f6f6;border:1px solid #ddd;padding:20px;overflow:hidden;zoom:1}.wc_addons_wrap .storefront img{width:278px;height:auto;float:left;margin:0 20px 0 0;box-shadow:0 1px 6px rgba(0,0,0,.1)}.wc_addons_wrap .storefront p{max-width:750px}.woocommerce-BlankState a.button-primary,.woocommerce-BlankState button.button-primary,.woocommerce-message a.button-primary,.woocommerce-message button.button-primary{background:#bb77ae;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;color:#fff;text-shadow:0 -1px 1px #A36597,1px 0 1px #A36597,0 1px 1px #A36597,-1px 0 1px #A36597}.woocommerce-BlankState a.button-primary:active,.woocommerce-BlankState a.button-primary:focus,.woocommerce-BlankState a.button-primary:hover,.woocommerce-BlankState button.button-primary:active,.woocommerce-BlankState button.button-primary:focus,.woocommerce-BlankState button.button-primary:hover,.woocommerce-message a.button-primary:active,.woocommerce-message a.button-primary:focus,.woocommerce-message a.button-primary:hover,.woocommerce-message button.button-primary:active,.woocommerce-message button.button-primary:focus,.woocommerce-message button.button-primary:hover{background:#A36597;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597}.woocommerce-message{position:relative;border-left-color:#cc99c2!important;overflow:hidden}.woocommerce-message a.docs,.woocommerce-message a.skip{text-decoration:none!important}.woocommerce-message a.woocommerce-message-close{position:absolute;top:10px;right:10px;padding:10px 15px 10px 21px;font-size:13px;line-height:1.23076923;text-decoration:none}.woocommerce-message a.woocommerce-message-close:before{position:absolute;top:8px;left:0;-webkit-transition:all .1s ease-in-out;transition:all .1s ease-in-out}.woocommerce-message .twitter-share-button{margin-top:-3px;margin-left:3px;vertical-align:middle}#variable_product_options #message,#variable_product_options .notice{margin:10px}.clear{clear:both}#woocommerce-fields-bulk.inline-edit-col label,#woocommerce-fields.inline-edit-col{clear:left}.wrap.woocommerce div.error,.wrap.woocommerce div.updated{margin-top:10px}mark.amount{background:0 0;color:inherit}.postbox,.woocommerce{input:invalid;input-border:1px solid #cc010b;input-background:#ffebe8}.simplify-commerce-banner{overflow:hidden}.simplify-commerce-banner img{float:right;padding:15px 0;margin-left:1em;width:200px}.woocommerce-help-tip{color:#666;display:inline-block;font-size:1.1em;font-style:normal;height:16px;line-height:16px;position:relative;vertical-align:middle;width:16px}.woocommerce-help-tip:after{font-family:Dashicons;font-weight:400;font-variant:normal;line-height:1;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";cursor:help}h2 .woocommerce-help-tip{margin-top:-5px;margin-left:.25em}table.wc_status_table{margin-bottom:1em}table.wc_status_table h2{font-size:14px;margin:0}table.wc_status_table tr:nth-child(2n) td,table.wc_status_table tr:nth-child(2n) th{background:#fcfcfc}table.wc_status_table th{font-weight:700;padding:9px}table.wc_status_table td:first-child{width:33%}table.wc_status_table td.help{width:1em}table.wc_status_table td{padding:9px;font-size:1.1em}table.wc_status_table td mark{background:0 0}table.wc_status_table td mark.yes{color:#7ad03a}table.wc_status_table td mark.no{color:#999}table.wc_status_table td mark.error{color:#a00}table.wc_status_table td ul{margin:0}table.wc_status_table .help_tip{cursor:help}#debug-report{display:none;margin:10px 0;padding:0;position:relative}#debug-report textarea{font-family:monospace;width:100%;margin:0;height:300px;padding:20px;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;resize:none;font-size:12px;line-height:20px;outline:0}#log-viewer-select{padding:10px 0 8px;line-height:180%}#log-viewer textarea{width:100%;resize:vertical}.inline-edit-product.quick-edit-row .inline-edit-col-center,.inline-edit-product.quick-edit-row .inline-edit-col-right{float:right!important}#woocommerce-fields.inline-edit-col label.featured,#woocommerce-fields.inline-edit-col label.manage_stock{margin-left:10px}#woocommerce-fields.inline-edit-col .dimensions div{display:block;margin:.2em 0}#woocommerce-fields.inline-edit-col .dimensions div span.title{display:block;float:left;width:5em}#woocommerce-fields.inline-edit-col .dimensions div span.input-text-wrap{display:block;margin-left:5em}#woocommerce-fields.inline-edit-col .text{box-sizing:border-box;width:99%;float:left;margin:1px 1% 1px 1px}#woocommerce-fields.inline-edit-col .height,#woocommerce-fields.inline-edit-col .length,#woocommerce-fields.inline-edit-col .width{width:32.33%}#woocommerce-fields.inline-edit-col .height{margin-right:0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group label{clear:none;width:49%;margin:.2em 0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group.dimensions label{width:75%;max-width:75%}#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .regular_price,#woocommerce-fields-bulk.inline-edit-col .sale_price,#woocommerce-fields-bulk.inline-edit-col .stock,#woocommerce-fields-bulk.inline-edit-col .weight{box-sizing:border-box;width:100%;margin-left:4.4em}#woocommerce-fields-bulk.inline-edit-col .height,#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .width{box-sizing:border-box;width:25%}.column-coupon_code{line-height:2.25em}.column-coupon_code,ul.wc_coupon_list{margin:0;overflow:hidden;zoom:1;clear:both}ul.wc_coupon_list li{margin:0}ul.wc_coupon_list li.code{display:inline-block}ul.wc_coupon_list li.code:after{content:", "}ul.wc_coupon_list li.code:last-of-type:after{display:none}ul.wc_coupon_list li.code .tips{cursor:pointer}ul.wc_coupon_list_block{margin:0;padding-bottom:2px}ul.wc_coupon_list_block li{border-top:1px solid #fff;border-bottom:1px solid #ccc;line-height:2.5em;margin:0;padding:.5em 0}ul.wc_coupon_list_block li:first-child{border-top:0;padding-top:0}ul.wc_coupon_list_block li:last-child{border-bottom:0;padding-bottom:0}.button.wc-reload{text-indent:-9999px;position:relative;padding:0;height:28px;width:28px!important;display:inline-block}.button.wc-reload:after{font-family:Dashicons;font-weight:400;font-variant:normal;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:28px}#order_data h2,#order_data p.order_number{font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif;font-weight:400}.tablenav .actions{overflow:visible}.tablenav .select2-container{float:left;max-width:200px;font-size:14px;vertical-align:middle;margin:1px 6px 1px 1px}#woocommerce-order-data .handlediv,#woocommerce-order-data .hndle{display:none}#woocommerce-order-data .inside{display:block!important}#order_data{padding:23px 24px 12px}#order_data h2{margin:0;font-size:21px;line-height:1.2;text-shadow:1px 1px 1px #fff;padding:0}#order_data h3{font-size:14px}#order_data h3,#order_data h4{color:#333;margin:1.33em 0 0}#order_data p{color:#777}#order_data p.order_number{margin:0;line-height:1.6em;font-size:16px}#order_data .order_data_column_container{clear:both}#order_data .order_data_column{width:32%;padding:0 2% 0 0;float:left}#order_data .order_data_column:last-child{padding-right:0}#order_data .order_data_column p{padding:0!important}#order_data .order_data_column .address strong{display:block}#order_data .order_data_column .form-field{float:left;width:48%;padding:0;margin:9px 0 0}#order_data .order_data_column .form-field label{display:block;padding:0 0 3px}#order_data .order_data_column .form-field input,#order_data .order_data_column .form-field select,#order_data .order_data_column .form-field textarea{width:100%}#order_data .order_data_column .form-field .select2-container{width:100%!important}#order_data .order_data_column .form-field .date-picker{width:50%}#order_data .order_data_column .form-field .hour,#order_data .order_data_column .form-field .minute{width:3em}#order_data .order_data_column .form-field small{display:block;margin:5px 0 0;color:#999}#order_data .order_data_column .form-field.last{float:right}#order_data .order_data_column .form-field-wide{width:100%;clear:both}#order_data .order_data_column .form-field-wide .wc-customer-search,#order_data .order_data_column .form-field-wide .wc-enhanced-select,#order_data .order_data_column .form-field-wide input,#order_data .order_data_column .form-field-wide select,#order_data .order_data_column .form-field-wide textarea{width:100%}#order_data .order_data_column p.none_set{color:#999}#order_data .order_data_column ._billing_address_1_field,#order_data .order_data_column ._billing_city_field,#order_data .order_data_column ._billing_country_field,#order_data .order_data_column ._billing_email_field,#order_data .order_data_column ._billing_first_name_field,#order_data .order_data_column ._shipping_address_1_field,#order_data .order_data_column ._shipping_city_field,#order_data .order_data_column ._shipping_country_field,#order_data .order_data_column ._shipping_first_name_field{float:left}#order_data .order_data_column ._billing_address_2_field,#order_data .order_data_column ._billing_last_name_field,#order_data .order_data_column ._billing_phone_field,#order_data .order_data_column ._billing_postcode_field,#order_data .order_data_column ._billing_state_field,#order_data .order_data_column ._shipping_address_2_field,#order_data .order_data_column ._shipping_last_name_field,#order_data .order_data_column ._shipping_postcode_field,#order_data .order_data_column ._shipping_state_field,#order_data .order_data_column .wc-customer-user label a,#order_data .order_data_column .wc-order-status label a{float:right}#order_data .order_data_column ._billing_company_field,#order_data .order_data_column ._shipping_company_field,#order_data .order_data_column ._transaction_id_field{clear:both;width:100%}#order_data .order_data_column ._billing_email_field{clear:left}#order_data .order_data_column div.edit_address{display:none;zoom:1;padding-right:1px}#order_data .order_data_column .billing-same-as-shipping,#order_data .order_data_column .load_customer_billing,#order_data .order_data_column .load_customer_shipping,#order_data .order_data_column a.edit_address{width:14px;height:0;padding:14px 0 0;margin:0 0 0 6px;overflow:hidden;position:relative;color:#999;border:0;float:right}#order_data .order_data_column .billing-same-as-shipping:focus,#order_data .order_data_column .billing-same-as-shipping:hover,#order_data .order_data_column .load_customer_billing:focus,#order_data .order_data_column .load_customer_billing:hover,#order_data .order_data_column .load_customer_shipping:focus,#order_data .order_data_column .load_customer_shipping:hover,#order_data .order_data_column a.edit_address:focus,#order_data .order_data_column a.edit_address:hover{color:#000}#order_data .order_data_column .billing-same-as-shipping:after,#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after,#order_data .order_data_column a.edit_address: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}#order_data .order_data_column .billing-same-as-shipping:after{content:"\e008"}#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after{content:"\e03a"}#order_data .order_data_column a.edit_address:after{font-family:Dashicons;content:"\f464"}.order_actions{margin:0;overflow:hidden;zoom:1}.order_actions li{border-top:1px solid #fff;border-bottom:1px solid #ddd;padding:6px 0;margin:0;line-height:1.6em;float:left;width:50%;text-align:center}.order_actions li a{float:none;text-align:center;text-decoration:underline}.order_actions li.wide{width:auto;float:none;clear:both;padding:6px;text-align:left;overflow:hidden}.order_actions li #delete-action{line-height:25px;vertical-align:middle;text-align:left;float:left}.order_actions li .save_order{float:right}.order_actions li#actions{overflow:hidden}.order_actions li#actions .button{width:24px;box-sizing:border-box;float:right}.order_actions li#actions select{width:225px;box-sizing:border-box;float:left}#woocommerce-order-items .inside{margin:0;padding:0;background:#fefefe}#woocommerce-order-items .wc-order-data-row{border-bottom:1px solid #DFDFDF;padding:1.5em 2em;background:#f8f8f8;line-height:2em;text-align:right}#woocommerce-order-items .wc-order-data-row:after,#woocommerce-order-items .wc-order-data-row:before{content:" ";display:table}#woocommerce-order-items .wc-order-data-row:after{clear:both}#woocommerce-order-items .wc-order-data-row p{margin:0;line-height:2em}#woocommerce-order-items .wc-order-data-row .wc-used-coupons{text-align:left}#woocommerce-order-items .wc-order-data-row .wc-used-coupons .tips{display:inline-block}#woocommerce-order-items .wc-order-add-item{background:#fff;vertical-align:top;border-top:none}#woocommerce-order-items .wc-order-add-item .add_item_id,#woocommerce-order-items .wc-order-add-item .select2-container{vertical-align:top}#woocommerce-order-items .wc-order-add-item .add_item_id .search-field input,#woocommerce-order-items .wc-order-add-item .select2-container .search-field input{min-width:100px}#woocommerce-order-items .wc-order-add-item .select2-container{width:400px!important;text-align:left}#woocommerce-order-items .wc-order-add-item .calculate-action,#woocommerce-order-items .wc-order-add-item .cancel-action,#woocommerce-order-items .wc-order-add-item .save-action{float:left;margin-right:2px}#woocommerce-order-items .wc-used-coupons{float:left;width:50%}#woocommerce-order-items .wc-order-totals{float:right;width:50%;margin:0;padding:0;text-align:right}#woocommerce-order-items .wc-order-totals .amount{font-weight:700}#woocommerce-order-items .wc-order-totals .label{vertical-align:top}#woocommerce-order-items .wc-order-totals .total{font-size:1em!important;width:10em;margin:0 0 0 .5em;box-sizing:border-box}#woocommerce-order-items .wc-order-totals .total input[type=text]{width:96%;float:right}#woocommerce-order-items .wc-order-totals .refunded-total{color:#a00}#woocommerce-order-items .refund-actions{margin-top:5px;padding-top:12px;border-top:1px solid #DFDFDF}#woocommerce-order-items .refund-actions .button{float:right;margin-left:4px}#woocommerce-order-items .refund-actions .cancel-action,#woocommerce-order-items .wc-order-item-bulk-edit .cancel-action{float:left;margin-left:0}#woocommerce-order-items .add_meta{margin-left:0!important}#woocommerce-order-items h3 small{color:#999}#woocommerce-order-items .amount{white-space:nowrap}#woocommerce-order-items .add-items .description{margin-right:10px}#woocommerce-order-items .add-items .button{float:left;margin-right:.25em}#woocommerce-order-items .add-items .button-primary{float:none;margin-right:0}#woocommerce-order-items .inside{display:block!important}#woocommerce-order-items .handlediv,#woocommerce-order-items .hndle{display:none}#woocommerce-order-items .woocommerce_order_items_wrapper{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items{width:100%;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th{text-align:left;padding:1em;font-weight:400;color:#999;background:#f8f8f8;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th.sortable{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th .wc-arrow{float:right;position:relative;margin-right:-1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td{padding:1.5em 1em 1em;text-align:left;line-height:1.5em;vertical-align:top;border-bottom:1px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td select{width:50%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{font-size:14px;padding:4px;color:#555}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr td{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected{background:#F5EBF3}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected td{border-color:#E6CCE1;opacity:.8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:last-child td{border-bottom:1px solid #dfdfdf}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:first-child td{border-top:8px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody#order_line_items tr:first-child td{border-top:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb{text-align:left;width:38px;padding-bottom:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail{width:38px;height:38px;border:2px solid #e8e8e8;background:#f8f8f8;color:#ccc;position:relative;font-size:21px;display:block;text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;height:100%;text-align:center;content:"";width:38px;line-height:38px;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail img{width:100%;height:100%;margin:0;padding:0;position:relative}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-sku,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-variation{display:block;margin-top:.5em;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item{min-width:200px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .center,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .variation-id{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class{text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label{white-space:nowrap;color:#999;font-size:.833em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label input{display:inline}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class input{width:70px;vertical-align:middle;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class select{width:85px;height:26px;vertical-align:middle;font-size:1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input{display:inline-block;background:#fff;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);margin:1px 0;min-width:80px;overflow:hidden;line-height:1em;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input{width:100%;box-sizing:border-box}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input label{font-size:.75em;padding:4px 6px 0;color:#555;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input{width:100%;box-sizing:border-box;border:0;box-shadow:none;margin:0;padding:0 6px 4px;color:#555;background:0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input::-webkit-input-placeholder{color:#ddd}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child{border-bottom:1px dashed #ddd;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child label{color:#ccc}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .view{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .edit{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes label{display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount{display:block;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{margin-right:.25em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input{text-align:center;width:50px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items span.subtotal{opacity:.5}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.tax_class,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.tax_class{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .calculated{border-color:#ae8ca2;border-style:dotted}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{margin:.5em 0 0;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{color:#ccc;top:0;left:0;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-align:center;font-family:WooCommerce}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr th{border:0;padding:0 4px .5em 0;line-height:1.5em;width:20%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td{padding:0 4px .5em 0;border:0;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input{width:100%;margin:0;position:relative;border-bottom:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .refund_by,ul.order_notes li p.meta .exact-date{border-bottom:1px dotted #999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td textarea{width:100%;height:4em;margin:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input:focus+textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input:focus+textarea{border-top-color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p{margin:0 0 .5em;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p:last-child{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method_name{width:100%;margin:0 0 .5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;float:right;font-size:14px;visibility:hidden;margin:3px -18px 0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:hover:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:hover:before{color:#a00}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax:hover .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax:hover .delete-order-tax{visibility:visible}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded{display:block;color:#a00;white-space:nowrap;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;width:100%;height:100%;text-align:center;content:"";position:relative;top:auto;left:auto;margin:-1px 4px 0 0;vertical-align:middle;line-height:1em}#woocommerce-order-items .wc-order-edit-line-item{padding-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions{width:44px;text-align:right;padding-left:0;vertical-align:middle}#woocommerce-order-items .wc-order-edit-line-item-actions a{color:#ccc;display:inline-block;cursor:pointer;padding:0 0 .5em;margin:0 0 0 12px;vertical-align:middle;text-decoration:none;line-height:16px;width:16px;overflow:hidden}#woocommerce-order-items .wc-order-edit-line-item-actions a:before{margin:0;padding:0;font-size:16px;width:16px;height:16px}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before,#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{font-family:Dashicons;-webkit-font-smoothing:antialiased;text-indent:0;top:0;left:0;width:100%;height:100%;margin:0;text-align:center;position:relative;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1}#woocommerce-order-items .wc-order-edit-line-item-actions a:hover:before{color:#999}#woocommerce-order-items .wc-order-edit-line-item-actions a:first-child{margin-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:hover:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:hover:before{color:#a00}#woocommerce-order-items tbody tr .wc-order-edit-line-item-actions{visibility:hidden}#woocommerce-order-items tbody tr:hover .wc-order-edit-line-item-actions{visibility:visible}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions{width:1.5em;visibility:visible!important}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions a{padding:0}#woocommerce-order-downloads .buttons{float:left;padding:0;margin:0;vertical-align:top}#woocommerce-order-downloads .buttons .add_item_id,#woocommerce-order-downloads .buttons .select2-container{width:400px!important;margin-right:9px;vertical-align:top;float:left}#woocommerce-order-downloads .buttons button{margin:2px 0 0}#woocommerce-order-downloads h3 small{color:#999}#poststuff #woocommerce-order-actions .inside{margin:0;padding:0}#poststuff #woocommerce-order-actions .inside ul.order_actions li{padding:6px 10px;box-sizing:border-box}#poststuff #woocommerce-order-actions .inside ul.order_actions li:last-child{border-bottom:0}#poststuff #woocommerce-order-notes .inside{margin:0;padding:0}#poststuff #woocommerce-order-notes .inside ul.order_notes li{padding:0 10px}#woocommerce_customers p.search-box{margin:6px 0 4px;float:left}#woocommerce_customers .tablenav{float:right;clear:none}.widefat.customers td{vertical-align:middle;padding:4px 7px}.widefat .column-order_title{width:15%}.widefat .column-order_title time{display:block;color:#999;margin:3px 0}.widefat .column-orders,.widefat .column-paying,.widefat .column-spent{text-align:center;width:8%}.widefat .column-last_order{width:11%}.widefat .column-order_actions,.widefat .column-user_actions,.widefat .column-wc_actions{width:110px}.widefat .column-order_actions a.button,.widefat .column-user_actions a.button,.widefat .column-wc_actions a.button{float:left;margin:0 4px 2px 0;cursor:pointer;padding:3px 4px;height:auto}.widefat .column-order_actions a.button img,.widefat .column-user_actions a.button img,.widefat .column-wc_actions a.button img{display:block;width:12px;height:auto}.widefat small.meta{display:block;color:#999;font-size:inherit;margin:3px 0}.widefat .column-order_date,.widefat .column-order_total{width:9%}.widefat .column-order_status{width:45px;text-align:center}.widefat .column-order_status mark{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;background:0 0;font-size:1.4em;margin:0 auto}.widefat .column-order_status mark.cancelled:after,.widefat .column-order_status mark.completed:after,.widefat .column-order_status mark.failed:after,.widefat .column-order_status mark.on-hold:after,.widefat .column-order_status mark.pending:after,.widefat .column-order_status mark.processing:after,.widefat .column-order_status mark.refunded:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.column-customer_message .note-on:after,.column-order_notes .note-on:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;left:0;text-align:center;line-height:16px;font-family:WooCommerce}.widefat .column-order_status mark.pending:after{content:"\e012";color:#ffba00}.widefat .column-order_status mark.completed:after{content:"\e015";color:#2ea2cc}.widefat .column-order_status mark.on-hold:after{content:"\e033";color:#999}.widefat .column-order_status mark.failed:after{content:"\e016";color:#d0c21f}.widefat .column-order_status mark.cancelled:after{content:"\e013";color:#a00}.widefat .column-order_status mark.processing:after{content:"\e011";color:#73a724}.widefat .column-order_status mark.refunded:after{content:"\e014";color:#999}.widefat td.column-order_status{padding-top:9px}.column-customer_message .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-customer_message .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.column-order_notes .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-order_notes .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.order_actions .complete,.order_actions .processing,.order_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.order_actions .processing:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.order_actions .complete:after,.order_actions .view:after{font-family:Dashicons;text-indent:0;position:absolute;width:100%;height:100%;left:0;line-height:1.85;margin:0;text-align:center;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;font-weight:400}.order_actions .complete:after{content:""}.order_actions .view:after{content:""}.user_actions .edit,.user_actions .link,.user_actions .refresh,.user_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.user_actions .edit:after,.user_actions .link:after,.user_actions .refresh:after,.user_actions .view:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.user_actions .edit:after{font-family:Dashicons;content:"\f464"}.user_actions .link:after{content:"\e00d"}.user_actions .view:after{content:"\e010"}.user_actions .refresh:after{content:"\e031"}.attributes-table td,.attributes-table th{width:15%;vertical-align:top}.attributes-table .attribute-terms{width:32%}.attributes-table .attribute-actions{width:2em}.attributes-table .attribute-actions .configure-terms{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.attributes-table .attribute-actions .configure-terms:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}ul.order_notes{padding:2px 0 0}ul.order_notes li .note_content{padding:10px;background:#efefef;position:relative}ul.order_notes li .note_content p{margin:0;padding:0;word-wrap:break-word}ul.order_notes li p.meta{padding:10px;color:#999;margin:0;font-size:11px}ul.order_notes li a.delete_note{color:#a00}table.wp-list-table .row-actions,table.wp-list-table span.na{color:#999}ul.order_notes li .note_content:after{content:"";display:block;position:absolute;bottom:-10px;left:20px;width:0;height:0;border-width:10px 10px 0 0;border-style:solid;border-color:#efefef transparent}ul.order_notes li.customer-note .note_content{background:#A7CEDC}ul.order_notes li.customer-note .note_content:after{border-color:#A7CEDC transparent}ul.order_notes li.system-note .note_content{background:#d7cad2}ul.order_notes li.system-note .note_content:after{border-color:#d7cad2 transparent}.add_note{border-top:1px solid #ddd;padding:10px 10px 0}.add_note h4{margin-top:5px!important}.add_note #add_order_note{width:100%;height:50px}table.wp-list-table .column-thumb{width:52px;text-align:center;white-space:nowrap}table.wp-list-table .column-name{width:22%}table.wp-list-table .column-product_cat,table.wp-list-table .column-product_tag{width:11%!important}table.wp-list-table .column-featured,table.wp-list-table .column-product_type{width:48px;text-align:left!important}table.wp-list-table .column-customer_message,table.wp-list-table .column-order_notes{width:48px;text-align:center}table.wp-list-table .column-customer_message img,table.wp-list-table .column-order_notes img{margin:0 auto;padding-top:0!important}table.wp-list-table .manage-column.column-featured img,table.wp-list-table .manage-column.column-product_type img{padding-left:2px}table.wp-list-table .column-price .woocommerce-price-suffix{display:none}table.wp-list-table img{margin:1px 2px}table.wp-list-table td.column-thumb img{margin:0;width:auto;height:auto;max-width:40px;max-height:40px;vertical-align:middle}table.wp-list-table .column-is_in_stock{text-align:left!important}table.wp-list-table span.wc-featured,table.wp-list-table span.wc-image,table.wp-list-table span.wc-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table span.wc-featured:before,table.wp-list-table span.wc-image:before,table.wp-list-table span.wc-type:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:""}table.wp-list-table span.wc-featured{margin:0;cursor:pointer}table.wp-list-table span.wc-featured:before{content:"\f155"}table.wp-list-table span.wc-featured.not-featured:before{content:"\f154"}table.wp-list-table td.column-featured span.wc-featured{font-size:1.6em}table.wp-list-table span.wc-type{margin:0}table.wp-list-table span.wc-type:before{font-family:WooCommerce;content:"\e006"}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after,table.wp-list-table span.product-type:before{font-family:WooCommerce;text-align:center;line-height:1;top:0;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;left:0}table.wp-list-table span.product-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.6em}table.wp-list-table span.product-type:before{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}table.wp-list-table span.product-type.grouped:before{content:"\e002"}table.wp-list-table span.product-type.external:before{content:"\e034"}table.wp-list-table span.product-type.variable:before{content:"\e003"}table.wp-list-table span.product-type.downloadable:before{content:"\e001"}table.wp-list-table span.product-type.virtual:before{content:"\e000"}table.wp-list-table mark.instock{font-weight:700;color:#7ad03a;background:0 0;line-height:1}table.wp-list-table mark.outofstock{font-weight:700;color:#a44;background:0 0;line-height:1}table.wp-list-table .notes_head,table.wp-list-table .order-notes_head,table.wp-list-table .status_head{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%}table.wc_emails .wc-email-settings-table-name,table.wc_emails td.name,table.wc_gateways .wc-email-settings-table-name,table.wc_gateways td.name,table.wc_shipping .wc-email-settings-table-name,table.wc_shipping td.name{font-weight:700}table.wp-list-table .order-notes_head:after{content:"\e028"}table.wp-list-table .notes_head:after{content:"\e026"}table.wp-list-table .status_head:after{content:"\e011"}table.wp-list-table .column-order_items{width:12%}table.wp-list-table .column-order_items table.order_items{width:100%;margin:3px 0 0;padding:0;display:none}table.wp-list-table .column-order_items table.order_items td{border:0;margin:0;padding:0 0 3px}table.wp-list-table .column-order_items table.order_items td.qty{color:#999;padding-right:6px;text-align:left}mark.notice{background:#fff;color:#a00;margin:0 0 0 10px}a.export_rates,a.import_rates{float:right;margin-left:9px;margin-top:-2px;margin-bottom:0}#rates-search{float:right}#rates-search input.wc-tax-rates-search-field{padding:4px 8px;font-size:1.2em}#rates-pagination{float:right;margin-right:.5em}#rates-pagination .tablenav{margin:0}table.wc_input_table,table.wc_tax_rates{width:100%}table.wc_input_table span.tips,table.wc_tax_rates span.tips{color:#2ea2cc}table.wc_input_table th,table.wc_tax_rates th{white-space:nowrap}table.wc_input_table td,table.wc_tax_rates td{padding:0;border-right:1px solid #DFDFDF;border-bottom:1px solid #DFDFDF;border-top:0;background:#fff;cursor:default}table.wc_input_table td input[type=text],table.wc_input_table td input[type=number],table.wc_tax_rates td input[type=text],table.wc_tax_rates td input[type=number]{width:100%;padding:5px 10px;margin:0;border:0;background:0 0}table.wc_input_table td.apply_to_shipping,table.wc_input_table td.compound,table.wc_tax_rates td.apply_to_shipping,table.wc_tax_rates td.compound{padding:5px 7px;vertical-align:middle}table.wc_input_table td.apply_to_shipping input,table.wc_input_table td.compound input,table.wc_tax_rates td.apply_to_shipping input,table.wc_tax_rates td.compound input{width:auto;padding:0}table.wc_input_table td:last-child,table.wc_tax_rates td:last-child{border-right:0}table.wc_input_table tr.current td,table.wc_tax_rates tr.current td{background-color:#fefbcc}table.wc_input_table .cost,table.wc_input_table .cost input,table.wc_input_table .item_cost,table.wc_input_table .item_cost input,table.wc_tax_rates .cost,table.wc_tax_rates .cost input,table.wc_tax_rates .item_cost,table.wc_tax_rates .item_cost input{text-align:right}table.wc_input_table th.sort,table.wc_tax_rates th.sort{width:17px;padding:0 4px}table.wc_input_table td.sort,table.wc_tax_rates td.sort{padding:0 4px}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort{cursor:move;font-size:15px;background:#f9f9f9;text-align:center;vertical-align:middle}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before{color:#333}table.wc_input_table .button,table.wc_tax_rates .button{float:left;margin-right:5px}table.wc_input_table .export,table.wc_input_table .import,table.wc_tax_rates .export,table.wc_tax_rates .import{float:right;margin-right:0;margin-left:5px}table.wc_input_table span.tips,table.wc_tax_rates span.tips{padding:0 3px}table.wc_input_table .pagination,table.wc_tax_rates .pagination{float:right}table.wc_input_table .pagination .button,table.wc_tax_rates .pagination .button{margin-left:5px;margin-right:0}table.wc_input_table .pagination .current,table.wc_tax_rates .pagination .current{background:#bbb;text-shadow:none}table.wc_input_table tr:last-child td,table.wc_tax_rates tr:last-child td{border-bottom:0}table.wc_emails,table.wc_gateways,table.wc_shipping{position:relative}table.wc_emails td,table.wc_gateways td,table.wc_shipping td{vertical-align:middle;padding:7px;line-height:2em}table.wc_emails tr:nth-child(odd) td,table.wc_gateways tr:nth-child(odd) td,table.wc_shipping tr:nth-child(odd) td{background:#f9f9f9}table.wc_emails th,table.wc_gateways th,table.wc_shipping th{padding:9px 7px!important;vertical-align:middle}table.wc_emails .settings,table.wc_gateways .settings,table.wc_shipping .settings{text-align:right}table.wc_emails .default,table.wc_emails .radio,table.wc_emails .status,table.wc_gateways .default,table.wc_gateways .radio,table.wc_gateways .status,table.wc_shipping .default,table.wc_shipping .radio,table.wc_shipping .status{text-align:center}table.wc_emails .default .tips,table.wc_emails .radio .tips,table.wc_emails .status .tips,table.wc_gateways .default .tips,table.wc_gateways .radio .tips,table.wc_gateways .status .tips,table.wc_shipping .default .tips,table.wc_shipping .radio .tips,table.wc_shipping .status .tips{margin:0 auto}table.wc_emails .default input,table.wc_emails .radio input,table.wc_emails .status input,table.wc_gateways .default input,table.wc_gateways .radio input,table.wc_gateways .status input,table.wc_shipping .default input,table.wc_shipping .radio input,table.wc_shipping .status input{margin:0}table.wc_emails th.sort,table.wc_gateways th.sort,table.wc_shipping th.sort{width:28px;padding:0}table.wc_emails td.sort,table.wc_gateways td.sort,table.wc_shipping td.sort{padding:0 7px;cursor:move;font-size:15px;text-align:center;vertical-align:middle}table.wc_emails td.sort:before,table.wc_gateways td.sort:before,table.wc_shipping td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_emails .wc-email-settings-table-name span,table.wc_gateways .wc-email-settings-table-name span,table.wc_shipping .wc-email-settings-table-name span{font-weight:400;color:#999;margin:0 0 0 4px!important}table.wc_emails .wc-email-settings-table-status,table.wc_gateways .wc-email-settings-table-status,table.wc_shipping .wc-email-settings-table-status{text-align:center;width:1em}table.wc_emails .wc-email-settings-table-status .tips,table.wc_gateways .wc-email-settings-table-status .tips,table.wc_shipping .wc-email-settings-table-status .tips{margin:0 auto}table.wc_emails .wc-email-settings-table-actions a,table.wc_gateways .wc-email-settings-table-actions a,table.wc_shipping .wc-email-settings-table-actions a{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}table.wc_emails .wc-email-settings-table-actions a:after,table.wc_gateways .wc-email-settings-table-actions a:after,table.wc_shipping .wc-email-settings-table-actions a:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}table.wc-shipping-classes td,table.wc-shipping-classes th,table.wc-shipping-zone-methods td,table.wc-shipping-zone-methods th,table.wc-shipping-zones td,table.wc-shipping-zones th{vertical-align:top;line-height:24px;padding:1em;font-size:14px;background:#fff}table.wc-shipping-classes td li,table.wc-shipping-classes th li,table.wc-shipping-zone-methods td li,table.wc-shipping-zone-methods th li,table.wc-shipping-zones td li,table.wc-shipping-zones th li{line-height:24px;font-size:14px}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state,table.wc-shipping-classes td.wc-shipping-zones-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state,table.wc-shipping-zones td.wc-shipping-zones-blank-state{background:#F7F1F6!important;overflow:hidden;position:relative;padding:7.5em 7.5%;border-bottom:2px solid #EEE2EC}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zones td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state p{color:#a46497;font-size:1.5em;line-height:1.5em;margin:0 0 1em;position:relative;z-index:1;text-shadow:1px 1px 1px #fff}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state p.main{font-size:2em}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state li{margin-left:1em;list-style:circle inside}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-classes td.wc-shipping-zones-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state:before,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zones td.wc-shipping-zones-blank-state:before{content:"\e01b";font-family:WooCommerce;text-align:center;line-height:1;color:#EEE2EC;display:block;width:1em;font-size:40em;top:50%;right:-3.75%;margin-top:-.1875em;position:absolute}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-classes td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zones-blank-state .button-primary{background-color:#804877;border-color:#804877;-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);margin:0;opacity:1;text-shadow:0 -1px 1px #8a4f7f,1px 0 1px #8a4f7f,0 1px 1px #8a4f7f,-1px 0 1px #8a4f7f;font-size:1.5em;padding:.75em 1em;height:auto;position:relative;z-index:1}table.wc-shipping-classes .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-classes .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-classes tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-classes tr.odd td,table.wc-shipping-zone-methods .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tr.odd td,table.wc-shipping-zones .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zones .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zones tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zones tr.odd td{background:#f9f9f9}table.wc-shipping-classes p,table.wc-shipping-classes ul,table.wc-shipping-zone-methods p,table.wc-shipping-zone-methods ul,table.wc-shipping-zones p,table.wc-shipping-zones ul{margin:0}table.wc-shipping-classes td.wc-shipping-zone-method-sort,table.wc-shipping-classes td.wc-shipping-zone-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-sort,table.wc-shipping-zones td.wc-shipping-zone-method-sort,table.wc-shipping-zones td.wc-shipping-zone-sort{cursor:move;font-size:15px;text-align:center}table.wc-shipping-classes td.wc-shipping-zone-method-sort:before,table.wc-shipping-classes td.wc-shipping-zone-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:before,table.wc-shipping-zones td.wc-shipping-zone-sort:before{content:"\f333";font-family:Dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-classes td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-sort:hover:before{color:#333}table.wc-shipping-classes td.wc-shipping-zone-worldwide,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide,table.wc-shipping-zones td.wc-shipping-zone-worldwide{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-worldwide:before,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide:before,table.wc-shipping-zones td.wc-shipping-zone-worldwide:before{content:"\f319";font-family:dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes .wc-shipping-zone-methods,table.wc-shipping-classes .wc-shipping-zone-name,table.wc-shipping-zone-methods .wc-shipping-zone-methods,table.wc-shipping-zone-methods .wc-shipping-zone-name,table.wc-shipping-zones .wc-shipping-zone-methods,table.wc-shipping-zones .wc-shipping-zone-name{width:25%}table.wc-shipping-classes .wc-shipping-class-description input,table.wc-shipping-classes .wc-shipping-class-description select,table.wc-shipping-classes .wc-shipping-class-description textarea,table.wc-shipping-classes .wc-shipping-class-name input,table.wc-shipping-classes .wc-shipping-class-name select,table.wc-shipping-classes .wc-shipping-class-name textarea,table.wc-shipping-classes .wc-shipping-class-slug input,table.wc-shipping-classes .wc-shipping-class-slug select,table.wc-shipping-classes .wc-shipping-class-slug textarea,table.wc-shipping-classes .wc-shipping-zone-name input,table.wc-shipping-classes .wc-shipping-zone-name select,table.wc-shipping-classes .wc-shipping-zone-name textarea,table.wc-shipping-classes .wc-shipping-zone-region input,table.wc-shipping-classes .wc-shipping-zone-region select,table.wc-shipping-classes .wc-shipping-zone-region textarea,table.wc-shipping-zone-methods .wc-shipping-class-description input,table.wc-shipping-zone-methods .wc-shipping-class-description select,table.wc-shipping-zone-methods .wc-shipping-class-description textarea,table.wc-shipping-zone-methods .wc-shipping-class-name input,table.wc-shipping-zone-methods .wc-shipping-class-name select,table.wc-shipping-zone-methods .wc-shipping-class-name textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug input,table.wc-shipping-zone-methods .wc-shipping-class-slug select,table.wc-shipping-zone-methods .wc-shipping-class-slug textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name input,table.wc-shipping-zone-methods .wc-shipping-zone-name select,table.wc-shipping-zone-methods .wc-shipping-zone-name textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region input,table.wc-shipping-zone-methods .wc-shipping-zone-region select,table.wc-shipping-zone-methods .wc-shipping-zone-region textarea,table.wc-shipping-zones .wc-shipping-class-description input,table.wc-shipping-zones .wc-shipping-class-description select,table.wc-shipping-zones .wc-shipping-class-description textarea,table.wc-shipping-zones .wc-shipping-class-name input,table.wc-shipping-zones .wc-shipping-class-name select,table.wc-shipping-zones .wc-shipping-class-name textarea,table.wc-shipping-zones .wc-shipping-class-slug input,table.wc-shipping-zones .wc-shipping-class-slug select,table.wc-shipping-zones .wc-shipping-class-slug textarea,table.wc-shipping-zones .wc-shipping-zone-name input,table.wc-shipping-zones .wc-shipping-zone-name select,table.wc-shipping-zones .wc-shipping-zone-name textarea,table.wc-shipping-zones .wc-shipping-zone-region input,table.wc-shipping-zones .wc-shipping-zone-region select,table.wc-shipping-zones .wc-shipping-zone-region textarea{width:100%}table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-zone-delete{color:red}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle{float:right;margin:0;font-size:.9em;text-decoration:underline}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes{display:none}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea{margin-top:1em}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes .description{font-size:.9em;color:#999}table.wc-shipping-classes .wc-shipping-class-count,table.wc-shipping-zone-methods .wc-shipping-class-count,table.wc-shipping-zones .wc-shipping-class-count{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-methods,table.wc-shipping-zone-methods td.wc-shipping-zone-methods,table.wc-shipping-zones td.wc-shipping-zone-methods{color:#999}table.wc-shipping-classes td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .method_disabled{text-decoration:line-through}table.wc-shipping-classes td.wc-shipping-zone-methods ul,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul,table.wc-shipping-zones td.wc-shipping-zone-methods ul{color:#999;position:relative;padding-right:32px}table.wc-shipping-classes td.wc-shipping-zone-methods ul li,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li,table.wc-shipping-zones td.wc-shipping-zone-methods ul li{display:inline;margin:0}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:before{content:", "}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-classes td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:nth-child(2):before{content:""}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child{display:block}table.wc-shipping-classes td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zones td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row{position:absolute;right:0;top:0}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method{display:block;width:24px;padding:24px 0 0;height:0;overflow:hidden;cursor:pointer}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method:before{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;font-family:Dashicons;content:"\f502";color:#999;vertical-align:middle;line-height:24px;font-size:16px;margin:0}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled:before{line-height:inherit}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled{margin-top:1px;display:inline-block}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled{cursor:not-allowed}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled:before{color:#ccc}table.wc-shipping-classes .wc-shipping-zone-method-title,table.wc-shipping-zone-methods .wc-shipping-zone-method-title,table.wc-shipping-zones .wc-shipping-zone-method-title{width:33%}table.wc-shipping-classes .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zone-methods .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zones .wc-shipping-zone-method-title .wc-shipping-zone-method-delete{color:red}table.wc-shipping-classes .wc-shipping-zone-method-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled{text-align:center}table.wc-shipping-classes tfoot input,table.wc-shipping-classes tfoot select,table.wc-shipping-zone-methods tfoot input,table.wc-shipping-zone-methods tfoot select,table.wc-shipping-zones tfoot input,table.wc-shipping-zones tfoot select{vertical-align:middle!important}table.wc-shipping-classes tfoot .button-secondary,table.wc-shipping-zone-methods tfoot .button-secondary,table.wc-shipping-zones tfoot .button-secondary{float:right}table.wc-shipping-classes .editing .wc-shipping-zone-edit,table.wc-shipping-classes .editing .wc-shipping-zone-view,table.wc-shipping-zone-methods .editing .wc-shipping-zone-edit,table.wc-shipping-zone-methods .editing .wc-shipping-zone-view,table.wc-shipping-zones .editing .wc-shipping-zone-edit,table.wc-shipping-zones .editing .wc-shipping-zone-view{display:none}.wc-modal-shipping-method-settings{background:#f8f8f8;padding:1em!important}.wc-modal-shipping-method-settings form .form-table{width:100%;background:#fff;margin:0 0 1.5em}.wc-modal-shipping-method-settings form .form-table tr th{width:30%;position:relative}.wc-modal-shipping-method-settings form .form-table tr th .woocommerce-help-tip{float:right;margin:-8px -.5em 0 0;vertical-align:middle;right:0;top:50%;position:absolute}.wc-modal-shipping-method-settings form .form-table tr td input,.wc-modal-shipping-method-settings form .form-table tr td select,.wc-modal-shipping-method-settings form .form-table tr td textarea{width:50%;min-width:250px}.wc-modal-shipping-method-settings form .form-table tr td input[type=checkbox]{width:auto;min-width:16px}.wc-modal-shipping-method-settings form .form-table tr td,.wc-modal-shipping-method-settings form .form-table tr th{vertical-align:middle;margin:0;line-height:24px;padding:1em;border-bottom:1px solid #f8f8f8}.wc-modal-shipping-method-settings form .form-table:last-of-type{margin-bottom:0}.wc-backbone-modal .wc-shipping-zone-method-selector p{margin-top:0}.wc-backbone-modal .wc-shipping-zone-method-selector .wc-shipping-zone-method-description{margin:.75em 1px 0;line-height:1.5em;color:#999;font-style:italic}.wc-backbone-modal .wc-shipping-zone-method-selector select{width:100%;cursor:pointer}img.help_tip{margin:0 0 0 9px;vertical-align:middle}.postbox img.help_tip{margin-top:0}.postbox .woocommerce-help-tip{margin:0 0 0 9px}.status-disabled,.status-enabled,.status-manual{font-size:1.4em;display:block;text-indent:-9999px;position:relative;height:1em;width:1em}.status-disabled:before,.status-enabled:before,.status-manual:before{font-family:WooCommerce;line-height:1;margin:0;position:absolute;width:100%;height:100%;text-indent:0;top:0;font-variant:normal;-webkit-font-smoothing:antialiased;font-weight:400;text-align:center;left:0;speak:none;text-transform:none}.status-manual:before{content:"";color:#999}.status-enabled:before{content:"";color:#a46497}.status-disabled:before{content:"";color:#ccc}.woocommerce h2.woo-nav-tab-wrapper{margin-bottom:1em}.woocommerce nav.woo-nav-tab-wrapper{margin:1.5em 0 1em;border-bottom:1px solid #ccc}.woocommerce .subsubsub{margin:-8px 0 0}.woocommerce .wc-admin-breadcrumb{margin-left:.5em}.woocommerce .wc-admin-breadcrumb a{color:#a46497}.woocommerce #template div{margin:0}.woocommerce #template div p .button{float:right;margin-left:10px;margin-top:-4px}.woocommerce #template div .editor textarea{margin-bottom:8px}.woocommerce textarea[disabled=disabled]{background:#DFDFDF!important}.woocommerce table.form-table{margin:0;position:relative}.woocommerce table.form-table .forminp-radio ul{margin:0}.woocommerce table.form-table .forminp-radio ul li{line-height:1.4em}.woocommerce table.form-table textarea.input-text{height:100%;min-width:150px;display:block}.woocommerce table.form-table input.regular-input{width:25em}.woocommerce table.form-table textarea.wide-input{width:100%}.woocommerce table.form-table .woocommerce-help-tip,.woocommerce table.form-table img.help_tip{padding:0;margin:-4px 0 0 5px;vertical-align:middle;cursor:help;line-height:1}.woocommerce table.form-table span.help_tip{cursor:help;color:#2ea2cc}.woocommerce table.form-table th{position:relative;padding-right:24px}.woocommerce table.form-table .select2-container{display:block;max-width:350px;vertical-align:top;margin-bottom:3px}.woocommerce table.form-table table.widefat th{padding-right:inherit}.woocommerce table.form-table th .woocommerce-help-tip,.woocommerce table.form-table th img.help_tip{margin:0 -24px 0 0;float:right}.woocommerce table.form-table .wp-list-table .woocommerce-help-tip{float:none}.woocommerce table.form-table fieldset{margin-top:4px}.woocommerce table.form-table fieldset .woocommerce-help-tip,.woocommerce table.form-table fieldset img.help_tip{margin:-3px 0 0 5px}.woocommerce table.form-table fieldset p.description{margin-bottom:8px}.woocommerce table.form-table fieldset:first-child{margin-top:0}.woocommerce table.form-table .iris-picker{z-index:100;display:none;position:absolute;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,.2)}.woocommerce table.form-table .iris-picker .ui-slider{border:0!important;margin:0!important;width:auto!important;height:auto!important;background:none!important}.woocommerce table.form-table .iris-picker .ui-slider .ui-slider-handle{margin-bottom:0!important}.woocommerce table.form-table .colorpickpreview{padding:3px 3px 3px 20px;border:1px solid #ddd;border-right:0}.woocommerce table.form-table .colorpick{border-left:0}.woocommerce table.form-table .image_width_settings{vertical-align:middle}.woocommerce table.form-table .image_width_settings label{margin-left:10px}.woocommerce table.form-table .wc_emails_wrapper{padding:0 15px 10px 0}.woocommerce #tabs-wrap table a.remove{margin-left:4px}.woocommerce #tabs-wrap table p{margin:0 0 4px!important;overflow:hidden;zoom:1}.woocommerce #tabs-wrap table p a.add{float:left}#wp-excerpt-editor-container{background:#fff}#product_variation-parent #parent_id{width:100%}#postimagediv img{border:1px solid #d5d5d5;max-width:100%}#woocommerce-product-images .inside{margin:0;padding:0}#woocommerce-product-images .inside .add_product_images{padding:0 12px 12px}#woocommerce-product-images .inside #product_images_container{padding:0 0 0 9px}#woocommerce-product-images .inside #product_images_container ul{margin:0;padding:0}#woocommerce-product-images .inside #product_images_container ul:after,#woocommerce-product-images .inside #product_images_container ul:before{content:" ";display:table}#woocommerce-product-images .inside #product_images_container ul:after{clear:both}#woocommerce-product-images .inside #product_images_container ul li.add,#woocommerce-product-images .inside #product_images_container ul li.image,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{width:80px;float:left;cursor:move;border:1px solid #d5d5d5;margin:9px 9px 0 0;background:#f7f7f7;border-radius:2px;position:relative;box-sizing:border-box}#woocommerce-product-images .inside #product_images_container ul li.add img,#woocommerce-product-images .inside #product_images_container ul li.image img,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder img{width:100%;height:auto;display:block}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{border:3px dashed #ddd;position:relative}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-size:2.618em;line-height:72px;color:#ddd}#woocommerce-product-images .inside #product_images_container ul ul.actions{position:absolute;top:-8px;right:-8px;padding:2px;display:none}#woocommerce-product-images .inside #product_images_container ul ul.actions li{float:right;margin:0 0 0 2px}#woocommerce-product-images .inside #product_images_container ul ul.actions li a{width:1em;margin:0;height:0;display:block;overflow:hidden}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.tips{cursor:pointer}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.4em}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:hover:before{color:#a00}#woocommerce-product-images .inside #product_images_container ul li:hover ul.actions{display:block}#woocommerce-product-data .hndle{padding:10px}#woocommerce-product-data .hndle span{display:block;vertical-align:middle;line-height:24px}#woocommerce-product-data .hndle span span{display:inline;line-height:inherit;vertical-align:baseline}#woocommerce-product-data .hndle label{padding-right:1em;font-size:12px;vertical-align:baseline}#woocommerce-product-data .hndle label:first-child{margin-right:1em;border-right:1px solid #dfdfdf}#woocommerce-product-data .hndle input,#woocommerce-product-data .hndle select{margin:-3px 0 0 .5em;vertical-align:middle}#woocommerce-product-data>.handlediv{margin-top:4px}#woocommerce-product-data .wrap{margin:0}#woocommerce-coupon-description{padding:3px 8px;font-size:1.7em;line-height:1.42em;height:auto;width:100%;outline:0;margin:10px 0;display:block}#woocommerce-coupon-description::-webkit-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description::-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-ms-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap{background:#fff}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{float:left;width:80%}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-product-data .woocommerce_options_panel .wc-radios{display:block;float:left;margin:0}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-product-data .woocommerce_options_panel .wc-radios li{display:block;padding:0 0 10px}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li input,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-product-data .woocommerce_options_panel .wc-radios li input{width:auto}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap,.woocommerce .panel-wrap{overflow:hidden}#woocommerce-coupon-data ul.wc-tabs,#woocommerce-product-data ul.wc-tabs,.woocommerce ul.wc-tabs{margin:0;width:20%;float:left;line-height:1em;padding:0 0 10px;position:relative;background-color:#fafafa;border-right:1px solid #eee;box-sizing:border-box}#woocommerce-coupon-data ul.wc-tabs:after,#woocommerce-product-data ul.wc-tabs:after,.woocommerce ul.wc-tabs:after{content:"";display:block;width:100%;height:9999em;position:absolute;bottom:-9999em;left:0;background-color:#fafafa;border-right:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li,#woocommerce-product-data ul.wc-tabs li,.woocommerce ul.wc-tabs li{margin:0;padding:0;display:block;position:relative}#woocommerce-coupon-data ul.wc-tabs li a,#woocommerce-product-data ul.wc-tabs li a,.woocommerce ul.wc-tabs li a{margin:0;padding:10px;display:block;box-shadow:none;text-decoration:none;line-height:20px!important;border-bottom:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li a:before,#woocommerce-product-data ul.wc-tabs li a:before,.woocommerce ul.wc-tabs li a:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}#woocommerce-coupon-data ul.wc-tabs li.general_options a:before,#woocommerce-product-data ul.wc-tabs li.general_options a:before,.woocommerce ul.wc-tabs li.general_options a:before{content:"\f107"}#woocommerce-coupon-data ul.wc-tabs li.inventory_options a:before,#woocommerce-product-data ul.wc-tabs li.inventory_options a:before,.woocommerce ul.wc-tabs li.inventory_options a:before{content:"\f481"}#woocommerce-coupon-data ul.wc-tabs li.shipping_options a:before,#woocommerce-product-data ul.wc-tabs li.shipping_options a:before,.woocommerce ul.wc-tabs li.shipping_options a:before{font-family:WooCommerce;content:"\e01a"}#woocommerce-coupon-data ul.wc-tabs li.linked_product_options a:before,#woocommerce-product-data ul.wc-tabs li.linked_product_options a:before,.woocommerce ul.wc-tabs li.linked_product_options a:before{content:"\f103"}#woocommerce-coupon-data ul.wc-tabs li.attribute_options a:before,#woocommerce-product-data ul.wc-tabs li.attribute_options a:before,.woocommerce ul.wc-tabs li.attribute_options a:before{content:"\f175"}#woocommerce-coupon-data ul.wc-tabs li.advanced_options a:before,#woocommerce-product-data ul.wc-tabs li.advanced_options a:before,.woocommerce ul.wc-tabs li.advanced_options a:before{font-family:Dashicons;content:"\f111"}#woocommerce-coupon-data ul.wc-tabs li.variations_options a:before,#woocommerce-product-data ul.wc-tabs li.variations_options a:before,.woocommerce ul.wc-tabs li.variations_options a:before{content:"\f509"}#woocommerce-coupon-data ul.wc-tabs li.usage_restriction_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_restriction_options a:before,.woocommerce ul.wc-tabs li.usage_restriction_options a:before{font-family:WooCommerce;content:"\e602"}#woocommerce-coupon-data ul.wc-tabs li.usage_limit_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_limit_options a:before,.woocommerce ul.wc-tabs li.usage_limit_options a:before{font-family:WooCommerce;content:"\e601"}#woocommerce-coupon-data ul.wc-tabs li.general_coupon_data a:before,#woocommerce-product-data ul.wc-tabs li.general_coupon_data a:before,.woocommerce ul.wc-tabs li.general_coupon_data a:before{font-family:WooCommerce;content:"\e600"}#woocommerce-coupon-data ul.wc-tabs li.active a,#woocommerce-product-data ul.wc-tabs li.active a,.woocommerce ul.wc-tabs li.active a{color:#555;position:relative;background-color:#eee}.woocommerce_page_wc-settings .shippingrows th.check-column{padding-top:20px}.woocommerce_page_wc-settings .shippingrows tfoot th{padding-left:10px}.woocommerce_page_wc-settings .shippingrows .add.button:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}.woocommerce_page_wc-settings h3.wc-settings-sub-title{font-size:1.2em}#woocommerce-coupon-data .inside,#woocommerce-order-data .inside,#woocommerce-order-downloads .inside,#woocommerce-product-data .inside,#woocommerce-product-type-options .inside{margin:0;padding:0}.panel,.woocommerce_options_panel{padding:9px;color:#555}.panel .form-field .woocommerce-help-tip,.woocommerce_options_panel .form-field .woocommerce-help-tip{font-size:1.4em}.panel,.woocommerce_page_settings .woocommerce_options_panel{padding:0}#woocommerce-product-specs .inside,#woocommerce-product-type-options .panel{margin:0;padding:9px}#woocommerce-product-type-options .panel p,.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p{margin:0 0 9px;font-size:12px;padding:5px 9px;line-height:24px}#woocommerce-product-type-options .panel p:after,.woocommerce_options_panel fieldset.form-field:after,.woocommerce_options_panel p:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce_options_panel .checkbox,.woocommerce_variable_attributes .checkbox{width:auto;margin:3px 0;vertical-align:middle}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{width:100%;padding:0!important}.woocommerce_options_panel .downloadable_files table th,.woocommerce_variations .downloadable_files table th{padding:7px 0 7px 7px!important}.woocommerce_options_panel .downloadable_files table th.sort,.woocommerce_variations .downloadable_files table th.sort{width:17px;padding:7px!important}.woocommerce_options_panel .downloadable_files table th .woocommerce-help-tip,.woocommerce_variations .downloadable_files table th .woocommerce-help-tip{font-size:1.1em;margin-left:0}.woocommerce_options_panel .downloadable_files table td,.woocommerce_variations .downloadable_files table td{vertical-align:middle!important;padding:4px 0 4px 7px!important;position:relative}.woocommerce_options_panel .downloadable_files table td:last-child,.woocommerce_variations .downloadable_files table td:last-child{padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td input.input_text,.woocommerce_variations .downloadable_files table td input.input_text{width:100%;float:none;min-width:0;margin:1px 0}.woocommerce_options_panel .downloadable_files table td .upload_file_button,.woocommerce_variations .downloadable_files table td .upload_file_button{width:auto;float:right;cursor:pointer}.woocommerce_options_panel .downloadable_files table td .delete,.woocommerce_variations .downloadable_files table td .delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.2em}.woocommerce_options_panel .downloadable_files table td .delete:before,.woocommerce_variations .downloadable_files table td .delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}.woocommerce_options_panel .downloadable_files table td .delete:hover:before,.woocommerce_variations .downloadable_files table td .delete:hover:before{color:#a00}.woocommerce_options_panel .downloadable_files table td.sort,.woocommerce_variations .downloadable_files table td.sort{width:17px;cursor:move;font-size:15px;text-align:center;background:#f9f9f9;padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td.sort:before,.woocommerce_variations .downloadable_files table td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_options_panel .downloadable_files table td.sort:hover:before,.woocommerce_variations .downloadable_files table td.sort:hover:before{color:#333}.woocommerce_variation h3 .sort{width:17px;height:26px;cursor:move;float:right;font-size:15px;font-weight:400;margin-right:.5em;visibility:hidden;text-align:center;vertical-align:middle}.woocommerce_variation h3 .sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:28px;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_variation h3 .sort:hover:before{color:#777}.woocommerce_variation h3:hover .sort,.woocommerce_variation.ui-sortable-helper .sort{visibility:visible}.woocommerce_options_panel{min-height:175px;box-sizing:border-box}.woocommerce_options_panel .downloadable_files{padding:0 9px 0 162px;position:relative;margin:9px 0}.woocommerce_options_panel .downloadable_files label{position:absolute;left:0;margin:0 0 0 12px;line-height:24px}.woocommerce_options_panel p{margin:9px 0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px 5px 162px!important}.woocommerce_options_panel .sale_price_dates_fields .short:first-of-type{margin-bottom:1em}.woocommerce_options_panel .sale_price_dates_fields .short:nth-of-type(2){clear:left}.woocommerce_options_panel label,.woocommerce_options_panel legend{float:left;width:150px;padding:0;margin:0 0 0 -150px}.woocommerce_options_panel label .req,.woocommerce_options_panel legend .req{font-weight:700;font-style:normal;color:#a00}.woocommerce_options_panel .description{padding:0;margin:0 0 0 7px;clear:none;display:inline}.woocommerce_options_panel .description-block{margin-left:0;display:block}.woocommerce_options_panel input,.woocommerce_options_panel select,.woocommerce_options_panel textarea{margin:0}.woocommerce_options_panel textarea{height:3.5em;line-height:1.5em;vertical-align:top}.woocommerce_options_panel input[type=text],.woocommerce_options_panel input[type=number],.woocommerce_options_panel input[type=email],.woocommerce_options_panel input[type=password]{width:50%;float:left}.woocommerce_options_panel input.button{width:auto;margin-left:8px}.woocommerce_options_panel select{float:left}.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:50%}.woocommerce_options_panel .sized{width:auto!important;margin-right:6px}.woocommerce_options_panel .options_group{border-top:1px solid #fff;border-bottom:1px solid #eee}.woocommerce_options_panel .options_group:first-child{border-top:0}.woocommerce_options_panel .options_group:last-child{border-bottom:0}.woocommerce_options_panel .options_group fieldset{margin:9px 0;font-size:12px;padding:5px 9px;line-height:24px}.woocommerce_options_panel .options_group fieldset label{width:auto;float:none}.woocommerce_options_panel .options_group fieldset ul{float:left;width:50%;margin:0;padding:0}.woocommerce_options_panel .options_group fieldset ul li{margin:0;width:auto}.woocommerce_options_panel .options_group fieldset ul li input{width:auto;float:none;margin-right:4px}.woocommerce_options_panel .options_group fieldset ul.wc-radios label{margin-left:0}.woocommerce_options_panel .dimensions_field .wrap{display:block;width:50%}.woocommerce_options_panel .dimensions_field .wrap input{width:30.75%;margin-right:3.8%}.woocommerce_options_panel .dimensions_field .wrap .last{margin-right:0}.woocommerce_options_panel.padded{padding:1em}#woocommerce-product-data input.dp-applied,.woocommerce_options_panel .select2-container{float:left}#grouped_product_options,#simple_product_options,#virtual_product_options{padding:12px;font-style:italic;color:#666}.wc-metaboxes-wrapper .toolbar{margin:0!important;border-top:1px solid #fff;border-bottom:1px solid #eee;padding:9px 12px!important}.wc-metaboxes-wrapper .toolbar:first-child{border-top:0}.wc-metaboxes-wrapper .toolbar:last-child{border-bottom:0}.wc-metaboxes-wrapper .toolbar .add_variation{float:right;margin-left:5px}.wc-metaboxes-wrapper .toolbar .cancel-variation-changes,.wc-metaboxes-wrapper .toolbar .save-variation-changes{float:left;margin-right:5px}.wc-metaboxes-wrapper p.toolbar{overflow:hidden;zoom:1}.wc-metaboxes-wrapper .expand-close{margin-right:2px;color:#777;font-size:12px;font-style:italic}.wc-metaboxes-wrapper .expand-close a{background:0 0;padding:0;font-size:12px;text-decoration:none}.wc-metaboxes-wrapper#product_attributes .expand-close{float:right;line-height:28px}.wc-metaboxes-wrapper .fr,.wc-metaboxes-wrapper button.add_variable_attribute{float:right;margin:0 0 0 6px}.wc-metaboxes-wrapper .wc-metaboxes{border-bottom:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox-sortable-placeholder{border-color:#bbb;background-color:#f5f5f5;margin-bottom:9px;border-width:1px;border-style:dashed}.wc-metaboxes-wrapper .wc-metabox{background:#fff;border-bottom:1px solid #eee;margin:0!important}.wc-metaboxes-wrapper .wc-metabox select{font-weight:400}.wc-metaboxes-wrapper .wc-metabox:last-of-type{border-bottom:0}.wc-metaboxes-wrapper .wc-metabox .handlediv{width:27px}.wc-metaboxes-wrapper .wc-metabox .handlediv:before{content:"\f142"!important;cursor:pointer;display:inline-block;font:400 20px/1 Dashicons;line-height:.5!important;padding:8px 10px;position:relative;right:12px;top:0}.wc-metaboxes-wrapper .wc-metabox.closed{border-radius:3px}.wc-metaboxes-wrapper .wc-metabox.closed .handlediv:before{content:"\f140"!important}.wc-metaboxes-wrapper .wc-metabox.closed h3{border:0}.wc-metaboxes-wrapper .wc-metabox h3{margin:0!important;padding:.75em .75em .75em 1em!important;font-size:1em!important;overflow:hidden;zoom:1;cursor:move}.wc-metaboxes-wrapper .wc-metabox h3 a.delete,.wc-metaboxes-wrapper .wc-metabox h3 button{float:right}.wc-metaboxes-wrapper .wc-metabox h3 a.delete{color:red;font-weight:400;line-height:26px;text-decoration:none;position:relative;visibility:hidden}.wc-metaboxes-wrapper .wc-metabox h3 strong{line-height:26px;font-weight:700}.wc-metaboxes-wrapper .wc-metabox h3 select{font-family:sans-serif;max-width:20%;margin:.25em .25em .25em 0}.wc-metaboxes-wrapper .wc-metabox h3 .handlediv{background-position:6px 5px!important;visibility:hidden;height:26px}.wc-metaboxes-wrapper .wc-metabox h3.fixed{cursor:pointer!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3{cursor:pointer;padding:.5em .75em .5em 1em!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .handlediv,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .sort,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 a.delete{margin-top:.25em}.wc-metaboxes-wrapper .wc-metabox h3:hover .handlediv,.wc-metaboxes-wrapper .wc-metabox h3:hover a.delete,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper .handlediv,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper a.delete{visibility:visible}.wc-metaboxes-wrapper .wc-metabox table{width:100%;position:relative;background-color:#fdfdfd;padding:1em;border-top:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox table td{text-align:left;padding:0 6px 1em 0;vertical-align:top;border:0}.wc-metaboxes-wrapper .wc-metabox table td label{text-align:left;display:block;line-height:21px}.wc-metaboxes-wrapper .wc-metabox table td input{float:left;min-width:200px}.wc-metaboxes-wrapper .wc-metabox table td input,.wc-metaboxes-wrapper .wc-metabox table td textarea{width:100%;margin:0;display:block;font-size:14px;padding:4px;color:#555}.wc-metaboxes-wrapper .wc-metabox table td .select2-container,.wc-metaboxes-wrapper .wc-metabox table td select{width:100%!important}.wc-metaboxes-wrapper .wc-metabox table td input.short{width:200px}.wc-metaboxes-wrapper .wc-metabox table td input.checkbox{width:16px;min-width:inherit;vertical-align:text-bottom;display:inline-block;float:none}.wc-metaboxes-wrapper .wc-metabox table td.attribute_name{width:200px}.wc-metaboxes-wrapper .wc-metabox table .minus,.wc-metaboxes-wrapper .wc-metabox table .plus{margin-top:6px}.wc-metaboxes-wrapper .wc-metabox table .fl{float:left}.wc-metaboxes-wrapper .wc-metabox table .fr{float:right}.variations-pagenav{float:right;line-height:24px}.variations-pagenav .displaying-num{color:#777;font-size:12px;font-style:italic}.variations-pagenav a{padding:0 10px 3px;background:rgba(0,0,0,.05);font-size:16px;font-weight:400;text-decoration:none}.variations-pagenav a.disabled,.variations-pagenav a.disabled:active,.variations-pagenav a.disabled:focus,.variations-pagenav a.disabled:hover{color:#A0A5AA;background:rgba(0,0,0,.05)}.variations-defaults{float:left}.variations-defaults select{margin:.25em .25em .25em 0}.woocommerce_variable_attributes{background-color:#fdfdfd;border-top:1px solid #eee}.woocommerce_variable_attributes .data{padding:1em 2em}.woocommerce_variable_attributes .data:after,.woocommerce_variable_attributes .data:before{content:" ";display:table}.woocommerce_variable_attributes .data:after{clear:both}.woocommerce_variable_attributes .upload_image_button{display:block;width:48px;height:48px;float:left;margin-right:20px;position:relative;cursor:pointer}.woocommerce_variable_attributes .upload_image_button img{width:100%;height:auto;display:none}.woocommerce_variable_attributes .upload_image_button:before{content:"\f128";font-family:Dashicons;position:absolute;top:0;left:0;right:0;bottom:0;text-align:center;line-height:48px;font-size:48px;font-weight:400;-webkit-font-smoothing:antialiased}.woocommerce_variable_attributes .upload_image_button.remove img{display:block}.woocommerce_variable_attributes .upload_image_button.remove:before{content:"\f335";display:none}.woocommerce_variable_attributes .upload_image_button.remove:hover:before{display:block}.woocommerce_variable_attributes .options{border:1px solid #eee;border-width:1px 0;padding:.25em 0}.woocommerce_variable_attributes .options label{display:inline-block;padding:4px 1em 2px 0}.woocommerce_variable_attributes .options input[type=checkbox]{margin-top:5px;margin-right:3px}.form-row label{display:block}.form-row input[type=number],.form-row input[type=text],.form-row select{width:100%}.form-row.dimensions_field input{width:25%;float:left;margin-right:1%}.form-row.dimensions_field input:last-of-type{margin-right:0}.form-row-first,.form-row-last{width:48%;float:right}.form-row-first{clear:both;float:left}.form-row-full{clear:both}.tips{cursor:help;text-decoration:none}img.tips{padding:5px 0 0}#tiptip_holder{display:none;position:absolute;top:0;left:0;z-index:9999999}#tiptip_holder.tip_top{padding-bottom:5px}#tiptip_holder.tip_top #tiptip_arrow_inner{margin-top:-7px;margin-left:-6px;border-top-color:#333}#tiptip_holder.tip_bottom{padding-top:5px}#tiptip_holder.tip_bottom #tiptip_arrow_inner{margin-top:-5px;margin-left:-6px;border-bottom-color:#333}#tiptip_holder.tip_right{padding-left:5px}#tiptip_holder.tip_right #tiptip_arrow_inner{margin-top:-6px;margin-left:-5px;border-right-color:#333}#tiptip_holder.tip_left{padding-right:5px}#tiptip_holder.tip_left #tiptip_arrow_inner{margin-top:-6px;margin-left:-7px;border-left-color:#333}#tiptip_content,.chart-tooltip,.wc_error_tip{color:#fff;font-size:.8em;max-width:150px;background:#333;text-align:center;border-radius:3px;padding:.618em 1em;box-shadow:0 1px 3px rgba(0,0,0,.2)}#tiptip_content code,.chart-tooltip code,.wc_error_tip code{padding:1px;background:#888}#tiptip_arrow,#tiptip_arrow_inner{position:absolute;border-color:transparent;border-style:solid;border-width:6px;height:0;width:0}.wc_error_tip{max-width:20em;line-height:1.8em;position:absolute;white-space:normal;background:#d82223;margin:1.5em 1px 0 -1em;z-index:9999999}.wc_error_tip:after{content:"";display:block;border:8px solid #d82223;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-3px;left:50%;margin:-1em 0 0 -3px}img.ui-datepicker-trigger{vertical-align:middle;margin-top:-1px;cursor:pointer}.wc-metabox-content img.ui-datepicker-trigger,.woocommerce_options_panel img.ui-datepicker-trigger{float:left;margin-right:8px;margin-top:4px;margin-left:4px}#ui-datepicker-div{display:none}.woocommerce-reports-wide.woocommerce-reports-wrap,.woocommerce-reports-wrap.woocommerce-reports-wrap{margin-left:300px;padding-top:18px}.woocommerce-reports-wide.halved,.woocommerce-reports-wrap.halved{margin:0;overflow:hidden;zoom:1}.woocommerce-reports-wide .widefat td,.woocommerce-reports-wrap .widefat td{vertical-align:top;padding:7px}.woocommerce-reports-wide .widefat td .description,.woocommerce-reports-wrap .widefat td .description{margin:4px 0 0}.woocommerce-reports-wide .postbox:after,.woocommerce-reports-wrap .postbox:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox h3,.woocommerce-reports-wrap .postbox h3{cursor:default!important}.woocommerce-reports-wide .postbox .inside,.woocommerce-reports-wrap .postbox .inside{padding:10px;margin:0!important}.woocommerce-reports-wide .postbox div.stats_range,.woocommerce-reports-wide .postbox h3.stats_range,.woocommerce-reports-wrap .postbox div.stats_range,.woocommerce-reports-wrap .postbox h3.stats_range{border-bottom-color:#dfdfdf;margin:0;padding:0!important}.woocommerce-reports-wide .postbox div.stats_range .export_csv,.woocommerce-reports-wide .postbox h3.stats_range .export_csv,.woocommerce-reports-wrap .postbox div.stats_range .export_csv,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv{float:right;line-height:26px;border-left:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range .export_csv:before,.woocommerce-reports-wide .postbox h3.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox div.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;content:"";text-decoration:none;margin-right:4px}.woocommerce-reports-wide .postbox div.stats_range ul,.woocommerce-reports-wide .postbox h3.stats_range ul,.woocommerce-reports-wrap .postbox div.stats_range ul,.woocommerce-reports-wrap .postbox h3.stats_range ul{list-style:none;margin:0;padding:0;zoom:1;background:#f5f5f5;border-bottom:1px solid #ccc}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox div.stats_range ul:before,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:before,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:before,.woocommerce-reports-wrap .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:before{content:" ";display:table}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:after{clear:both}.woocommerce-reports-wide .postbox div.stats_range ul li,.woocommerce-reports-wide .postbox h3.stats_range ul li,.woocommerce-reports-wrap .postbox div.stats_range ul li,.woocommerce-reports-wrap .postbox h3.stats_range ul li{float:left;margin:0;padding:0;line-height:26px;font-weight:700;font-size:14px}.woocommerce-reports-wide .postbox div.stats_range ul li a,.woocommerce-reports-wide .postbox h3.stats_range ul li a,.woocommerce-reports-wrap .postbox div.stats_range ul li a,.woocommerce-reports-wrap .postbox h3.stats_range ul li a{border-right:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range ul li.active,.woocommerce-reports-wide .postbox h3.stats_range ul li.active,.woocommerce-reports-wrap .postbox div.stats_range ul li.active,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active{background:#fff;-webkit-box-shadow:0 4px 0 0 #fff;box-shadow:0 4px 0 0 #fff}.woocommerce-reports-wide .postbox div.stats_range ul li.active a,.woocommerce-reports-wide .postbox h3.stats_range ul li.active a,.woocommerce-reports-wrap .postbox div.stats_range ul li.active a,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active a{color:#777}.woocommerce-reports-wide .postbox div.stats_range ul li.custom,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom{padding:9px 10px;vertical-align:middle}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form{display:inline;margin:0}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form input.range_datepicker{padding:0;margin:0 10px 0 0;background:0 0;border:0;color:#777;text-align:center;-webkit-box-shadow:none;box-shadow:none}.woocommerce-reports-wide .postbox .chart-with-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar{padding:12px 12px 12px 249px;margin:0!important}.woocommerce-reports-wide .postbox .chart-with-sidebar .chart-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar .chart-sidebar{width:225px;margin-left:-237px;float:left}.woocommerce-reports-wide .postbox .chart-widgets,.woocommerce-reports-wrap .postbox .chart-widgets{margin:0;padding:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget{margin:0 0 1em;background:#fafafa;border:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4{background:#fff;border:1px solid #dfdfdf;border-left-width:0;border-right-width:0;padding:10px;margin:0;color:#2ea2cc;border-top-width:0;background-image:-webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9));background-image:-webkit-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-moz-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-o-linear-gradient(bottom,#ececec,#f9f9f9);background-image:linear-gradient(to top,#ececec,#f9f9f9)}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr.active td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr.active td{background:#f5f5f5}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4.section_title:hover,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4.section_title:hover{color:#a00}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title{cursor:pointer}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span{display:block}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin-left:.618em;content:"";text-decoration:none;float:right;font-size:.9em;line-height:1.618}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open{color:#333}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open span:after{display:none}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section{border-bottom:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section .select2-container,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section .select2-container{width:100%!important}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section:last-of-type,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section:last-of-type{border-radius:0 0 3px 3px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td{padding:7px 10px;vertical-align:top;border-top:1px solid #e5e5e5;line-height:1.4em}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.sparkline,form.report_filters div,form.report_filters input,form.report_filters label,form.report_filters p{vertical-align:middle}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr:first-child td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr:first-child td{border-top:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name{max-width:175px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name a,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name a{word-wrap:break-word}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table .wc_sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table .wc_sparkline{width:32px;height:1em;display:block;float:right}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p{margin:0;padding:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p .submit{margin-top:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget #product_ids,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget #product_ids{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_none,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_none{float:right;color:#999;margin-left:4px;margin-top:10px}.woocommerce-reports-wide .postbox .chart-legend,.woocommerce-reports-wrap .postbox .chart-legend{list-style:none;margin:0 0 1em;padding:0;border:1px solid #dfdfdf;border-right-width:0;border-bottom-width:0;background:#fff}.woocommerce-reports-wide .postbox .chart-legend li,.woocommerce-reports-wrap .postbox .chart-legend li{border-right:5px solid #aaa;color:#aaa;padding:1em;display:block;margin:0;-webkit-transition:all ease .5s;box-shadow:inset 0 -1px 0 0 #dfdfdf}.woocommerce-reports-wide .postbox .chart-legend li strong,.woocommerce-reports-wrap .postbox .chart-legend li strong{font-size:1.618em;line-height:1.2em;color:#464646;font-weight:400;display:block;font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif}.woocommerce-reports-wide .postbox .chart-legend li strong del,.woocommerce-reports-wrap .postbox .chart-legend li strong del{color:#e74c3c;font-weight:400}.woocommerce-reports-wide .postbox .chart-legend li:hover,.woocommerce-reports-wrap .postbox .chart-legend li:hover{box-shadow:inset 0 -1px 0 0 #dfdfdf,inset 300px 0 0 rgba(156,93,144,.1);border-right:5px solid #9c5d90!important;padding-left:1.5em;color:#9c5d90}.woocommerce-reports-wide .postbox .pie-chart-legend,.woocommerce-reports-wrap .postbox .pie-chart-legend{margin:12px 0 0;overflow:hidden}.woocommerce-reports-wide .postbox .pie-chart-legend li,.woocommerce-reports-wrap .postbox .pie-chart-legend li{float:left;margin:0;padding:6px 0 0;border-top:4px solid #999;text-align:center;box-sizing:border-box;width:50%}.woocommerce-reports-wide .postbox .stat,.woocommerce-reports-wrap .postbox .stat{font-size:1.5em!important;font-weight:700;text-align:center}.woocommerce-reports-wide .postbox .chart-placeholder,.woocommerce-reports-wrap .postbox .chart-placeholder{width:100%;height:650px;overflow:hidden;position:relative}.woocommerce-reports-wide .postbox .chart-prompt,.woocommerce-reports-wrap .postbox .chart-prompt{line-height:650px;margin:0;color:#999;font-size:1.2em;font-style:italic;text-align:center}.woocommerce-reports-wide .postbox .chart-container,.woocommerce-reports-wrap .postbox .chart-container{background:#fff;padding:12px;position:relative;border:1px solid #dfdfdf;border-radius:3px}.woocommerce-reports-wide .postbox .main .chart-legend,.woocommerce-reports-wrap .postbox .main .chart-legend{margin-top:12px}.woocommerce-reports-wide .postbox .main .chart-legend li,.woocommerce-reports-wrap .postbox .main .chart-legend li{border-right:0;margin:0 8px 0 0;float:left;border-top:4px solid #aaa}.woocommerce-reports-wide .woocommerce-reports-main,.woocommerce-reports-wrap .woocommerce-reports-main{float:left;min-width:100%}.woocommerce-reports-wide .woocommerce-reports-main table td,.woocommerce-reports-wrap .woocommerce-reports-main table td{padding:9px}.woocommerce-reports-wide .woocommerce-reports-sidebar,.woocommerce-reports-wrap .woocommerce-reports-sidebar{display:inline;width:281px;margin-left:-300px;clear:both;float:left}.woocommerce-reports-wide .woocommerce-reports-left,.woocommerce-reports-wrap .woocommerce-reports-left{width:49.5%;float:left}.woocommerce-reports-wide .woocommerce-reports-right,.woocommerce-reports-wrap .woocommerce-reports-right{width:49.5%;float:right}.woocommerce-reports-wide .column-wc_actions a.edit,.woocommerce-reports-wide .column-wc_actions a.view,.woocommerce-reports-wrap .column-wc_actions a.edit,.woocommerce-reports-wrap .column-wc_actions a.view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;line-height:1.85}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after{content:"\f464"}.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{content:"\f177"}.woocommerce-wide-reports-wrap{padding-bottom:11px}.woocommerce-wide-reports-wrap .widefat .export-data{float:right}.woocommerce-wide-reports-wrap .widefat td,.woocommerce-wide-reports-wrap .widefat th{vertical-align:middle;padding:7px}.chart-tooltip{position:absolute;display:none;line-height:1}table.bar_chart{width:100%}table.bar_chart thead th{text-align:left;color:#ccc;padding:6px 0}table.bar_chart tbody th{padding:6px 0;width:25%;text-align:left!important;font-weight:400!important;border-bottom:1px solid #fee}table.bar_chart tbody td{text-align:right;line-height:24px;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td span{color:#8a4b75;display:block}table.bar_chart tbody td span.alt{color:#47a03e;margin-top:6px}table.bar_chart tbody td.bars{position:relative;text-align:left;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td.bars a,table.bar_chart tbody td.bars span{text-decoration:none;clear:both;background:#8a4b75;float:left;display:block;line-height:24px;height:24px;-moz-border-radius:3px;-webkit-border-radius:3px;-o-border-radius:3px;-khtml-border-radius:3px;border-radius:3px}.post-type-product .woocommerce-BlankState-message:before,.post-type-shop_coupon .woocommerce-BlankState-message:before,.post-type-shop_order .woocommerce-BlankState-message:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}table.bar_chart tbody td.bars span.alt{clear:both;background:#47a03e}table.bar_chart tbody td.bars span.alt span{margin:0;color:#c5dec2!important;text-shadow:0 1px 0 #47a03e;background:0 0}.post-type-shop_order .woocommerce-BlankState-message:before{content:""}.post-type-shop_coupon .woocommerce-BlankState-message:before{content:""}.post-type-product .woocommerce-BlankState-message:before{content:""}.woocommerce-BlankState{text-align:center;padding:5em 0 0}.woocommerce-BlankState .woocommerce-BlankState-message{color:#aaa;margin:0 auto 1.5em;line-height:1.5em;font-size:1.2em;max-width:500px}.woocommerce-BlankState .woocommerce-BlankState-message:before{color:#ddd;text-shadow:0 -1px 1px rgba(0,0,0,.2),0 1px 0 rgba(255,255,255,.8);font-size:8em;display:block;position:relative!important;top:auto;left:auto;line-height:1em;margin:0 0 .1875em}.woocommerce-BlankState .woocommerce-BlankState-cta{font-size:1.2em;padding:.75em 1.5em;height:auto}@media only screen and (max-width:1280px){#order_data .order_data_column{width:48%}#order_data .order_data_column:first-child{width:100%}.woocommerce_options_panel .description{display:block;clear:both;margin-left:0}.woocommerce_options_panel .dimensions_field .wrap,.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:80%}.woocommerce_options_panel .downloadable_files,.woocommerce_variations .downloadable_files{padding:0;clear:both}.woocommerce_options_panel .downloadable_files label,.woocommerce_variations .downloadable_files label{position:static}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{margin:0 12px 24px;width:94%}.woocommerce_options_panel .downloadable_files table .sort,.woocommerce_variations .downloadable_files table .sort{visibility:hidden}.woocommerce_options_panel .woocommerce_variable_attributes .downloadable_files table,.woocommerce_variations .woocommerce_variable_attributes .downloadable_files table{margin:0 0 1em;width:100%}}@media only screen and (max-width:900px){#woocommerce-coupon-data ul.coupon_data_tabs,#woocommerce-product-data .wc-tabs-back,#woocommerce-product-data ul.product_data_tabs{width:10%}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{width:90%}#woocommerce-coupon-data ul.coupon_data_tabs li a,#woocommerce-product-data ul.product_data_tabs li a{position:relative;text-indent:-999px;padding:10px}#woocommerce-coupon-data ul.coupon_data_tabs li a:before,#woocommerce-product-data ul.product_data_tabs li a:before{position:absolute;top:0;right:0;bottom:0;left:0;text-indent:0;text-align:center;line-height:40px;width:100%;height:40px}}@media only screen and (max-width:782px){#wp-excerpt-media-buttons a{font-size:16px;line-height:37px;height:39px;padding:0 20px 0 15px}#wp-excerpt-editor-tools{padding-top:20px;padding-right:15px;overflow:hidden;margin-bottom:-1px}.post-type-product .wp-list-table .is-expanded td:not(.hidden),.post-type-shop_order .wp-list-table .is-expanded td:not(.hidden){overflow:visible}#woocommerce-product-data .checkbox{width:25px}.variations-pagenav{float:none;text-align:center;font-size:18px}.variations-pagenav .displaying-num{font-size:16px}.variations-pagenav a{padding:8px 20px 11px;font-size:18px}.variations-pagenav select{padding:0 20px}.variations-defaults{float:none;text-align:center;margin-top:10px}.post-type-product .wp-list-table .column-thumb{display:none;text-align:left;padding-bottom:0}.post-type-product .wp-list-table .column-thumb:before{display:none!important}.post-type-product .wp-list-table .column-thumb img{max-width:32px}.post-type-product .wp-list-table .toggle-row{top:-28px}.post-type-shop_order .wp-list-table .column-order_status{display:none;text-align:left;padding-bottom:0}.post-type-shop_order .wp-list-table .column-order_status mark{margin:0}.post-type-shop_order .wp-list-table .column-order_status:before{display:none!important}.post-type-shop_order .wp-list-table .column-customer_message,.post-type-shop_order .wp-list-table .column-order_notes{text-align:inherit}.post-type-shop_order .wp-list-table .column-order_notes .note-on{font-size:1.3em;margin:0}.post-type-shop_order .wp-list-table .toggle-row{top:-15px}}@media only screen and (max-width:500px){.woocommerce_options_panel label,.woocommerce_options_panel legend{float:none;width:auto;display:block;margin:0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px!important}}.wc-backbone-modal *{box-sizing:border-box}.wc-backbone-modal .wc-backbone-modal-content{position:fixed;background:#fff;z-index:100000;left:50%;top:50%;transform:translate(-50%,-50%);width:500px}.wc-backbone-modal .wc-backbone-modal-content article{overflow:auto}.wc-backbone-modal.wc-backbone-modal-shipping-method-settings .wc-backbone-modal-content{width:75%;min-width:500px}.wc-backbone-modal-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;min-height:360px;background:#000;opacity:.7;z-index:99900}.wc-backbone-modal-main{padding-bottom:55px}.wc-backbone-modal-main article,.wc-backbone-modal-main header{display:block;position:relative}.wc-backbone-modal-main .wc-backbone-modal-header{height:auto;background:#fcfcfc;padding:1em 1.5em;border-bottom:1px solid #ddd}.wc-backbone-modal-main .wc-backbone-modal-header h1{margin:0;font-size:18px;font-weight:700;line-height:1.5em}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link{cursor:pointer;color:#777;height:54px;width:54px;padding:0;position:absolute;top:0;right:0;text-align:center;border:0;border-left:1px solid #ddd;background-color:transparent;-webkit-transition:color .1s ease-in-out,background .1s ease-in-out;transition:color .1s ease-in-out,background .1s ease-in-out}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:before{font:400 22px/50px dashicons!important;color:#666;display:block;content:'\f335';font-weight:300}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus,.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:hover{background:#ddd;border-color:#ccc;color:#000}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus{outline:0}.wc-backbone-modal-main article{padding:1.5em}.wc-backbone-modal-main article p{margin:1.5em 0}.wc-backbone-modal-main article p:last-child,.wc-backbone-modal-main footer .inner .button{margin-bottom:0}.wc-backbone-modal-main article p:first-child{margin-top:0}.wc-backbone-modal-main article .pagination{padding:10px 0 0;text-align:center}.wc-backbone-modal-main footer{position:absolute;left:0;right:0;bottom:0;z-index:100;padding:1em 1.5em;background:#fcfcfc;border-top:1px solid #dfdfdf;box-shadow:0 -4px 4px -4px rgba(0,0,0,.1)}.wc-backbone-modal-main footer .inner{float:right;line-height:23px}.select2-drop{z-index:999999!important}.select2-container-multi .select2-choices .select2-search-field input{font-family:inherit;font-size:inherit;font-weight:inherit;padding:3px 5px}.select2-container{line-height:1.85em;font-size:14px} \ No newline at end of file diff --git a/assets/css/admin.scss b/assets/css/admin.scss index c727dfa568e..bf0f9457d61 100644 --- a/assets/css/admin.scss +++ b/assets/css/admin.scss @@ -2037,17 +2037,22 @@ table.wc_input_table { color: $blue; } + th { + white-space: nowrap; + } + td { padding: 0; border-right: 1px solid #DFDFDF; border-bottom: 1px solid #DFDFDF; border-top: 0; background: #fff; + cursor: default;; input[type="text"], input[type="number"] { width: 100%; - padding: 5px 7px; + padding: 5px 10px; margin: 0; border: 0; background: transparent none; @@ -2149,13 +2154,6 @@ table.wc_input_table { } } - tfoot { - th { - padding-left: 20px; - padding-right: 20px; - } - } - tr { &:last-child { td { From 7328bd4a18b2f07a0ca8186b1c5bf0b9242ff018 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 27 Jul 2016 10:37:55 +0100 Subject: [PATCH 157/298] sort_rates placeholder function --- includes/class-wc-tax.php | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/includes/class-wc-tax.php b/includes/class-wc-tax.php index 16f8d39d433..7de38350d95 100644 --- a/includes/class-wc-tax.php +++ b/includes/class-wc-tax.php @@ -266,6 +266,22 @@ class WC_Tax { return $shipping_rates; } + /** + * Logical sort order for tax rates based on the following in order of priority: + * - Priority + * - County code + * - State code + * - # of zip codes + * - # of cities + * @param array $rates + * @return array + * @todo remove tax_rate_order column + */ + private static function sort_rates( $rates ) { + + return $rates; + } + /** * Loop through a set of tax rates and get the matching rates (1 per priority). * @@ -338,9 +354,10 @@ class WC_Tax { LEFT OUTER JOIN {$wpdb->prefix}woocommerce_tax_rate_locations as locations2 ON tax_rates.tax_rate_id = locations2.tax_rate_id WHERE 1=1 AND " . implode( ' AND ', $criteria ) . " GROUP BY tax_rate_id - ORDER BY tax_rate_priority, tax_rate_order + ORDER BY tax_rate_priority " ); + $found_rates = self::sort_rates( $found_rates ); $matched_tax_rates = array(); $found_priority = array(); @@ -892,7 +909,7 @@ class WC_Tax { global $wpdb; // Get all the rates and locations. Snagging all at once should significantly cut down on the number of queries. - $rates = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}woocommerce_tax_rates` WHERE `tax_rate_class` = %s ORDER BY `tax_rate_order`;", sanitize_title( $tax_class ) ) ); + $rates = self::sort_rates( $wpdb->get_results( $wpdb->prepare( "SELECT * FROM `{$wpdb->prefix}woocommerce_tax_rates` WHERE `tax_rate_class` = %s;", sanitize_title( $tax_class ) ) ) ); $locations = $wpdb->get_results( "SELECT * FROM `{$wpdb->prefix}woocommerce_tax_rate_locations`" ); if ( ! empty( $rates ) ) { From a25925655089700d41a03960f42735cc6151cc92 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 27 Jul 2016 11:30:12 +0100 Subject: [PATCH 158/298] Ordering in place --- assets/css/admin.css | 2 +- assets/css/admin.scss | 6 ++++++ includes/class-wc-tax.php | 35 ++++++++++++++++++++++++++++++++--- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/assets/css/admin.css b/assets/css/admin.css index dcb9d725769..538b0962c3e 100644 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -1 +1 @@ -@charset "UTF-8";.button.wc-reload:after,.woocommerce-help-tip:after{speak:none;text-transform:none;-webkit-font-smoothing:antialiased}@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg)}}@-moz-keyframes spin{100%{-moz-transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}.select2-container{margin:0;position:relative;display:block!important;zoom:1;vertical-align:middle}.select2-container,.select2-drop,.select2-search,.select2-search input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{display:block;padding:0 0 0 8px;overflow:hidden;position:relative;border:1px solid #ccc;white-space:nowrap;color:#444;text-decoration:none;border-radius:3px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;font-weight:400}html[dir=rtl] .select2-container .select2-choice{padding:0 8px 0 0}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#ccc;border-radius:0 0 4px 4px}.select2-container.select2-allowclear .select2-choice .select2-chosen{margin-right:42px}.select2-container .select2-choice>.select2-chosen{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:none;width:auto}html[dir=rtl] .select2-container .select2-choice>.select2-chosen{margin-left:26px;margin-right:0}.select2-container .select2-choice abbr{display:none;width:12px;height:12px;position:absolute;right:24px;top:5px;font-size:1px;text-decoration:none;border:0;background:url(../images/select2.png) right top no-repeat;cursor:pointer;outline:0}.select2-container.select2-allowclear .select2-choice abbr{display:inline-block}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop-mask{border:0;margin:0;padding:0;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:9998;background-color:#fff;filter:alpha(opacity=0)}.select2-drop{width:100%;margin-top:-1px;position:absolute;top:100%;background:#fff;color:#000;border:1px solid #ccc;border-top:0;border-radius:0 0 3px 3px}.select2-drop.select2-drop-above{margin-top:1px;border-top:1px solid #ccc;border-bottom:0;border-radius:3px 3px 0 0}.select2-drop-active{border:1px solid #666;border-top:none}.select2-drop.select2-drop-above.select2-drop-active{border-top:1px solid #666}.select2-drop-auto-width{border-top:1px solid #ccc;width:auto}.select2-drop-auto-width .select2-search{padding-top:4px}.select2-container .select2-choice .select2-arrow{display:inline-block;width:18px;height:100%;position:absolute;right:0;top:0;border-radius:0 3px 3px 0;background-clip:padding-box}html[dir=rtl] .select2-container .select2-choice .select2-arrow{left:0;right:auto;border-radius:3px 0 0 3px}.select2-container .select2-choice .select2-arrow b{display:block;width:100%;height:100%;position:relative}.select2-container .select2-choice .select2-arrow b:after{position:absolute;display:block;content:"";top:50%;left:50%;border:4px solid transparent;border-top-color:#666;margin-left:-7px;margin-top:-2px}.select2-search{display:inline-block;width:100%;margin:0;padding-left:4px;padding-right:4px;position:relative;z-index:10000;white-space:nowrap;padding-bottom:4px}.select2-search input{width:100%;height:auto!important;padding:4px 20px 4px 5px!important;margin:0;outline:0;font-family:sans-serif;font-size:1em;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none;background:url(../images/select2.png) 100% -22px no-repeat #fff}html[dir=rtl] .select2-search input{padding:4px 5px 4px 20px;background:url(../images/select2.png) -37px -22px no-repeat #fff}.select2-drop.select2-drop-above .select2-search input{margin-top:4px}.select2-search input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff}.select2-container-active .select2-choice,.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-dropdown-open .select2-choice{border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-dropdown-open .select2-choice .select2-arrow b:after{border-top-color:transparent;border-bottom-color:#666;margin-top:-6px}.select2-dropdown-open.select2-drop-above .select2-choice,.select2-dropdown-open.select2-drop-above .select2-choices{border:1px solid #666;border-top-color:transparent}.select2-dropdown-open .select2-choice .select2-arrow{background:0 0;border-left:none;filter:none}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow{border-right:none}.select2-dropdown-open .select2-choice .select2-arrow b{background-position:-18px 1px}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow b{background-position:-16px 1px}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.select2-results{max-height:200px;padding:4px;margin:0;position:relative;overflow-x:hidden;overflow-y:auto;-webkit-tap-highlight-color:transparent;background:#fafafa}html[dir=rtl] .select2-results{padding:0 4px 0 0;margin:4px 0 4px 4px}.select2-results ul.select2-result-sub{margin:0;padding-left:0}.select2-results li{list-style:none;display:list-item;background-image:none;margin:3px 0}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:700}.select2-results .select2-result-label{padding:5px 7px;margin:0;cursor:pointer;min-height:1em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select2-results-dept-1 .select2-result-label{padding-left:20px}.select2-results-dept-2 .select2-result-label{padding-left:40px}.select2-results-dept-3 .select2-result-label{padding-left:60px}.select2-results-dept-4 .select2-result-label{padding-left:80px}.select2-results-dept-5 .select2-result-label{padding-left:100px}.select2-results-dept-6 .select2-result-label{padding-left:110px}.select2-results-dept-7 .select2-result-label{padding-left:120px}.select2-results .select2-highlighted{background:#f1f1f1;color:#000;border-radius:3px}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:0 0}.select2-results .select2-highlighted ul{background:#fff;color:#000}.select2-results .select2-ajax-error,.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item;padding-left:5px}.select2-results .select2-disabled.select2-highlighted{color:#666;background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-disabled{background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-selected{display:none}.select2-more-results.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #f4f4f4}.select2-results .select2-ajax-error{background:rgba(255,50,50,.2)}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice .select2-arrow{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container.select2-container-disabled .select2-choice abbr{display:none}.select2-container-multi .select2-choices{height:auto!important;height:1%;margin:0;padding:0 5px 0 0;position:relative;border:1px solid #ccc;cursor:text;overflow:hidden;background-color:#fff;min-height:26px}html[dir=rtl] .select2-container-multi .select2-choices{padding:0 0 0 5px}.select2-locked{padding:3px 5px!important}.select2-container-multi.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-container-multi .select2-choices li{float:left;list-style:none}html[dir=rtl] .select2-container-multi .select2-choices li{float:right}.select2-container-multi .select2-choices .select2-search-field{margin:0;padding:0;white-space:nowrap}.select2-container-multi .select2-choices .select2-search-field:first-child{width:100%}.select2-container-multi .select2-choices .select2-search-field input{margin:1px 0;outline:0;border:0;-webkit-box-shadow:none;box-shadow:none;background:0 0!important}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff!important}.select2-default{color:#999!important}.select2-container-multi .select2-choices .select2-search-choice{padding:5px 8px 5px 24px;margin:3px 0 3px 5px;position:relative;line-height:15px;color:#333;cursor:default;border-radius:2px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#e4e4e4}html[dir=rtl] .select2-container-multi .select2-choices .select2-search-choice{margin:3px 5px 3px 0;padding:5px 24px 5px 8px}.select2-container-multi .select2-choices .select2-search-choice .select2-chosen{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;width:12px;height:13px;position:absolute;right:7px;top:6px;font-size:1px;outline:0;background:url(../images/select2.png) right top no-repeat}html[dir=rtl] .select2-search-choice-close{right:auto;left:7px}.select2-container-multi .select2-search-choice-close{left:7px}html[dir=rtl] .select2-container-multi .select2-search-choice-close{left:auto;right:7px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover,.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{padding:3px 5px;border:1px solid #ddd;background-image:none;background-color:#f4f4f4}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none;background:0 0}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-match{text-decoration:underline}.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.select2-display-none{display:none}.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:2dppx){.select2-search input{background-image:url(../images/select2x2.png)!important;background-repeat:no-repeat!important;background-size:60px 40px!important;background-position:100% -21px!important}}@font-face{font-family:star;src:url(../fonts/star.eot);src:url(../fonts/star.eot?#iefix) format("embedded-opentype"),url(../fonts/star.woff) format("woff"),url(../fonts/star.ttf) format("truetype"),url(../fonts/star.svg#star) format("svg");font-weight:400;font-style:normal}@font-face{font-family:WooCommerce;src:url(../fonts/WooCommerce.eot);src:url(../fonts/WooCommerce.eot?#iefix) format("embedded-opentype"),url(../fonts/WooCommerce.woff) format("woff"),url(../fonts/WooCommerce.ttf) format("truetype"),url(../fonts/WooCommerce.svg#WooCommerce) format("svg");font-weight:400;font-style:normal}.blockUI.blockOverlay:before{height:1em;width:1em;position:absolute;top:50%;left:50%;margin-left:-.5em;margin-top:-.5em;display:block;content:"";-webkit-animation:spin 1s ease-in-out infinite;-moz-animation:spin 1s ease-in-out infinite;animation:spin 1s ease-in-out infinite;background:url(../images/icons/loader.svg) center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75)}.wc_addons_wrap .products{overflow:hidden}.wc_addons_wrap .products li{float:left;margin:0 1em 1em 0!important;padding:0;vertical-align:top;width:300px}.wc_addons_wrap .products li a{text-decoration:none;color:inherit;border:1px solid #ddd;display:block;min-height:220px;overflow:hidden;background:#f5f5f5;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1)}.wc_addons_wrap .products li a img{max-width:258px;max-height:24px;padding:17px 20px;display:block;margin:0;background:#fff;border-right:260px solid #fff}.wc_addons_wrap .products li a .price,.wc_addons_wrap .products li a img.extension-thumb+h3{display:none}.wc_addons_wrap .products li a h2,.wc_addons_wrap .products li a h3{margin:0!important;padding:20px!important;background:#fff}.wc_addons_wrap .products li a p{padding:20px!important;margin:0!important;border-top:1px solid #f1f1f1}.wc_addons_wrap .products li a:focus,.wc_addons_wrap .products li a:hover{background-color:#fff}.wc_addons_wrap .storefront{background:url(../images/storefront-bg.jpg) bottom right #f6f6f6;border:1px solid #ddd;padding:20px;overflow:hidden;zoom:1}.wc_addons_wrap .storefront img{width:278px;height:auto;float:left;margin:0 20px 0 0;box-shadow:0 1px 6px rgba(0,0,0,.1)}.wc_addons_wrap .storefront p{max-width:750px}.woocommerce-BlankState a.button-primary,.woocommerce-BlankState button.button-primary,.woocommerce-message a.button-primary,.woocommerce-message button.button-primary{background:#bb77ae;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;color:#fff;text-shadow:0 -1px 1px #A36597,1px 0 1px #A36597,0 1px 1px #A36597,-1px 0 1px #A36597}.woocommerce-BlankState a.button-primary:active,.woocommerce-BlankState a.button-primary:focus,.woocommerce-BlankState a.button-primary:hover,.woocommerce-BlankState button.button-primary:active,.woocommerce-BlankState button.button-primary:focus,.woocommerce-BlankState button.button-primary:hover,.woocommerce-message a.button-primary:active,.woocommerce-message a.button-primary:focus,.woocommerce-message a.button-primary:hover,.woocommerce-message button.button-primary:active,.woocommerce-message button.button-primary:focus,.woocommerce-message button.button-primary:hover{background:#A36597;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597}.woocommerce-message{position:relative;border-left-color:#cc99c2!important;overflow:hidden}.woocommerce-message a.docs,.woocommerce-message a.skip{text-decoration:none!important}.woocommerce-message a.woocommerce-message-close{position:absolute;top:10px;right:10px;padding:10px 15px 10px 21px;font-size:13px;line-height:1.23076923;text-decoration:none}.woocommerce-message a.woocommerce-message-close:before{position:absolute;top:8px;left:0;-webkit-transition:all .1s ease-in-out;transition:all .1s ease-in-out}.woocommerce-message .twitter-share-button{margin-top:-3px;margin-left:3px;vertical-align:middle}#variable_product_options #message,#variable_product_options .notice{margin:10px}.clear{clear:both}#woocommerce-fields-bulk.inline-edit-col label,#woocommerce-fields.inline-edit-col{clear:left}.wrap.woocommerce div.error,.wrap.woocommerce div.updated{margin-top:10px}mark.amount{background:0 0;color:inherit}.postbox,.woocommerce{input:invalid;input-border:1px solid #cc010b;input-background:#ffebe8}.simplify-commerce-banner{overflow:hidden}.simplify-commerce-banner img{float:right;padding:15px 0;margin-left:1em;width:200px}.woocommerce-help-tip{color:#666;display:inline-block;font-size:1.1em;font-style:normal;height:16px;line-height:16px;position:relative;vertical-align:middle;width:16px}.woocommerce-help-tip:after{font-family:Dashicons;font-weight:400;font-variant:normal;line-height:1;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";cursor:help}h2 .woocommerce-help-tip{margin-top:-5px;margin-left:.25em}table.wc_status_table{margin-bottom:1em}table.wc_status_table h2{font-size:14px;margin:0}table.wc_status_table tr:nth-child(2n) td,table.wc_status_table tr:nth-child(2n) th{background:#fcfcfc}table.wc_status_table th{font-weight:700;padding:9px}table.wc_status_table td:first-child{width:33%}table.wc_status_table td.help{width:1em}table.wc_status_table td{padding:9px;font-size:1.1em}table.wc_status_table td mark{background:0 0}table.wc_status_table td mark.yes{color:#7ad03a}table.wc_status_table td mark.no{color:#999}table.wc_status_table td mark.error{color:#a00}table.wc_status_table td ul{margin:0}table.wc_status_table .help_tip{cursor:help}#debug-report{display:none;margin:10px 0;padding:0;position:relative}#debug-report textarea{font-family:monospace;width:100%;margin:0;height:300px;padding:20px;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;resize:none;font-size:12px;line-height:20px;outline:0}#log-viewer-select{padding:10px 0 8px;line-height:180%}#log-viewer textarea{width:100%;resize:vertical}.inline-edit-product.quick-edit-row .inline-edit-col-center,.inline-edit-product.quick-edit-row .inline-edit-col-right{float:right!important}#woocommerce-fields.inline-edit-col label.featured,#woocommerce-fields.inline-edit-col label.manage_stock{margin-left:10px}#woocommerce-fields.inline-edit-col .dimensions div{display:block;margin:.2em 0}#woocommerce-fields.inline-edit-col .dimensions div span.title{display:block;float:left;width:5em}#woocommerce-fields.inline-edit-col .dimensions div span.input-text-wrap{display:block;margin-left:5em}#woocommerce-fields.inline-edit-col .text{box-sizing:border-box;width:99%;float:left;margin:1px 1% 1px 1px}#woocommerce-fields.inline-edit-col .height,#woocommerce-fields.inline-edit-col .length,#woocommerce-fields.inline-edit-col .width{width:32.33%}#woocommerce-fields.inline-edit-col .height{margin-right:0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group label{clear:none;width:49%;margin:.2em 0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group.dimensions label{width:75%;max-width:75%}#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .regular_price,#woocommerce-fields-bulk.inline-edit-col .sale_price,#woocommerce-fields-bulk.inline-edit-col .stock,#woocommerce-fields-bulk.inline-edit-col .weight{box-sizing:border-box;width:100%;margin-left:4.4em}#woocommerce-fields-bulk.inline-edit-col .height,#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .width{box-sizing:border-box;width:25%}.column-coupon_code{line-height:2.25em}.column-coupon_code,ul.wc_coupon_list{margin:0;overflow:hidden;zoom:1;clear:both}ul.wc_coupon_list li{margin:0}ul.wc_coupon_list li.code{display:inline-block}ul.wc_coupon_list li.code:after{content:", "}ul.wc_coupon_list li.code:last-of-type:after{display:none}ul.wc_coupon_list li.code .tips{cursor:pointer}ul.wc_coupon_list_block{margin:0;padding-bottom:2px}ul.wc_coupon_list_block li{border-top:1px solid #fff;border-bottom:1px solid #ccc;line-height:2.5em;margin:0;padding:.5em 0}ul.wc_coupon_list_block li:first-child{border-top:0;padding-top:0}ul.wc_coupon_list_block li:last-child{border-bottom:0;padding-bottom:0}.button.wc-reload{text-indent:-9999px;position:relative;padding:0;height:28px;width:28px!important;display:inline-block}.button.wc-reload:after{font-family:Dashicons;font-weight:400;font-variant:normal;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:28px}#order_data h2,#order_data p.order_number{font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif;font-weight:400}.tablenav .actions{overflow:visible}.tablenav .select2-container{float:left;max-width:200px;font-size:14px;vertical-align:middle;margin:1px 6px 1px 1px}#woocommerce-order-data .handlediv,#woocommerce-order-data .hndle{display:none}#woocommerce-order-data .inside{display:block!important}#order_data{padding:23px 24px 12px}#order_data h2{margin:0;font-size:21px;line-height:1.2;text-shadow:1px 1px 1px #fff;padding:0}#order_data h3{font-size:14px}#order_data h3,#order_data h4{color:#333;margin:1.33em 0 0}#order_data p{color:#777}#order_data p.order_number{margin:0;line-height:1.6em;font-size:16px}#order_data .order_data_column_container{clear:both}#order_data .order_data_column{width:32%;padding:0 2% 0 0;float:left}#order_data .order_data_column:last-child{padding-right:0}#order_data .order_data_column p{padding:0!important}#order_data .order_data_column .address strong{display:block}#order_data .order_data_column .form-field{float:left;width:48%;padding:0;margin:9px 0 0}#order_data .order_data_column .form-field label{display:block;padding:0 0 3px}#order_data .order_data_column .form-field input,#order_data .order_data_column .form-field select,#order_data .order_data_column .form-field textarea{width:100%}#order_data .order_data_column .form-field .select2-container{width:100%!important}#order_data .order_data_column .form-field .date-picker{width:50%}#order_data .order_data_column .form-field .hour,#order_data .order_data_column .form-field .minute{width:3em}#order_data .order_data_column .form-field small{display:block;margin:5px 0 0;color:#999}#order_data .order_data_column .form-field.last{float:right}#order_data .order_data_column .form-field-wide{width:100%;clear:both}#order_data .order_data_column .form-field-wide .wc-customer-search,#order_data .order_data_column .form-field-wide .wc-enhanced-select,#order_data .order_data_column .form-field-wide input,#order_data .order_data_column .form-field-wide select,#order_data .order_data_column .form-field-wide textarea{width:100%}#order_data .order_data_column p.none_set{color:#999}#order_data .order_data_column ._billing_address_1_field,#order_data .order_data_column ._billing_city_field,#order_data .order_data_column ._billing_country_field,#order_data .order_data_column ._billing_email_field,#order_data .order_data_column ._billing_first_name_field,#order_data .order_data_column ._shipping_address_1_field,#order_data .order_data_column ._shipping_city_field,#order_data .order_data_column ._shipping_country_field,#order_data .order_data_column ._shipping_first_name_field{float:left}#order_data .order_data_column ._billing_address_2_field,#order_data .order_data_column ._billing_last_name_field,#order_data .order_data_column ._billing_phone_field,#order_data .order_data_column ._billing_postcode_field,#order_data .order_data_column ._billing_state_field,#order_data .order_data_column ._shipping_address_2_field,#order_data .order_data_column ._shipping_last_name_field,#order_data .order_data_column ._shipping_postcode_field,#order_data .order_data_column ._shipping_state_field,#order_data .order_data_column .wc-customer-user label a,#order_data .order_data_column .wc-order-status label a{float:right}#order_data .order_data_column ._billing_company_field,#order_data .order_data_column ._shipping_company_field,#order_data .order_data_column ._transaction_id_field{clear:both;width:100%}#order_data .order_data_column ._billing_email_field{clear:left}#order_data .order_data_column div.edit_address{display:none;zoom:1;padding-right:1px}#order_data .order_data_column .billing-same-as-shipping,#order_data .order_data_column .load_customer_billing,#order_data .order_data_column .load_customer_shipping,#order_data .order_data_column a.edit_address{width:14px;height:0;padding:14px 0 0;margin:0 0 0 6px;overflow:hidden;position:relative;color:#999;border:0;float:right}#order_data .order_data_column .billing-same-as-shipping:focus,#order_data .order_data_column .billing-same-as-shipping:hover,#order_data .order_data_column .load_customer_billing:focus,#order_data .order_data_column .load_customer_billing:hover,#order_data .order_data_column .load_customer_shipping:focus,#order_data .order_data_column .load_customer_shipping:hover,#order_data .order_data_column a.edit_address:focus,#order_data .order_data_column a.edit_address:hover{color:#000}#order_data .order_data_column .billing-same-as-shipping:after,#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after,#order_data .order_data_column a.edit_address: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}#order_data .order_data_column .billing-same-as-shipping:after{content:"\e008"}#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after{content:"\e03a"}#order_data .order_data_column a.edit_address:after{font-family:Dashicons;content:"\f464"}.order_actions{margin:0;overflow:hidden;zoom:1}.order_actions li{border-top:1px solid #fff;border-bottom:1px solid #ddd;padding:6px 0;margin:0;line-height:1.6em;float:left;width:50%;text-align:center}.order_actions li a{float:none;text-align:center;text-decoration:underline}.order_actions li.wide{width:auto;float:none;clear:both;padding:6px;text-align:left;overflow:hidden}.order_actions li #delete-action{line-height:25px;vertical-align:middle;text-align:left;float:left}.order_actions li .save_order{float:right}.order_actions li#actions{overflow:hidden}.order_actions li#actions .button{width:24px;box-sizing:border-box;float:right}.order_actions li#actions select{width:225px;box-sizing:border-box;float:left}#woocommerce-order-items .inside{margin:0;padding:0;background:#fefefe}#woocommerce-order-items .wc-order-data-row{border-bottom:1px solid #DFDFDF;padding:1.5em 2em;background:#f8f8f8;line-height:2em;text-align:right}#woocommerce-order-items .wc-order-data-row:after,#woocommerce-order-items .wc-order-data-row:before{content:" ";display:table}#woocommerce-order-items .wc-order-data-row:after{clear:both}#woocommerce-order-items .wc-order-data-row p{margin:0;line-height:2em}#woocommerce-order-items .wc-order-data-row .wc-used-coupons{text-align:left}#woocommerce-order-items .wc-order-data-row .wc-used-coupons .tips{display:inline-block}#woocommerce-order-items .wc-order-add-item{background:#fff;vertical-align:top;border-top:none}#woocommerce-order-items .wc-order-add-item .add_item_id,#woocommerce-order-items .wc-order-add-item .select2-container{vertical-align:top}#woocommerce-order-items .wc-order-add-item .add_item_id .search-field input,#woocommerce-order-items .wc-order-add-item .select2-container .search-field input{min-width:100px}#woocommerce-order-items .wc-order-add-item .select2-container{width:400px!important;text-align:left}#woocommerce-order-items .wc-order-add-item .calculate-action,#woocommerce-order-items .wc-order-add-item .cancel-action,#woocommerce-order-items .wc-order-add-item .save-action{float:left;margin-right:2px}#woocommerce-order-items .wc-used-coupons{float:left;width:50%}#woocommerce-order-items .wc-order-totals{float:right;width:50%;margin:0;padding:0;text-align:right}#woocommerce-order-items .wc-order-totals .amount{font-weight:700}#woocommerce-order-items .wc-order-totals .label{vertical-align:top}#woocommerce-order-items .wc-order-totals .total{font-size:1em!important;width:10em;margin:0 0 0 .5em;box-sizing:border-box}#woocommerce-order-items .wc-order-totals .total input[type=text]{width:96%;float:right}#woocommerce-order-items .wc-order-totals .refunded-total{color:#a00}#woocommerce-order-items .refund-actions{margin-top:5px;padding-top:12px;border-top:1px solid #DFDFDF}#woocommerce-order-items .refund-actions .button{float:right;margin-left:4px}#woocommerce-order-items .refund-actions .cancel-action,#woocommerce-order-items .wc-order-item-bulk-edit .cancel-action{float:left;margin-left:0}#woocommerce-order-items .add_meta{margin-left:0!important}#woocommerce-order-items h3 small{color:#999}#woocommerce-order-items .amount{white-space:nowrap}#woocommerce-order-items .add-items .description{margin-right:10px}#woocommerce-order-items .add-items .button{float:left;margin-right:.25em}#woocommerce-order-items .add-items .button-primary{float:none;margin-right:0}#woocommerce-order-items .inside{display:block!important}#woocommerce-order-items .handlediv,#woocommerce-order-items .hndle{display:none}#woocommerce-order-items .woocommerce_order_items_wrapper{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items{width:100%;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th{text-align:left;padding:1em;font-weight:400;color:#999;background:#f8f8f8;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th.sortable{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th .wc-arrow{float:right;position:relative;margin-right:-1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td{padding:1.5em 1em 1em;text-align:left;line-height:1.5em;vertical-align:top;border-bottom:1px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td select{width:50%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{font-size:14px;padding:4px;color:#555}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr td{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected{background:#F5EBF3}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected td{border-color:#E6CCE1;opacity:.8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:last-child td{border-bottom:1px solid #dfdfdf}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:first-child td{border-top:8px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody#order_line_items tr:first-child td{border-top:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb{text-align:left;width:38px;padding-bottom:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail{width:38px;height:38px;border:2px solid #e8e8e8;background:#f8f8f8;color:#ccc;position:relative;font-size:21px;display:block;text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;height:100%;text-align:center;content:"";width:38px;line-height:38px;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail img{width:100%;height:100%;margin:0;padding:0;position:relative}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-sku,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-variation{display:block;margin-top:.5em;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item{min-width:200px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .center,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .variation-id{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class{text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label{white-space:nowrap;color:#999;font-size:.833em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label input{display:inline}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class input{width:70px;vertical-align:middle;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class select{width:85px;height:26px;vertical-align:middle;font-size:1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input{display:inline-block;background:#fff;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);margin:1px 0;min-width:80px;overflow:hidden;line-height:1em;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input{width:100%;box-sizing:border-box}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input label{font-size:.75em;padding:4px 6px 0;color:#555;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input{width:100%;box-sizing:border-box;border:0;box-shadow:none;margin:0;padding:0 6px 4px;color:#555;background:0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input::-webkit-input-placeholder{color:#ddd}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child{border-bottom:1px dashed #ddd;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child label{color:#ccc}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .view{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .edit{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes label{display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount{display:block;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{margin-right:.25em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input{text-align:center;width:50px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items span.subtotal{opacity:.5}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.tax_class,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.tax_class{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .calculated{border-color:#ae8ca2;border-style:dotted}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{margin:.5em 0 0;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{color:#ccc;top:0;left:0;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-align:center;font-family:WooCommerce}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr th{border:0;padding:0 4px .5em 0;line-height:1.5em;width:20%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td{padding:0 4px .5em 0;border:0;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input{width:100%;margin:0;position:relative;border-bottom:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .refund_by,ul.order_notes li p.meta .exact-date{border-bottom:1px dotted #999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td textarea{width:100%;height:4em;margin:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input:focus+textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input:focus+textarea{border-top-color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p{margin:0 0 .5em;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p:last-child{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method_name{width:100%;margin:0 0 .5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;float:right;font-size:14px;visibility:hidden;margin:3px -18px 0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:hover:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:hover:before{color:#a00}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax:hover .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax:hover .delete-order-tax{visibility:visible}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded{display:block;color:#a00;white-space:nowrap;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;width:100%;height:100%;text-align:center;content:"";position:relative;top:auto;left:auto;margin:-1px 4px 0 0;vertical-align:middle;line-height:1em}#woocommerce-order-items .wc-order-edit-line-item{padding-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions{width:44px;text-align:right;padding-left:0;vertical-align:middle}#woocommerce-order-items .wc-order-edit-line-item-actions a{color:#ccc;display:inline-block;cursor:pointer;padding:0 0 .5em;margin:0 0 0 12px;vertical-align:middle;text-decoration:none;line-height:16px;width:16px;overflow:hidden}#woocommerce-order-items .wc-order-edit-line-item-actions a:before{margin:0;padding:0;font-size:16px;width:16px;height:16px}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before,#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{font-family:Dashicons;-webkit-font-smoothing:antialiased;text-indent:0;top:0;left:0;width:100%;height:100%;margin:0;text-align:center;position:relative;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1}#woocommerce-order-items .wc-order-edit-line-item-actions a:hover:before{color:#999}#woocommerce-order-items .wc-order-edit-line-item-actions a:first-child{margin-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:hover:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:hover:before{color:#a00}#woocommerce-order-items tbody tr .wc-order-edit-line-item-actions{visibility:hidden}#woocommerce-order-items tbody tr:hover .wc-order-edit-line-item-actions{visibility:visible}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions{width:1.5em;visibility:visible!important}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions a{padding:0}#woocommerce-order-downloads .buttons{float:left;padding:0;margin:0;vertical-align:top}#woocommerce-order-downloads .buttons .add_item_id,#woocommerce-order-downloads .buttons .select2-container{width:400px!important;margin-right:9px;vertical-align:top;float:left}#woocommerce-order-downloads .buttons button{margin:2px 0 0}#woocommerce-order-downloads h3 small{color:#999}#poststuff #woocommerce-order-actions .inside{margin:0;padding:0}#poststuff #woocommerce-order-actions .inside ul.order_actions li{padding:6px 10px;box-sizing:border-box}#poststuff #woocommerce-order-actions .inside ul.order_actions li:last-child{border-bottom:0}#poststuff #woocommerce-order-notes .inside{margin:0;padding:0}#poststuff #woocommerce-order-notes .inside ul.order_notes li{padding:0 10px}#woocommerce_customers p.search-box{margin:6px 0 4px;float:left}#woocommerce_customers .tablenav{float:right;clear:none}.widefat.customers td{vertical-align:middle;padding:4px 7px}.widefat .column-order_title{width:15%}.widefat .column-order_title time{display:block;color:#999;margin:3px 0}.widefat .column-orders,.widefat .column-paying,.widefat .column-spent{text-align:center;width:8%}.widefat .column-last_order{width:11%}.widefat .column-order_actions,.widefat .column-user_actions,.widefat .column-wc_actions{width:110px}.widefat .column-order_actions a.button,.widefat .column-user_actions a.button,.widefat .column-wc_actions a.button{float:left;margin:0 4px 2px 0;cursor:pointer;padding:3px 4px;height:auto}.widefat .column-order_actions a.button img,.widefat .column-user_actions a.button img,.widefat .column-wc_actions a.button img{display:block;width:12px;height:auto}.widefat small.meta{display:block;color:#999;font-size:inherit;margin:3px 0}.widefat .column-order_date,.widefat .column-order_total{width:9%}.widefat .column-order_status{width:45px;text-align:center}.widefat .column-order_status mark{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;background:0 0;font-size:1.4em;margin:0 auto}.widefat .column-order_status mark.cancelled:after,.widefat .column-order_status mark.completed:after,.widefat .column-order_status mark.failed:after,.widefat .column-order_status mark.on-hold:after,.widefat .column-order_status mark.pending:after,.widefat .column-order_status mark.processing:after,.widefat .column-order_status mark.refunded:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.column-customer_message .note-on:after,.column-order_notes .note-on:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;left:0;text-align:center;line-height:16px;font-family:WooCommerce}.widefat .column-order_status mark.pending:after{content:"\e012";color:#ffba00}.widefat .column-order_status mark.completed:after{content:"\e015";color:#2ea2cc}.widefat .column-order_status mark.on-hold:after{content:"\e033";color:#999}.widefat .column-order_status mark.failed:after{content:"\e016";color:#d0c21f}.widefat .column-order_status mark.cancelled:after{content:"\e013";color:#a00}.widefat .column-order_status mark.processing:after{content:"\e011";color:#73a724}.widefat .column-order_status mark.refunded:after{content:"\e014";color:#999}.widefat td.column-order_status{padding-top:9px}.column-customer_message .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-customer_message .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.column-order_notes .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-order_notes .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.order_actions .complete,.order_actions .processing,.order_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.order_actions .processing:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.order_actions .complete:after,.order_actions .view:after{font-family:Dashicons;text-indent:0;position:absolute;width:100%;height:100%;left:0;line-height:1.85;margin:0;text-align:center;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;font-weight:400}.order_actions .complete:after{content:""}.order_actions .view:after{content:""}.user_actions .edit,.user_actions .link,.user_actions .refresh,.user_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.user_actions .edit:after,.user_actions .link:after,.user_actions .refresh:after,.user_actions .view:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.user_actions .edit:after{font-family:Dashicons;content:"\f464"}.user_actions .link:after{content:"\e00d"}.user_actions .view:after{content:"\e010"}.user_actions .refresh:after{content:"\e031"}.attributes-table td,.attributes-table th{width:15%;vertical-align:top}.attributes-table .attribute-terms{width:32%}.attributes-table .attribute-actions{width:2em}.attributes-table .attribute-actions .configure-terms{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.attributes-table .attribute-actions .configure-terms:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}ul.order_notes{padding:2px 0 0}ul.order_notes li .note_content{padding:10px;background:#efefef;position:relative}ul.order_notes li .note_content p{margin:0;padding:0;word-wrap:break-word}ul.order_notes li p.meta{padding:10px;color:#999;margin:0;font-size:11px}ul.order_notes li a.delete_note{color:#a00}table.wp-list-table .row-actions,table.wp-list-table span.na{color:#999}ul.order_notes li .note_content:after{content:"";display:block;position:absolute;bottom:-10px;left:20px;width:0;height:0;border-width:10px 10px 0 0;border-style:solid;border-color:#efefef transparent}ul.order_notes li.customer-note .note_content{background:#A7CEDC}ul.order_notes li.customer-note .note_content:after{border-color:#A7CEDC transparent}ul.order_notes li.system-note .note_content{background:#d7cad2}ul.order_notes li.system-note .note_content:after{border-color:#d7cad2 transparent}.add_note{border-top:1px solid #ddd;padding:10px 10px 0}.add_note h4{margin-top:5px!important}.add_note #add_order_note{width:100%;height:50px}table.wp-list-table .column-thumb{width:52px;text-align:center;white-space:nowrap}table.wp-list-table .column-name{width:22%}table.wp-list-table .column-product_cat,table.wp-list-table .column-product_tag{width:11%!important}table.wp-list-table .column-featured,table.wp-list-table .column-product_type{width:48px;text-align:left!important}table.wp-list-table .column-customer_message,table.wp-list-table .column-order_notes{width:48px;text-align:center}table.wp-list-table .column-customer_message img,table.wp-list-table .column-order_notes img{margin:0 auto;padding-top:0!important}table.wp-list-table .manage-column.column-featured img,table.wp-list-table .manage-column.column-product_type img{padding-left:2px}table.wp-list-table .column-price .woocommerce-price-suffix{display:none}table.wp-list-table img{margin:1px 2px}table.wp-list-table td.column-thumb img{margin:0;width:auto;height:auto;max-width:40px;max-height:40px;vertical-align:middle}table.wp-list-table .column-is_in_stock{text-align:left!important}table.wp-list-table span.wc-featured,table.wp-list-table span.wc-image,table.wp-list-table span.wc-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table span.wc-featured:before,table.wp-list-table span.wc-image:before,table.wp-list-table span.wc-type:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:""}table.wp-list-table span.wc-featured{margin:0;cursor:pointer}table.wp-list-table span.wc-featured:before{content:"\f155"}table.wp-list-table span.wc-featured.not-featured:before{content:"\f154"}table.wp-list-table td.column-featured span.wc-featured{font-size:1.6em}table.wp-list-table span.wc-type{margin:0}table.wp-list-table span.wc-type:before{font-family:WooCommerce;content:"\e006"}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after,table.wp-list-table span.product-type:before{font-family:WooCommerce;text-align:center;line-height:1;top:0;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;left:0}table.wp-list-table span.product-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.6em}table.wp-list-table span.product-type:before{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}table.wp-list-table span.product-type.grouped:before{content:"\e002"}table.wp-list-table span.product-type.external:before{content:"\e034"}table.wp-list-table span.product-type.variable:before{content:"\e003"}table.wp-list-table span.product-type.downloadable:before{content:"\e001"}table.wp-list-table span.product-type.virtual:before{content:"\e000"}table.wp-list-table mark.instock{font-weight:700;color:#7ad03a;background:0 0;line-height:1}table.wp-list-table mark.outofstock{font-weight:700;color:#a44;background:0 0;line-height:1}table.wp-list-table .notes_head,table.wp-list-table .order-notes_head,table.wp-list-table .status_head{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%}table.wc_emails .wc-email-settings-table-name,table.wc_emails td.name,table.wc_gateways .wc-email-settings-table-name,table.wc_gateways td.name,table.wc_shipping .wc-email-settings-table-name,table.wc_shipping td.name{font-weight:700}table.wp-list-table .order-notes_head:after{content:"\e028"}table.wp-list-table .notes_head:after{content:"\e026"}table.wp-list-table .status_head:after{content:"\e011"}table.wp-list-table .column-order_items{width:12%}table.wp-list-table .column-order_items table.order_items{width:100%;margin:3px 0 0;padding:0;display:none}table.wp-list-table .column-order_items table.order_items td{border:0;margin:0;padding:0 0 3px}table.wp-list-table .column-order_items table.order_items td.qty{color:#999;padding-right:6px;text-align:left}mark.notice{background:#fff;color:#a00;margin:0 0 0 10px}a.export_rates,a.import_rates{float:right;margin-left:9px;margin-top:-2px;margin-bottom:0}#rates-search{float:right}#rates-search input.wc-tax-rates-search-field{padding:4px 8px;font-size:1.2em}#rates-pagination{float:right;margin-right:.5em}#rates-pagination .tablenav{margin:0}table.wc_input_table,table.wc_tax_rates{width:100%}table.wc_input_table span.tips,table.wc_tax_rates span.tips{color:#2ea2cc}table.wc_input_table th,table.wc_tax_rates th{white-space:nowrap}table.wc_input_table td,table.wc_tax_rates td{padding:0;border-right:1px solid #DFDFDF;border-bottom:1px solid #DFDFDF;border-top:0;background:#fff;cursor:default}table.wc_input_table td input[type=text],table.wc_input_table td input[type=number],table.wc_tax_rates td input[type=text],table.wc_tax_rates td input[type=number]{width:100%;padding:5px 10px;margin:0;border:0;background:0 0}table.wc_input_table td.apply_to_shipping,table.wc_input_table td.compound,table.wc_tax_rates td.apply_to_shipping,table.wc_tax_rates td.compound{padding:5px 7px;vertical-align:middle}table.wc_input_table td.apply_to_shipping input,table.wc_input_table td.compound input,table.wc_tax_rates td.apply_to_shipping input,table.wc_tax_rates td.compound input{width:auto;padding:0}table.wc_input_table td:last-child,table.wc_tax_rates td:last-child{border-right:0}table.wc_input_table tr.current td,table.wc_tax_rates tr.current td{background-color:#fefbcc}table.wc_input_table .cost,table.wc_input_table .cost input,table.wc_input_table .item_cost,table.wc_input_table .item_cost input,table.wc_tax_rates .cost,table.wc_tax_rates .cost input,table.wc_tax_rates .item_cost,table.wc_tax_rates .item_cost input{text-align:right}table.wc_input_table th.sort,table.wc_tax_rates th.sort{width:17px;padding:0 4px}table.wc_input_table td.sort,table.wc_tax_rates td.sort{padding:0 4px}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort{cursor:move;font-size:15px;background:#f9f9f9;text-align:center;vertical-align:middle}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before{color:#333}table.wc_input_table .button,table.wc_tax_rates .button{float:left;margin-right:5px}table.wc_input_table .export,table.wc_input_table .import,table.wc_tax_rates .export,table.wc_tax_rates .import{float:right;margin-right:0;margin-left:5px}table.wc_input_table span.tips,table.wc_tax_rates span.tips{padding:0 3px}table.wc_input_table .pagination,table.wc_tax_rates .pagination{float:right}table.wc_input_table .pagination .button,table.wc_tax_rates .pagination .button{margin-left:5px;margin-right:0}table.wc_input_table .pagination .current,table.wc_tax_rates .pagination .current{background:#bbb;text-shadow:none}table.wc_input_table tr:last-child td,table.wc_tax_rates tr:last-child td{border-bottom:0}table.wc_emails,table.wc_gateways,table.wc_shipping{position:relative}table.wc_emails td,table.wc_gateways td,table.wc_shipping td{vertical-align:middle;padding:7px;line-height:2em}table.wc_emails tr:nth-child(odd) td,table.wc_gateways tr:nth-child(odd) td,table.wc_shipping tr:nth-child(odd) td{background:#f9f9f9}table.wc_emails th,table.wc_gateways th,table.wc_shipping th{padding:9px 7px!important;vertical-align:middle}table.wc_emails .settings,table.wc_gateways .settings,table.wc_shipping .settings{text-align:right}table.wc_emails .default,table.wc_emails .radio,table.wc_emails .status,table.wc_gateways .default,table.wc_gateways .radio,table.wc_gateways .status,table.wc_shipping .default,table.wc_shipping .radio,table.wc_shipping .status{text-align:center}table.wc_emails .default .tips,table.wc_emails .radio .tips,table.wc_emails .status .tips,table.wc_gateways .default .tips,table.wc_gateways .radio .tips,table.wc_gateways .status .tips,table.wc_shipping .default .tips,table.wc_shipping .radio .tips,table.wc_shipping .status .tips{margin:0 auto}table.wc_emails .default input,table.wc_emails .radio input,table.wc_emails .status input,table.wc_gateways .default input,table.wc_gateways .radio input,table.wc_gateways .status input,table.wc_shipping .default input,table.wc_shipping .radio input,table.wc_shipping .status input{margin:0}table.wc_emails th.sort,table.wc_gateways th.sort,table.wc_shipping th.sort{width:28px;padding:0}table.wc_emails td.sort,table.wc_gateways td.sort,table.wc_shipping td.sort{padding:0 7px;cursor:move;font-size:15px;text-align:center;vertical-align:middle}table.wc_emails td.sort:before,table.wc_gateways td.sort:before,table.wc_shipping td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_emails .wc-email-settings-table-name span,table.wc_gateways .wc-email-settings-table-name span,table.wc_shipping .wc-email-settings-table-name span{font-weight:400;color:#999;margin:0 0 0 4px!important}table.wc_emails .wc-email-settings-table-status,table.wc_gateways .wc-email-settings-table-status,table.wc_shipping .wc-email-settings-table-status{text-align:center;width:1em}table.wc_emails .wc-email-settings-table-status .tips,table.wc_gateways .wc-email-settings-table-status .tips,table.wc_shipping .wc-email-settings-table-status .tips{margin:0 auto}table.wc_emails .wc-email-settings-table-actions a,table.wc_gateways .wc-email-settings-table-actions a,table.wc_shipping .wc-email-settings-table-actions a{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}table.wc_emails .wc-email-settings-table-actions a:after,table.wc_gateways .wc-email-settings-table-actions a:after,table.wc_shipping .wc-email-settings-table-actions a:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}table.wc-shipping-classes td,table.wc-shipping-classes th,table.wc-shipping-zone-methods td,table.wc-shipping-zone-methods th,table.wc-shipping-zones td,table.wc-shipping-zones th{vertical-align:top;line-height:24px;padding:1em;font-size:14px;background:#fff}table.wc-shipping-classes td li,table.wc-shipping-classes th li,table.wc-shipping-zone-methods td li,table.wc-shipping-zone-methods th li,table.wc-shipping-zones td li,table.wc-shipping-zones th li{line-height:24px;font-size:14px}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state,table.wc-shipping-classes td.wc-shipping-zones-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state,table.wc-shipping-zones td.wc-shipping-zones-blank-state{background:#F7F1F6!important;overflow:hidden;position:relative;padding:7.5em 7.5%;border-bottom:2px solid #EEE2EC}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zones td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state p{color:#a46497;font-size:1.5em;line-height:1.5em;margin:0 0 1em;position:relative;z-index:1;text-shadow:1px 1px 1px #fff}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state p.main{font-size:2em}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state li{margin-left:1em;list-style:circle inside}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-classes td.wc-shipping-zones-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state:before,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zones td.wc-shipping-zones-blank-state:before{content:"\e01b";font-family:WooCommerce;text-align:center;line-height:1;color:#EEE2EC;display:block;width:1em;font-size:40em;top:50%;right:-3.75%;margin-top:-.1875em;position:absolute}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-classes td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zones-blank-state .button-primary{background-color:#804877;border-color:#804877;-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);margin:0;opacity:1;text-shadow:0 -1px 1px #8a4f7f,1px 0 1px #8a4f7f,0 1px 1px #8a4f7f,-1px 0 1px #8a4f7f;font-size:1.5em;padding:.75em 1em;height:auto;position:relative;z-index:1}table.wc-shipping-classes .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-classes .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-classes tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-classes tr.odd td,table.wc-shipping-zone-methods .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tr.odd td,table.wc-shipping-zones .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zones .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zones tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zones tr.odd td{background:#f9f9f9}table.wc-shipping-classes p,table.wc-shipping-classes ul,table.wc-shipping-zone-methods p,table.wc-shipping-zone-methods ul,table.wc-shipping-zones p,table.wc-shipping-zones ul{margin:0}table.wc-shipping-classes td.wc-shipping-zone-method-sort,table.wc-shipping-classes td.wc-shipping-zone-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-sort,table.wc-shipping-zones td.wc-shipping-zone-method-sort,table.wc-shipping-zones td.wc-shipping-zone-sort{cursor:move;font-size:15px;text-align:center}table.wc-shipping-classes td.wc-shipping-zone-method-sort:before,table.wc-shipping-classes td.wc-shipping-zone-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:before,table.wc-shipping-zones td.wc-shipping-zone-sort:before{content:"\f333";font-family:Dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-classes td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-sort:hover:before{color:#333}table.wc-shipping-classes td.wc-shipping-zone-worldwide,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide,table.wc-shipping-zones td.wc-shipping-zone-worldwide{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-worldwide:before,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide:before,table.wc-shipping-zones td.wc-shipping-zone-worldwide:before{content:"\f319";font-family:dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes .wc-shipping-zone-methods,table.wc-shipping-classes .wc-shipping-zone-name,table.wc-shipping-zone-methods .wc-shipping-zone-methods,table.wc-shipping-zone-methods .wc-shipping-zone-name,table.wc-shipping-zones .wc-shipping-zone-methods,table.wc-shipping-zones .wc-shipping-zone-name{width:25%}table.wc-shipping-classes .wc-shipping-class-description input,table.wc-shipping-classes .wc-shipping-class-description select,table.wc-shipping-classes .wc-shipping-class-description textarea,table.wc-shipping-classes .wc-shipping-class-name input,table.wc-shipping-classes .wc-shipping-class-name select,table.wc-shipping-classes .wc-shipping-class-name textarea,table.wc-shipping-classes .wc-shipping-class-slug input,table.wc-shipping-classes .wc-shipping-class-slug select,table.wc-shipping-classes .wc-shipping-class-slug textarea,table.wc-shipping-classes .wc-shipping-zone-name input,table.wc-shipping-classes .wc-shipping-zone-name select,table.wc-shipping-classes .wc-shipping-zone-name textarea,table.wc-shipping-classes .wc-shipping-zone-region input,table.wc-shipping-classes .wc-shipping-zone-region select,table.wc-shipping-classes .wc-shipping-zone-region textarea,table.wc-shipping-zone-methods .wc-shipping-class-description input,table.wc-shipping-zone-methods .wc-shipping-class-description select,table.wc-shipping-zone-methods .wc-shipping-class-description textarea,table.wc-shipping-zone-methods .wc-shipping-class-name input,table.wc-shipping-zone-methods .wc-shipping-class-name select,table.wc-shipping-zone-methods .wc-shipping-class-name textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug input,table.wc-shipping-zone-methods .wc-shipping-class-slug select,table.wc-shipping-zone-methods .wc-shipping-class-slug textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name input,table.wc-shipping-zone-methods .wc-shipping-zone-name select,table.wc-shipping-zone-methods .wc-shipping-zone-name textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region input,table.wc-shipping-zone-methods .wc-shipping-zone-region select,table.wc-shipping-zone-methods .wc-shipping-zone-region textarea,table.wc-shipping-zones .wc-shipping-class-description input,table.wc-shipping-zones .wc-shipping-class-description select,table.wc-shipping-zones .wc-shipping-class-description textarea,table.wc-shipping-zones .wc-shipping-class-name input,table.wc-shipping-zones .wc-shipping-class-name select,table.wc-shipping-zones .wc-shipping-class-name textarea,table.wc-shipping-zones .wc-shipping-class-slug input,table.wc-shipping-zones .wc-shipping-class-slug select,table.wc-shipping-zones .wc-shipping-class-slug textarea,table.wc-shipping-zones .wc-shipping-zone-name input,table.wc-shipping-zones .wc-shipping-zone-name select,table.wc-shipping-zones .wc-shipping-zone-name textarea,table.wc-shipping-zones .wc-shipping-zone-region input,table.wc-shipping-zones .wc-shipping-zone-region select,table.wc-shipping-zones .wc-shipping-zone-region textarea{width:100%}table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-zone-delete{color:red}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle{float:right;margin:0;font-size:.9em;text-decoration:underline}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes{display:none}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea{margin-top:1em}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes .description{font-size:.9em;color:#999}table.wc-shipping-classes .wc-shipping-class-count,table.wc-shipping-zone-methods .wc-shipping-class-count,table.wc-shipping-zones .wc-shipping-class-count{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-methods,table.wc-shipping-zone-methods td.wc-shipping-zone-methods,table.wc-shipping-zones td.wc-shipping-zone-methods{color:#999}table.wc-shipping-classes td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .method_disabled{text-decoration:line-through}table.wc-shipping-classes td.wc-shipping-zone-methods ul,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul,table.wc-shipping-zones td.wc-shipping-zone-methods ul{color:#999;position:relative;padding-right:32px}table.wc-shipping-classes td.wc-shipping-zone-methods ul li,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li,table.wc-shipping-zones td.wc-shipping-zone-methods ul li{display:inline;margin:0}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:before{content:", "}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-classes td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:nth-child(2):before{content:""}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child{display:block}table.wc-shipping-classes td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zones td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row{position:absolute;right:0;top:0}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method{display:block;width:24px;padding:24px 0 0;height:0;overflow:hidden;cursor:pointer}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method:before{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;font-family:Dashicons;content:"\f502";color:#999;vertical-align:middle;line-height:24px;font-size:16px;margin:0}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled:before{line-height:inherit}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled{margin-top:1px;display:inline-block}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled{cursor:not-allowed}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled:before{color:#ccc}table.wc-shipping-classes .wc-shipping-zone-method-title,table.wc-shipping-zone-methods .wc-shipping-zone-method-title,table.wc-shipping-zones .wc-shipping-zone-method-title{width:33%}table.wc-shipping-classes .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zone-methods .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zones .wc-shipping-zone-method-title .wc-shipping-zone-method-delete{color:red}table.wc-shipping-classes .wc-shipping-zone-method-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled{text-align:center}table.wc-shipping-classes tfoot input,table.wc-shipping-classes tfoot select,table.wc-shipping-zone-methods tfoot input,table.wc-shipping-zone-methods tfoot select,table.wc-shipping-zones tfoot input,table.wc-shipping-zones tfoot select{vertical-align:middle!important}table.wc-shipping-classes tfoot .button-secondary,table.wc-shipping-zone-methods tfoot .button-secondary,table.wc-shipping-zones tfoot .button-secondary{float:right}table.wc-shipping-classes .editing .wc-shipping-zone-edit,table.wc-shipping-classes .editing .wc-shipping-zone-view,table.wc-shipping-zone-methods .editing .wc-shipping-zone-edit,table.wc-shipping-zone-methods .editing .wc-shipping-zone-view,table.wc-shipping-zones .editing .wc-shipping-zone-edit,table.wc-shipping-zones .editing .wc-shipping-zone-view{display:none}.wc-modal-shipping-method-settings{background:#f8f8f8;padding:1em!important}.wc-modal-shipping-method-settings form .form-table{width:100%;background:#fff;margin:0 0 1.5em}.wc-modal-shipping-method-settings form .form-table tr th{width:30%;position:relative}.wc-modal-shipping-method-settings form .form-table tr th .woocommerce-help-tip{float:right;margin:-8px -.5em 0 0;vertical-align:middle;right:0;top:50%;position:absolute}.wc-modal-shipping-method-settings form .form-table tr td input,.wc-modal-shipping-method-settings form .form-table tr td select,.wc-modal-shipping-method-settings form .form-table tr td textarea{width:50%;min-width:250px}.wc-modal-shipping-method-settings form .form-table tr td input[type=checkbox]{width:auto;min-width:16px}.wc-modal-shipping-method-settings form .form-table tr td,.wc-modal-shipping-method-settings form .form-table tr th{vertical-align:middle;margin:0;line-height:24px;padding:1em;border-bottom:1px solid #f8f8f8}.wc-modal-shipping-method-settings form .form-table:last-of-type{margin-bottom:0}.wc-backbone-modal .wc-shipping-zone-method-selector p{margin-top:0}.wc-backbone-modal .wc-shipping-zone-method-selector .wc-shipping-zone-method-description{margin:.75em 1px 0;line-height:1.5em;color:#999;font-style:italic}.wc-backbone-modal .wc-shipping-zone-method-selector select{width:100%;cursor:pointer}img.help_tip{margin:0 0 0 9px;vertical-align:middle}.postbox img.help_tip{margin-top:0}.postbox .woocommerce-help-tip{margin:0 0 0 9px}.status-disabled,.status-enabled,.status-manual{font-size:1.4em;display:block;text-indent:-9999px;position:relative;height:1em;width:1em}.status-disabled:before,.status-enabled:before,.status-manual:before{font-family:WooCommerce;line-height:1;margin:0;position:absolute;width:100%;height:100%;text-indent:0;top:0;font-variant:normal;-webkit-font-smoothing:antialiased;font-weight:400;text-align:center;left:0;speak:none;text-transform:none}.status-manual:before{content:"";color:#999}.status-enabled:before{content:"";color:#a46497}.status-disabled:before{content:"";color:#ccc}.woocommerce h2.woo-nav-tab-wrapper{margin-bottom:1em}.woocommerce nav.woo-nav-tab-wrapper{margin:1.5em 0 1em;border-bottom:1px solid #ccc}.woocommerce .subsubsub{margin:-8px 0 0}.woocommerce .wc-admin-breadcrumb{margin-left:.5em}.woocommerce .wc-admin-breadcrumb a{color:#a46497}.woocommerce #template div{margin:0}.woocommerce #template div p .button{float:right;margin-left:10px;margin-top:-4px}.woocommerce #template div .editor textarea{margin-bottom:8px}.woocommerce textarea[disabled=disabled]{background:#DFDFDF!important}.woocommerce table.form-table{margin:0;position:relative}.woocommerce table.form-table .forminp-radio ul{margin:0}.woocommerce table.form-table .forminp-radio ul li{line-height:1.4em}.woocommerce table.form-table textarea.input-text{height:100%;min-width:150px;display:block}.woocommerce table.form-table input.regular-input{width:25em}.woocommerce table.form-table textarea.wide-input{width:100%}.woocommerce table.form-table .woocommerce-help-tip,.woocommerce table.form-table img.help_tip{padding:0;margin:-4px 0 0 5px;vertical-align:middle;cursor:help;line-height:1}.woocommerce table.form-table span.help_tip{cursor:help;color:#2ea2cc}.woocommerce table.form-table th{position:relative;padding-right:24px}.woocommerce table.form-table .select2-container{display:block;max-width:350px;vertical-align:top;margin-bottom:3px}.woocommerce table.form-table table.widefat th{padding-right:inherit}.woocommerce table.form-table th .woocommerce-help-tip,.woocommerce table.form-table th img.help_tip{margin:0 -24px 0 0;float:right}.woocommerce table.form-table .wp-list-table .woocommerce-help-tip{float:none}.woocommerce table.form-table fieldset{margin-top:4px}.woocommerce table.form-table fieldset .woocommerce-help-tip,.woocommerce table.form-table fieldset img.help_tip{margin:-3px 0 0 5px}.woocommerce table.form-table fieldset p.description{margin-bottom:8px}.woocommerce table.form-table fieldset:first-child{margin-top:0}.woocommerce table.form-table .iris-picker{z-index:100;display:none;position:absolute;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,.2)}.woocommerce table.form-table .iris-picker .ui-slider{border:0!important;margin:0!important;width:auto!important;height:auto!important;background:none!important}.woocommerce table.form-table .iris-picker .ui-slider .ui-slider-handle{margin-bottom:0!important}.woocommerce table.form-table .colorpickpreview{padding:3px 3px 3px 20px;border:1px solid #ddd;border-right:0}.woocommerce table.form-table .colorpick{border-left:0}.woocommerce table.form-table .image_width_settings{vertical-align:middle}.woocommerce table.form-table .image_width_settings label{margin-left:10px}.woocommerce table.form-table .wc_emails_wrapper{padding:0 15px 10px 0}.woocommerce #tabs-wrap table a.remove{margin-left:4px}.woocommerce #tabs-wrap table p{margin:0 0 4px!important;overflow:hidden;zoom:1}.woocommerce #tabs-wrap table p a.add{float:left}#wp-excerpt-editor-container{background:#fff}#product_variation-parent #parent_id{width:100%}#postimagediv img{border:1px solid #d5d5d5;max-width:100%}#woocommerce-product-images .inside{margin:0;padding:0}#woocommerce-product-images .inside .add_product_images{padding:0 12px 12px}#woocommerce-product-images .inside #product_images_container{padding:0 0 0 9px}#woocommerce-product-images .inside #product_images_container ul{margin:0;padding:0}#woocommerce-product-images .inside #product_images_container ul:after,#woocommerce-product-images .inside #product_images_container ul:before{content:" ";display:table}#woocommerce-product-images .inside #product_images_container ul:after{clear:both}#woocommerce-product-images .inside #product_images_container ul li.add,#woocommerce-product-images .inside #product_images_container ul li.image,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{width:80px;float:left;cursor:move;border:1px solid #d5d5d5;margin:9px 9px 0 0;background:#f7f7f7;border-radius:2px;position:relative;box-sizing:border-box}#woocommerce-product-images .inside #product_images_container ul li.add img,#woocommerce-product-images .inside #product_images_container ul li.image img,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder img{width:100%;height:auto;display:block}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{border:3px dashed #ddd;position:relative}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-size:2.618em;line-height:72px;color:#ddd}#woocommerce-product-images .inside #product_images_container ul ul.actions{position:absolute;top:-8px;right:-8px;padding:2px;display:none}#woocommerce-product-images .inside #product_images_container ul ul.actions li{float:right;margin:0 0 0 2px}#woocommerce-product-images .inside #product_images_container ul ul.actions li a{width:1em;margin:0;height:0;display:block;overflow:hidden}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.tips{cursor:pointer}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.4em}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:hover:before{color:#a00}#woocommerce-product-images .inside #product_images_container ul li:hover ul.actions{display:block}#woocommerce-product-data .hndle{padding:10px}#woocommerce-product-data .hndle span{display:block;vertical-align:middle;line-height:24px}#woocommerce-product-data .hndle span span{display:inline;line-height:inherit;vertical-align:baseline}#woocommerce-product-data .hndle label{padding-right:1em;font-size:12px;vertical-align:baseline}#woocommerce-product-data .hndle label:first-child{margin-right:1em;border-right:1px solid #dfdfdf}#woocommerce-product-data .hndle input,#woocommerce-product-data .hndle select{margin:-3px 0 0 .5em;vertical-align:middle}#woocommerce-product-data>.handlediv{margin-top:4px}#woocommerce-product-data .wrap{margin:0}#woocommerce-coupon-description{padding:3px 8px;font-size:1.7em;line-height:1.42em;height:auto;width:100%;outline:0;margin:10px 0;display:block}#woocommerce-coupon-description::-webkit-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description::-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-ms-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap{background:#fff}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{float:left;width:80%}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-product-data .woocommerce_options_panel .wc-radios{display:block;float:left;margin:0}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-product-data .woocommerce_options_panel .wc-radios li{display:block;padding:0 0 10px}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li input,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-product-data .woocommerce_options_panel .wc-radios li input{width:auto}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap,.woocommerce .panel-wrap{overflow:hidden}#woocommerce-coupon-data ul.wc-tabs,#woocommerce-product-data ul.wc-tabs,.woocommerce ul.wc-tabs{margin:0;width:20%;float:left;line-height:1em;padding:0 0 10px;position:relative;background-color:#fafafa;border-right:1px solid #eee;box-sizing:border-box}#woocommerce-coupon-data ul.wc-tabs:after,#woocommerce-product-data ul.wc-tabs:after,.woocommerce ul.wc-tabs:after{content:"";display:block;width:100%;height:9999em;position:absolute;bottom:-9999em;left:0;background-color:#fafafa;border-right:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li,#woocommerce-product-data ul.wc-tabs li,.woocommerce ul.wc-tabs li{margin:0;padding:0;display:block;position:relative}#woocommerce-coupon-data ul.wc-tabs li a,#woocommerce-product-data ul.wc-tabs li a,.woocommerce ul.wc-tabs li a{margin:0;padding:10px;display:block;box-shadow:none;text-decoration:none;line-height:20px!important;border-bottom:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li a:before,#woocommerce-product-data ul.wc-tabs li a:before,.woocommerce ul.wc-tabs li a:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}#woocommerce-coupon-data ul.wc-tabs li.general_options a:before,#woocommerce-product-data ul.wc-tabs li.general_options a:before,.woocommerce ul.wc-tabs li.general_options a:before{content:"\f107"}#woocommerce-coupon-data ul.wc-tabs li.inventory_options a:before,#woocommerce-product-data ul.wc-tabs li.inventory_options a:before,.woocommerce ul.wc-tabs li.inventory_options a:before{content:"\f481"}#woocommerce-coupon-data ul.wc-tabs li.shipping_options a:before,#woocommerce-product-data ul.wc-tabs li.shipping_options a:before,.woocommerce ul.wc-tabs li.shipping_options a:before{font-family:WooCommerce;content:"\e01a"}#woocommerce-coupon-data ul.wc-tabs li.linked_product_options a:before,#woocommerce-product-data ul.wc-tabs li.linked_product_options a:before,.woocommerce ul.wc-tabs li.linked_product_options a:before{content:"\f103"}#woocommerce-coupon-data ul.wc-tabs li.attribute_options a:before,#woocommerce-product-data ul.wc-tabs li.attribute_options a:before,.woocommerce ul.wc-tabs li.attribute_options a:before{content:"\f175"}#woocommerce-coupon-data ul.wc-tabs li.advanced_options a:before,#woocommerce-product-data ul.wc-tabs li.advanced_options a:before,.woocommerce ul.wc-tabs li.advanced_options a:before{font-family:Dashicons;content:"\f111"}#woocommerce-coupon-data ul.wc-tabs li.variations_options a:before,#woocommerce-product-data ul.wc-tabs li.variations_options a:before,.woocommerce ul.wc-tabs li.variations_options a:before{content:"\f509"}#woocommerce-coupon-data ul.wc-tabs li.usage_restriction_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_restriction_options a:before,.woocommerce ul.wc-tabs li.usage_restriction_options a:before{font-family:WooCommerce;content:"\e602"}#woocommerce-coupon-data ul.wc-tabs li.usage_limit_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_limit_options a:before,.woocommerce ul.wc-tabs li.usage_limit_options a:before{font-family:WooCommerce;content:"\e601"}#woocommerce-coupon-data ul.wc-tabs li.general_coupon_data a:before,#woocommerce-product-data ul.wc-tabs li.general_coupon_data a:before,.woocommerce ul.wc-tabs li.general_coupon_data a:before{font-family:WooCommerce;content:"\e600"}#woocommerce-coupon-data ul.wc-tabs li.active a,#woocommerce-product-data ul.wc-tabs li.active a,.woocommerce ul.wc-tabs li.active a{color:#555;position:relative;background-color:#eee}.woocommerce_page_wc-settings .shippingrows th.check-column{padding-top:20px}.woocommerce_page_wc-settings .shippingrows tfoot th{padding-left:10px}.woocommerce_page_wc-settings .shippingrows .add.button:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}.woocommerce_page_wc-settings h3.wc-settings-sub-title{font-size:1.2em}#woocommerce-coupon-data .inside,#woocommerce-order-data .inside,#woocommerce-order-downloads .inside,#woocommerce-product-data .inside,#woocommerce-product-type-options .inside{margin:0;padding:0}.panel,.woocommerce_options_panel{padding:9px;color:#555}.panel .form-field .woocommerce-help-tip,.woocommerce_options_panel .form-field .woocommerce-help-tip{font-size:1.4em}.panel,.woocommerce_page_settings .woocommerce_options_panel{padding:0}#woocommerce-product-specs .inside,#woocommerce-product-type-options .panel{margin:0;padding:9px}#woocommerce-product-type-options .panel p,.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p{margin:0 0 9px;font-size:12px;padding:5px 9px;line-height:24px}#woocommerce-product-type-options .panel p:after,.woocommerce_options_panel fieldset.form-field:after,.woocommerce_options_panel p:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce_options_panel .checkbox,.woocommerce_variable_attributes .checkbox{width:auto;margin:3px 0;vertical-align:middle}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{width:100%;padding:0!important}.woocommerce_options_panel .downloadable_files table th,.woocommerce_variations .downloadable_files table th{padding:7px 0 7px 7px!important}.woocommerce_options_panel .downloadable_files table th.sort,.woocommerce_variations .downloadable_files table th.sort{width:17px;padding:7px!important}.woocommerce_options_panel .downloadable_files table th .woocommerce-help-tip,.woocommerce_variations .downloadable_files table th .woocommerce-help-tip{font-size:1.1em;margin-left:0}.woocommerce_options_panel .downloadable_files table td,.woocommerce_variations .downloadable_files table td{vertical-align:middle!important;padding:4px 0 4px 7px!important;position:relative}.woocommerce_options_panel .downloadable_files table td:last-child,.woocommerce_variations .downloadable_files table td:last-child{padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td input.input_text,.woocommerce_variations .downloadable_files table td input.input_text{width:100%;float:none;min-width:0;margin:1px 0}.woocommerce_options_panel .downloadable_files table td .upload_file_button,.woocommerce_variations .downloadable_files table td .upload_file_button{width:auto;float:right;cursor:pointer}.woocommerce_options_panel .downloadable_files table td .delete,.woocommerce_variations .downloadable_files table td .delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.2em}.woocommerce_options_panel .downloadable_files table td .delete:before,.woocommerce_variations .downloadable_files table td .delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}.woocommerce_options_panel .downloadable_files table td .delete:hover:before,.woocommerce_variations .downloadable_files table td .delete:hover:before{color:#a00}.woocommerce_options_panel .downloadable_files table td.sort,.woocommerce_variations .downloadable_files table td.sort{width:17px;cursor:move;font-size:15px;text-align:center;background:#f9f9f9;padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td.sort:before,.woocommerce_variations .downloadable_files table td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_options_panel .downloadable_files table td.sort:hover:before,.woocommerce_variations .downloadable_files table td.sort:hover:before{color:#333}.woocommerce_variation h3 .sort{width:17px;height:26px;cursor:move;float:right;font-size:15px;font-weight:400;margin-right:.5em;visibility:hidden;text-align:center;vertical-align:middle}.woocommerce_variation h3 .sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:28px;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_variation h3 .sort:hover:before{color:#777}.woocommerce_variation h3:hover .sort,.woocommerce_variation.ui-sortable-helper .sort{visibility:visible}.woocommerce_options_panel{min-height:175px;box-sizing:border-box}.woocommerce_options_panel .downloadable_files{padding:0 9px 0 162px;position:relative;margin:9px 0}.woocommerce_options_panel .downloadable_files label{position:absolute;left:0;margin:0 0 0 12px;line-height:24px}.woocommerce_options_panel p{margin:9px 0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px 5px 162px!important}.woocommerce_options_panel .sale_price_dates_fields .short:first-of-type{margin-bottom:1em}.woocommerce_options_panel .sale_price_dates_fields .short:nth-of-type(2){clear:left}.woocommerce_options_panel label,.woocommerce_options_panel legend{float:left;width:150px;padding:0;margin:0 0 0 -150px}.woocommerce_options_panel label .req,.woocommerce_options_panel legend .req{font-weight:700;font-style:normal;color:#a00}.woocommerce_options_panel .description{padding:0;margin:0 0 0 7px;clear:none;display:inline}.woocommerce_options_panel .description-block{margin-left:0;display:block}.woocommerce_options_panel input,.woocommerce_options_panel select,.woocommerce_options_panel textarea{margin:0}.woocommerce_options_panel textarea{height:3.5em;line-height:1.5em;vertical-align:top}.woocommerce_options_panel input[type=text],.woocommerce_options_panel input[type=number],.woocommerce_options_panel input[type=email],.woocommerce_options_panel input[type=password]{width:50%;float:left}.woocommerce_options_panel input.button{width:auto;margin-left:8px}.woocommerce_options_panel select{float:left}.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:50%}.woocommerce_options_panel .sized{width:auto!important;margin-right:6px}.woocommerce_options_panel .options_group{border-top:1px solid #fff;border-bottom:1px solid #eee}.woocommerce_options_panel .options_group:first-child{border-top:0}.woocommerce_options_panel .options_group:last-child{border-bottom:0}.woocommerce_options_panel .options_group fieldset{margin:9px 0;font-size:12px;padding:5px 9px;line-height:24px}.woocommerce_options_panel .options_group fieldset label{width:auto;float:none}.woocommerce_options_panel .options_group fieldset ul{float:left;width:50%;margin:0;padding:0}.woocommerce_options_panel .options_group fieldset ul li{margin:0;width:auto}.woocommerce_options_panel .options_group fieldset ul li input{width:auto;float:none;margin-right:4px}.woocommerce_options_panel .options_group fieldset ul.wc-radios label{margin-left:0}.woocommerce_options_panel .dimensions_field .wrap{display:block;width:50%}.woocommerce_options_panel .dimensions_field .wrap input{width:30.75%;margin-right:3.8%}.woocommerce_options_panel .dimensions_field .wrap .last{margin-right:0}.woocommerce_options_panel.padded{padding:1em}#woocommerce-product-data input.dp-applied,.woocommerce_options_panel .select2-container{float:left}#grouped_product_options,#simple_product_options,#virtual_product_options{padding:12px;font-style:italic;color:#666}.wc-metaboxes-wrapper .toolbar{margin:0!important;border-top:1px solid #fff;border-bottom:1px solid #eee;padding:9px 12px!important}.wc-metaboxes-wrapper .toolbar:first-child{border-top:0}.wc-metaboxes-wrapper .toolbar:last-child{border-bottom:0}.wc-metaboxes-wrapper .toolbar .add_variation{float:right;margin-left:5px}.wc-metaboxes-wrapper .toolbar .cancel-variation-changes,.wc-metaboxes-wrapper .toolbar .save-variation-changes{float:left;margin-right:5px}.wc-metaboxes-wrapper p.toolbar{overflow:hidden;zoom:1}.wc-metaboxes-wrapper .expand-close{margin-right:2px;color:#777;font-size:12px;font-style:italic}.wc-metaboxes-wrapper .expand-close a{background:0 0;padding:0;font-size:12px;text-decoration:none}.wc-metaboxes-wrapper#product_attributes .expand-close{float:right;line-height:28px}.wc-metaboxes-wrapper .fr,.wc-metaboxes-wrapper button.add_variable_attribute{float:right;margin:0 0 0 6px}.wc-metaboxes-wrapper .wc-metaboxes{border-bottom:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox-sortable-placeholder{border-color:#bbb;background-color:#f5f5f5;margin-bottom:9px;border-width:1px;border-style:dashed}.wc-metaboxes-wrapper .wc-metabox{background:#fff;border-bottom:1px solid #eee;margin:0!important}.wc-metaboxes-wrapper .wc-metabox select{font-weight:400}.wc-metaboxes-wrapper .wc-metabox:last-of-type{border-bottom:0}.wc-metaboxes-wrapper .wc-metabox .handlediv{width:27px}.wc-metaboxes-wrapper .wc-metabox .handlediv:before{content:"\f142"!important;cursor:pointer;display:inline-block;font:400 20px/1 Dashicons;line-height:.5!important;padding:8px 10px;position:relative;right:12px;top:0}.wc-metaboxes-wrapper .wc-metabox.closed{border-radius:3px}.wc-metaboxes-wrapper .wc-metabox.closed .handlediv:before{content:"\f140"!important}.wc-metaboxes-wrapper .wc-metabox.closed h3{border:0}.wc-metaboxes-wrapper .wc-metabox h3{margin:0!important;padding:.75em .75em .75em 1em!important;font-size:1em!important;overflow:hidden;zoom:1;cursor:move}.wc-metaboxes-wrapper .wc-metabox h3 a.delete,.wc-metaboxes-wrapper .wc-metabox h3 button{float:right}.wc-metaboxes-wrapper .wc-metabox h3 a.delete{color:red;font-weight:400;line-height:26px;text-decoration:none;position:relative;visibility:hidden}.wc-metaboxes-wrapper .wc-metabox h3 strong{line-height:26px;font-weight:700}.wc-metaboxes-wrapper .wc-metabox h3 select{font-family:sans-serif;max-width:20%;margin:.25em .25em .25em 0}.wc-metaboxes-wrapper .wc-metabox h3 .handlediv{background-position:6px 5px!important;visibility:hidden;height:26px}.wc-metaboxes-wrapper .wc-metabox h3.fixed{cursor:pointer!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3{cursor:pointer;padding:.5em .75em .5em 1em!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .handlediv,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .sort,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 a.delete{margin-top:.25em}.wc-metaboxes-wrapper .wc-metabox h3:hover .handlediv,.wc-metaboxes-wrapper .wc-metabox h3:hover a.delete,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper .handlediv,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper a.delete{visibility:visible}.wc-metaboxes-wrapper .wc-metabox table{width:100%;position:relative;background-color:#fdfdfd;padding:1em;border-top:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox table td{text-align:left;padding:0 6px 1em 0;vertical-align:top;border:0}.wc-metaboxes-wrapper .wc-metabox table td label{text-align:left;display:block;line-height:21px}.wc-metaboxes-wrapper .wc-metabox table td input{float:left;min-width:200px}.wc-metaboxes-wrapper .wc-metabox table td input,.wc-metaboxes-wrapper .wc-metabox table td textarea{width:100%;margin:0;display:block;font-size:14px;padding:4px;color:#555}.wc-metaboxes-wrapper .wc-metabox table td .select2-container,.wc-metaboxes-wrapper .wc-metabox table td select{width:100%!important}.wc-metaboxes-wrapper .wc-metabox table td input.short{width:200px}.wc-metaboxes-wrapper .wc-metabox table td input.checkbox{width:16px;min-width:inherit;vertical-align:text-bottom;display:inline-block;float:none}.wc-metaboxes-wrapper .wc-metabox table td.attribute_name{width:200px}.wc-metaboxes-wrapper .wc-metabox table .minus,.wc-metaboxes-wrapper .wc-metabox table .plus{margin-top:6px}.wc-metaboxes-wrapper .wc-metabox table .fl{float:left}.wc-metaboxes-wrapper .wc-metabox table .fr{float:right}.variations-pagenav{float:right;line-height:24px}.variations-pagenav .displaying-num{color:#777;font-size:12px;font-style:italic}.variations-pagenav a{padding:0 10px 3px;background:rgba(0,0,0,.05);font-size:16px;font-weight:400;text-decoration:none}.variations-pagenav a.disabled,.variations-pagenav a.disabled:active,.variations-pagenav a.disabled:focus,.variations-pagenav a.disabled:hover{color:#A0A5AA;background:rgba(0,0,0,.05)}.variations-defaults{float:left}.variations-defaults select{margin:.25em .25em .25em 0}.woocommerce_variable_attributes{background-color:#fdfdfd;border-top:1px solid #eee}.woocommerce_variable_attributes .data{padding:1em 2em}.woocommerce_variable_attributes .data:after,.woocommerce_variable_attributes .data:before{content:" ";display:table}.woocommerce_variable_attributes .data:after{clear:both}.woocommerce_variable_attributes .upload_image_button{display:block;width:48px;height:48px;float:left;margin-right:20px;position:relative;cursor:pointer}.woocommerce_variable_attributes .upload_image_button img{width:100%;height:auto;display:none}.woocommerce_variable_attributes .upload_image_button:before{content:"\f128";font-family:Dashicons;position:absolute;top:0;left:0;right:0;bottom:0;text-align:center;line-height:48px;font-size:48px;font-weight:400;-webkit-font-smoothing:antialiased}.woocommerce_variable_attributes .upload_image_button.remove img{display:block}.woocommerce_variable_attributes .upload_image_button.remove:before{content:"\f335";display:none}.woocommerce_variable_attributes .upload_image_button.remove:hover:before{display:block}.woocommerce_variable_attributes .options{border:1px solid #eee;border-width:1px 0;padding:.25em 0}.woocommerce_variable_attributes .options label{display:inline-block;padding:4px 1em 2px 0}.woocommerce_variable_attributes .options input[type=checkbox]{margin-top:5px;margin-right:3px}.form-row label{display:block}.form-row input[type=number],.form-row input[type=text],.form-row select{width:100%}.form-row.dimensions_field input{width:25%;float:left;margin-right:1%}.form-row.dimensions_field input:last-of-type{margin-right:0}.form-row-first,.form-row-last{width:48%;float:right}.form-row-first{clear:both;float:left}.form-row-full{clear:both}.tips{cursor:help;text-decoration:none}img.tips{padding:5px 0 0}#tiptip_holder{display:none;position:absolute;top:0;left:0;z-index:9999999}#tiptip_holder.tip_top{padding-bottom:5px}#tiptip_holder.tip_top #tiptip_arrow_inner{margin-top:-7px;margin-left:-6px;border-top-color:#333}#tiptip_holder.tip_bottom{padding-top:5px}#tiptip_holder.tip_bottom #tiptip_arrow_inner{margin-top:-5px;margin-left:-6px;border-bottom-color:#333}#tiptip_holder.tip_right{padding-left:5px}#tiptip_holder.tip_right #tiptip_arrow_inner{margin-top:-6px;margin-left:-5px;border-right-color:#333}#tiptip_holder.tip_left{padding-right:5px}#tiptip_holder.tip_left #tiptip_arrow_inner{margin-top:-6px;margin-left:-7px;border-left-color:#333}#tiptip_content,.chart-tooltip,.wc_error_tip{color:#fff;font-size:.8em;max-width:150px;background:#333;text-align:center;border-radius:3px;padding:.618em 1em;box-shadow:0 1px 3px rgba(0,0,0,.2)}#tiptip_content code,.chart-tooltip code,.wc_error_tip code{padding:1px;background:#888}#tiptip_arrow,#tiptip_arrow_inner{position:absolute;border-color:transparent;border-style:solid;border-width:6px;height:0;width:0}.wc_error_tip{max-width:20em;line-height:1.8em;position:absolute;white-space:normal;background:#d82223;margin:1.5em 1px 0 -1em;z-index:9999999}.wc_error_tip:after{content:"";display:block;border:8px solid #d82223;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-3px;left:50%;margin:-1em 0 0 -3px}img.ui-datepicker-trigger{vertical-align:middle;margin-top:-1px;cursor:pointer}.wc-metabox-content img.ui-datepicker-trigger,.woocommerce_options_panel img.ui-datepicker-trigger{float:left;margin-right:8px;margin-top:4px;margin-left:4px}#ui-datepicker-div{display:none}.woocommerce-reports-wide.woocommerce-reports-wrap,.woocommerce-reports-wrap.woocommerce-reports-wrap{margin-left:300px;padding-top:18px}.woocommerce-reports-wide.halved,.woocommerce-reports-wrap.halved{margin:0;overflow:hidden;zoom:1}.woocommerce-reports-wide .widefat td,.woocommerce-reports-wrap .widefat td{vertical-align:top;padding:7px}.woocommerce-reports-wide .widefat td .description,.woocommerce-reports-wrap .widefat td .description{margin:4px 0 0}.woocommerce-reports-wide .postbox:after,.woocommerce-reports-wrap .postbox:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox h3,.woocommerce-reports-wrap .postbox h3{cursor:default!important}.woocommerce-reports-wide .postbox .inside,.woocommerce-reports-wrap .postbox .inside{padding:10px;margin:0!important}.woocommerce-reports-wide .postbox div.stats_range,.woocommerce-reports-wide .postbox h3.stats_range,.woocommerce-reports-wrap .postbox div.stats_range,.woocommerce-reports-wrap .postbox h3.stats_range{border-bottom-color:#dfdfdf;margin:0;padding:0!important}.woocommerce-reports-wide .postbox div.stats_range .export_csv,.woocommerce-reports-wide .postbox h3.stats_range .export_csv,.woocommerce-reports-wrap .postbox div.stats_range .export_csv,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv{float:right;line-height:26px;border-left:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range .export_csv:before,.woocommerce-reports-wide .postbox h3.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox div.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;content:"";text-decoration:none;margin-right:4px}.woocommerce-reports-wide .postbox div.stats_range ul,.woocommerce-reports-wide .postbox h3.stats_range ul,.woocommerce-reports-wrap .postbox div.stats_range ul,.woocommerce-reports-wrap .postbox h3.stats_range ul{list-style:none;margin:0;padding:0;zoom:1;background:#f5f5f5;border-bottom:1px solid #ccc}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox div.stats_range ul:before,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:before,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:before,.woocommerce-reports-wrap .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:before{content:" ";display:table}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:after{clear:both}.woocommerce-reports-wide .postbox div.stats_range ul li,.woocommerce-reports-wide .postbox h3.stats_range ul li,.woocommerce-reports-wrap .postbox div.stats_range ul li,.woocommerce-reports-wrap .postbox h3.stats_range ul li{float:left;margin:0;padding:0;line-height:26px;font-weight:700;font-size:14px}.woocommerce-reports-wide .postbox div.stats_range ul li a,.woocommerce-reports-wide .postbox h3.stats_range ul li a,.woocommerce-reports-wrap .postbox div.stats_range ul li a,.woocommerce-reports-wrap .postbox h3.stats_range ul li a{border-right:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range ul li.active,.woocommerce-reports-wide .postbox h3.stats_range ul li.active,.woocommerce-reports-wrap .postbox div.stats_range ul li.active,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active{background:#fff;-webkit-box-shadow:0 4px 0 0 #fff;box-shadow:0 4px 0 0 #fff}.woocommerce-reports-wide .postbox div.stats_range ul li.active a,.woocommerce-reports-wide .postbox h3.stats_range ul li.active a,.woocommerce-reports-wrap .postbox div.stats_range ul li.active a,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active a{color:#777}.woocommerce-reports-wide .postbox div.stats_range ul li.custom,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom{padding:9px 10px;vertical-align:middle}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form{display:inline;margin:0}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form input.range_datepicker{padding:0;margin:0 10px 0 0;background:0 0;border:0;color:#777;text-align:center;-webkit-box-shadow:none;box-shadow:none}.woocommerce-reports-wide .postbox .chart-with-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar{padding:12px 12px 12px 249px;margin:0!important}.woocommerce-reports-wide .postbox .chart-with-sidebar .chart-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar .chart-sidebar{width:225px;margin-left:-237px;float:left}.woocommerce-reports-wide .postbox .chart-widgets,.woocommerce-reports-wrap .postbox .chart-widgets{margin:0;padding:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget{margin:0 0 1em;background:#fafafa;border:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4{background:#fff;border:1px solid #dfdfdf;border-left-width:0;border-right-width:0;padding:10px;margin:0;color:#2ea2cc;border-top-width:0;background-image:-webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9));background-image:-webkit-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-moz-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-o-linear-gradient(bottom,#ececec,#f9f9f9);background-image:linear-gradient(to top,#ececec,#f9f9f9)}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr.active td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr.active td{background:#f5f5f5}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4.section_title:hover,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4.section_title:hover{color:#a00}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title{cursor:pointer}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span{display:block}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin-left:.618em;content:"";text-decoration:none;float:right;font-size:.9em;line-height:1.618}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open{color:#333}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open span:after{display:none}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section{border-bottom:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section .select2-container,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section .select2-container{width:100%!important}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section:last-of-type,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section:last-of-type{border-radius:0 0 3px 3px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td{padding:7px 10px;vertical-align:top;border-top:1px solid #e5e5e5;line-height:1.4em}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.sparkline,form.report_filters div,form.report_filters input,form.report_filters label,form.report_filters p{vertical-align:middle}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr:first-child td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr:first-child td{border-top:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name{max-width:175px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name a,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name a{word-wrap:break-word}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table .wc_sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table .wc_sparkline{width:32px;height:1em;display:block;float:right}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p{margin:0;padding:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p .submit{margin-top:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget #product_ids,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget #product_ids{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_none,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_none{float:right;color:#999;margin-left:4px;margin-top:10px}.woocommerce-reports-wide .postbox .chart-legend,.woocommerce-reports-wrap .postbox .chart-legend{list-style:none;margin:0 0 1em;padding:0;border:1px solid #dfdfdf;border-right-width:0;border-bottom-width:0;background:#fff}.woocommerce-reports-wide .postbox .chart-legend li,.woocommerce-reports-wrap .postbox .chart-legend li{border-right:5px solid #aaa;color:#aaa;padding:1em;display:block;margin:0;-webkit-transition:all ease .5s;box-shadow:inset 0 -1px 0 0 #dfdfdf}.woocommerce-reports-wide .postbox .chart-legend li strong,.woocommerce-reports-wrap .postbox .chart-legend li strong{font-size:1.618em;line-height:1.2em;color:#464646;font-weight:400;display:block;font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif}.woocommerce-reports-wide .postbox .chart-legend li strong del,.woocommerce-reports-wrap .postbox .chart-legend li strong del{color:#e74c3c;font-weight:400}.woocommerce-reports-wide .postbox .chart-legend li:hover,.woocommerce-reports-wrap .postbox .chart-legend li:hover{box-shadow:inset 0 -1px 0 0 #dfdfdf,inset 300px 0 0 rgba(156,93,144,.1);border-right:5px solid #9c5d90!important;padding-left:1.5em;color:#9c5d90}.woocommerce-reports-wide .postbox .pie-chart-legend,.woocommerce-reports-wrap .postbox .pie-chart-legend{margin:12px 0 0;overflow:hidden}.woocommerce-reports-wide .postbox .pie-chart-legend li,.woocommerce-reports-wrap .postbox .pie-chart-legend li{float:left;margin:0;padding:6px 0 0;border-top:4px solid #999;text-align:center;box-sizing:border-box;width:50%}.woocommerce-reports-wide .postbox .stat,.woocommerce-reports-wrap .postbox .stat{font-size:1.5em!important;font-weight:700;text-align:center}.woocommerce-reports-wide .postbox .chart-placeholder,.woocommerce-reports-wrap .postbox .chart-placeholder{width:100%;height:650px;overflow:hidden;position:relative}.woocommerce-reports-wide .postbox .chart-prompt,.woocommerce-reports-wrap .postbox .chart-prompt{line-height:650px;margin:0;color:#999;font-size:1.2em;font-style:italic;text-align:center}.woocommerce-reports-wide .postbox .chart-container,.woocommerce-reports-wrap .postbox .chart-container{background:#fff;padding:12px;position:relative;border:1px solid #dfdfdf;border-radius:3px}.woocommerce-reports-wide .postbox .main .chart-legend,.woocommerce-reports-wrap .postbox .main .chart-legend{margin-top:12px}.woocommerce-reports-wide .postbox .main .chart-legend li,.woocommerce-reports-wrap .postbox .main .chart-legend li{border-right:0;margin:0 8px 0 0;float:left;border-top:4px solid #aaa}.woocommerce-reports-wide .woocommerce-reports-main,.woocommerce-reports-wrap .woocommerce-reports-main{float:left;min-width:100%}.woocommerce-reports-wide .woocommerce-reports-main table td,.woocommerce-reports-wrap .woocommerce-reports-main table td{padding:9px}.woocommerce-reports-wide .woocommerce-reports-sidebar,.woocommerce-reports-wrap .woocommerce-reports-sidebar{display:inline;width:281px;margin-left:-300px;clear:both;float:left}.woocommerce-reports-wide .woocommerce-reports-left,.woocommerce-reports-wrap .woocommerce-reports-left{width:49.5%;float:left}.woocommerce-reports-wide .woocommerce-reports-right,.woocommerce-reports-wrap .woocommerce-reports-right{width:49.5%;float:right}.woocommerce-reports-wide .column-wc_actions a.edit,.woocommerce-reports-wide .column-wc_actions a.view,.woocommerce-reports-wrap .column-wc_actions a.edit,.woocommerce-reports-wrap .column-wc_actions a.view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;line-height:1.85}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after{content:"\f464"}.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{content:"\f177"}.woocommerce-wide-reports-wrap{padding-bottom:11px}.woocommerce-wide-reports-wrap .widefat .export-data{float:right}.woocommerce-wide-reports-wrap .widefat td,.woocommerce-wide-reports-wrap .widefat th{vertical-align:middle;padding:7px}.chart-tooltip{position:absolute;display:none;line-height:1}table.bar_chart{width:100%}table.bar_chart thead th{text-align:left;color:#ccc;padding:6px 0}table.bar_chart tbody th{padding:6px 0;width:25%;text-align:left!important;font-weight:400!important;border-bottom:1px solid #fee}table.bar_chart tbody td{text-align:right;line-height:24px;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td span{color:#8a4b75;display:block}table.bar_chart tbody td span.alt{color:#47a03e;margin-top:6px}table.bar_chart tbody td.bars{position:relative;text-align:left;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td.bars a,table.bar_chart tbody td.bars span{text-decoration:none;clear:both;background:#8a4b75;float:left;display:block;line-height:24px;height:24px;-moz-border-radius:3px;-webkit-border-radius:3px;-o-border-radius:3px;-khtml-border-radius:3px;border-radius:3px}.post-type-product .woocommerce-BlankState-message:before,.post-type-shop_coupon .woocommerce-BlankState-message:before,.post-type-shop_order .woocommerce-BlankState-message:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}table.bar_chart tbody td.bars span.alt{clear:both;background:#47a03e}table.bar_chart tbody td.bars span.alt span{margin:0;color:#c5dec2!important;text-shadow:0 1px 0 #47a03e;background:0 0}.post-type-shop_order .woocommerce-BlankState-message:before{content:""}.post-type-shop_coupon .woocommerce-BlankState-message:before{content:""}.post-type-product .woocommerce-BlankState-message:before{content:""}.woocommerce-BlankState{text-align:center;padding:5em 0 0}.woocommerce-BlankState .woocommerce-BlankState-message{color:#aaa;margin:0 auto 1.5em;line-height:1.5em;font-size:1.2em;max-width:500px}.woocommerce-BlankState .woocommerce-BlankState-message:before{color:#ddd;text-shadow:0 -1px 1px rgba(0,0,0,.2),0 1px 0 rgba(255,255,255,.8);font-size:8em;display:block;position:relative!important;top:auto;left:auto;line-height:1em;margin:0 0 .1875em}.woocommerce-BlankState .woocommerce-BlankState-cta{font-size:1.2em;padding:.75em 1.5em;height:auto}@media only screen and (max-width:1280px){#order_data .order_data_column{width:48%}#order_data .order_data_column:first-child{width:100%}.woocommerce_options_panel .description{display:block;clear:both;margin-left:0}.woocommerce_options_panel .dimensions_field .wrap,.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:80%}.woocommerce_options_panel .downloadable_files,.woocommerce_variations .downloadable_files{padding:0;clear:both}.woocommerce_options_panel .downloadable_files label,.woocommerce_variations .downloadable_files label{position:static}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{margin:0 12px 24px;width:94%}.woocommerce_options_panel .downloadable_files table .sort,.woocommerce_variations .downloadable_files table .sort{visibility:hidden}.woocommerce_options_panel .woocommerce_variable_attributes .downloadable_files table,.woocommerce_variations .woocommerce_variable_attributes .downloadable_files table{margin:0 0 1em;width:100%}}@media only screen and (max-width:900px){#woocommerce-coupon-data ul.coupon_data_tabs,#woocommerce-product-data .wc-tabs-back,#woocommerce-product-data ul.product_data_tabs{width:10%}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{width:90%}#woocommerce-coupon-data ul.coupon_data_tabs li a,#woocommerce-product-data ul.product_data_tabs li a{position:relative;text-indent:-999px;padding:10px}#woocommerce-coupon-data ul.coupon_data_tabs li a:before,#woocommerce-product-data ul.product_data_tabs li a:before{position:absolute;top:0;right:0;bottom:0;left:0;text-indent:0;text-align:center;line-height:40px;width:100%;height:40px}}@media only screen and (max-width:782px){#wp-excerpt-media-buttons a{font-size:16px;line-height:37px;height:39px;padding:0 20px 0 15px}#wp-excerpt-editor-tools{padding-top:20px;padding-right:15px;overflow:hidden;margin-bottom:-1px}.post-type-product .wp-list-table .is-expanded td:not(.hidden),.post-type-shop_order .wp-list-table .is-expanded td:not(.hidden){overflow:visible}#woocommerce-product-data .checkbox{width:25px}.variations-pagenav{float:none;text-align:center;font-size:18px}.variations-pagenav .displaying-num{font-size:16px}.variations-pagenav a{padding:8px 20px 11px;font-size:18px}.variations-pagenav select{padding:0 20px}.variations-defaults{float:none;text-align:center;margin-top:10px}.post-type-product .wp-list-table .column-thumb{display:none;text-align:left;padding-bottom:0}.post-type-product .wp-list-table .column-thumb:before{display:none!important}.post-type-product .wp-list-table .column-thumb img{max-width:32px}.post-type-product .wp-list-table .toggle-row{top:-28px}.post-type-shop_order .wp-list-table .column-order_status{display:none;text-align:left;padding-bottom:0}.post-type-shop_order .wp-list-table .column-order_status mark{margin:0}.post-type-shop_order .wp-list-table .column-order_status:before{display:none!important}.post-type-shop_order .wp-list-table .column-customer_message,.post-type-shop_order .wp-list-table .column-order_notes{text-align:inherit}.post-type-shop_order .wp-list-table .column-order_notes .note-on{font-size:1.3em;margin:0}.post-type-shop_order .wp-list-table .toggle-row{top:-15px}}@media only screen and (max-width:500px){.woocommerce_options_panel label,.woocommerce_options_panel legend{float:none;width:auto;display:block;margin:0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px!important}}.wc-backbone-modal *{box-sizing:border-box}.wc-backbone-modal .wc-backbone-modal-content{position:fixed;background:#fff;z-index:100000;left:50%;top:50%;transform:translate(-50%,-50%);width:500px}.wc-backbone-modal .wc-backbone-modal-content article{overflow:auto}.wc-backbone-modal.wc-backbone-modal-shipping-method-settings .wc-backbone-modal-content{width:75%;min-width:500px}.wc-backbone-modal-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;min-height:360px;background:#000;opacity:.7;z-index:99900}.wc-backbone-modal-main{padding-bottom:55px}.wc-backbone-modal-main article,.wc-backbone-modal-main header{display:block;position:relative}.wc-backbone-modal-main .wc-backbone-modal-header{height:auto;background:#fcfcfc;padding:1em 1.5em;border-bottom:1px solid #ddd}.wc-backbone-modal-main .wc-backbone-modal-header h1{margin:0;font-size:18px;font-weight:700;line-height:1.5em}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link{cursor:pointer;color:#777;height:54px;width:54px;padding:0;position:absolute;top:0;right:0;text-align:center;border:0;border-left:1px solid #ddd;background-color:transparent;-webkit-transition:color .1s ease-in-out,background .1s ease-in-out;transition:color .1s ease-in-out,background .1s ease-in-out}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:before{font:400 22px/50px dashicons!important;color:#666;display:block;content:'\f335';font-weight:300}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus,.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:hover{background:#ddd;border-color:#ccc;color:#000}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus{outline:0}.wc-backbone-modal-main article{padding:1.5em}.wc-backbone-modal-main article p{margin:1.5em 0}.wc-backbone-modal-main article p:last-child,.wc-backbone-modal-main footer .inner .button{margin-bottom:0}.wc-backbone-modal-main article p:first-child{margin-top:0}.wc-backbone-modal-main article .pagination{padding:10px 0 0;text-align:center}.wc-backbone-modal-main footer{position:absolute;left:0;right:0;bottom:0;z-index:100;padding:1em 1.5em;background:#fcfcfc;border-top:1px solid #dfdfdf;box-shadow:0 -4px 4px -4px rgba(0,0,0,.1)}.wc-backbone-modal-main footer .inner{float:right;line-height:23px}.select2-drop{z-index:999999!important}.select2-container-multi .select2-choices .select2-search-field input{font-family:inherit;font-size:inherit;font-weight:inherit;padding:3px 5px}.select2-container{line-height:1.85em;font-size:14px} \ No newline at end of file +@charset "UTF-8";.button.wc-reload:after,.woocommerce-help-tip:after{speak:none;text-transform:none;-webkit-font-smoothing:antialiased}@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg)}}@-moz-keyframes spin{100%{-moz-transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}.select2-container{margin:0;position:relative;display:block!important;zoom:1;vertical-align:middle}.select2-container,.select2-drop,.select2-search,.select2-search input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{display:block;padding:0 0 0 8px;overflow:hidden;position:relative;border:1px solid #ccc;white-space:nowrap;color:#444;text-decoration:none;border-radius:3px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;font-weight:400}html[dir=rtl] .select2-container .select2-choice{padding:0 8px 0 0}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#ccc;border-radius:0 0 4px 4px}.select2-container.select2-allowclear .select2-choice .select2-chosen{margin-right:42px}.select2-container .select2-choice>.select2-chosen{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:none;width:auto}html[dir=rtl] .select2-container .select2-choice>.select2-chosen{margin-left:26px;margin-right:0}.select2-container .select2-choice abbr{display:none;width:12px;height:12px;position:absolute;right:24px;top:5px;font-size:1px;text-decoration:none;border:0;background:url(../images/select2.png) right top no-repeat;cursor:pointer;outline:0}.select2-container.select2-allowclear .select2-choice abbr{display:inline-block}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop-mask{border:0;margin:0;padding:0;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:9998;background-color:#fff;filter:alpha(opacity=0)}.select2-drop{width:100%;margin-top:-1px;position:absolute;top:100%;background:#fff;color:#000;border:1px solid #ccc;border-top:0;border-radius:0 0 3px 3px}.select2-drop.select2-drop-above{margin-top:1px;border-top:1px solid #ccc;border-bottom:0;border-radius:3px 3px 0 0}.select2-drop-active{border:1px solid #666;border-top:none}.select2-drop.select2-drop-above.select2-drop-active{border-top:1px solid #666}.select2-drop-auto-width{border-top:1px solid #ccc;width:auto}.select2-drop-auto-width .select2-search{padding-top:4px}.select2-container .select2-choice .select2-arrow{display:inline-block;width:18px;height:100%;position:absolute;right:0;top:0;border-radius:0 3px 3px 0;background-clip:padding-box}html[dir=rtl] .select2-container .select2-choice .select2-arrow{left:0;right:auto;border-radius:3px 0 0 3px}.select2-container .select2-choice .select2-arrow b{display:block;width:100%;height:100%;position:relative}.select2-container .select2-choice .select2-arrow b:after{position:absolute;display:block;content:"";top:50%;left:50%;border:4px solid transparent;border-top-color:#666;margin-left:-7px;margin-top:-2px}.select2-search{display:inline-block;width:100%;margin:0;padding-left:4px;padding-right:4px;position:relative;z-index:10000;white-space:nowrap;padding-bottom:4px}.select2-search input{width:100%;height:auto!important;padding:4px 20px 4px 5px!important;margin:0;outline:0;font-family:sans-serif;font-size:1em;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none;background:url(../images/select2.png) 100% -22px no-repeat #fff}html[dir=rtl] .select2-search input{padding:4px 5px 4px 20px;background:url(../images/select2.png) -37px -22px no-repeat #fff}.select2-drop.select2-drop-above .select2-search input{margin-top:4px}.select2-search input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff}.select2-container-active .select2-choice,.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-dropdown-open .select2-choice{border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-dropdown-open .select2-choice .select2-arrow b:after{border-top-color:transparent;border-bottom-color:#666;margin-top:-6px}.select2-dropdown-open.select2-drop-above .select2-choice,.select2-dropdown-open.select2-drop-above .select2-choices{border:1px solid #666;border-top-color:transparent}.select2-dropdown-open .select2-choice .select2-arrow{background:0 0;border-left:none;filter:none}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow{border-right:none}.select2-dropdown-open .select2-choice .select2-arrow b{background-position:-18px 1px}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow b{background-position:-16px 1px}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.select2-results{max-height:200px;padding:4px;margin:0;position:relative;overflow-x:hidden;overflow-y:auto;-webkit-tap-highlight-color:transparent;background:#fafafa}html[dir=rtl] .select2-results{padding:0 4px 0 0;margin:4px 0 4px 4px}.select2-results ul.select2-result-sub{margin:0;padding-left:0}.select2-results li{list-style:none;display:list-item;background-image:none;margin:3px 0}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:700}.select2-results .select2-result-label{padding:5px 7px;margin:0;cursor:pointer;min-height:1em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select2-results-dept-1 .select2-result-label{padding-left:20px}.select2-results-dept-2 .select2-result-label{padding-left:40px}.select2-results-dept-3 .select2-result-label{padding-left:60px}.select2-results-dept-4 .select2-result-label{padding-left:80px}.select2-results-dept-5 .select2-result-label{padding-left:100px}.select2-results-dept-6 .select2-result-label{padding-left:110px}.select2-results-dept-7 .select2-result-label{padding-left:120px}.select2-results .select2-highlighted{background:#f1f1f1;color:#000;border-radius:3px}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:0 0}.select2-results .select2-highlighted ul{background:#fff;color:#000}.select2-results .select2-ajax-error,.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item;padding-left:5px}.select2-results .select2-disabled.select2-highlighted{color:#666;background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-disabled{background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-selected{display:none}.select2-more-results.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #f4f4f4}.select2-results .select2-ajax-error{background:rgba(255,50,50,.2)}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice .select2-arrow{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container.select2-container-disabled .select2-choice abbr{display:none}.select2-container-multi .select2-choices{height:auto!important;height:1%;margin:0;padding:0 5px 0 0;position:relative;border:1px solid #ccc;cursor:text;overflow:hidden;background-color:#fff;min-height:26px}html[dir=rtl] .select2-container-multi .select2-choices{padding:0 0 0 5px}.select2-locked{padding:3px 5px!important}.select2-container-multi.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-container-multi .select2-choices li{float:left;list-style:none}html[dir=rtl] .select2-container-multi .select2-choices li{float:right}.select2-container-multi .select2-choices .select2-search-field{margin:0;padding:0;white-space:nowrap}.select2-container-multi .select2-choices .select2-search-field:first-child{width:100%}.select2-container-multi .select2-choices .select2-search-field input{margin:1px 0;outline:0;border:0;-webkit-box-shadow:none;box-shadow:none;background:0 0!important}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff!important}.select2-default{color:#999!important}.select2-container-multi .select2-choices .select2-search-choice{padding:5px 8px 5px 24px;margin:3px 0 3px 5px;position:relative;line-height:15px;color:#333;cursor:default;border-radius:2px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#e4e4e4}html[dir=rtl] .select2-container-multi .select2-choices .select2-search-choice{margin:3px 5px 3px 0;padding:5px 24px 5px 8px}.select2-container-multi .select2-choices .select2-search-choice .select2-chosen{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;width:12px;height:13px;position:absolute;right:7px;top:6px;font-size:1px;outline:0;background:url(../images/select2.png) right top no-repeat}html[dir=rtl] .select2-search-choice-close{right:auto;left:7px}.select2-container-multi .select2-search-choice-close{left:7px}html[dir=rtl] .select2-container-multi .select2-search-choice-close{left:auto;right:7px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover,.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{padding:3px 5px;border:1px solid #ddd;background-image:none;background-color:#f4f4f4}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none;background:0 0}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-match{text-decoration:underline}.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.select2-display-none{display:none}.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:2dppx){.select2-search input{background-image:url(../images/select2x2.png)!important;background-repeat:no-repeat!important;background-size:60px 40px!important;background-position:100% -21px!important}}@font-face{font-family:star;src:url(../fonts/star.eot);src:url(../fonts/star.eot?#iefix) format("embedded-opentype"),url(../fonts/star.woff) format("woff"),url(../fonts/star.ttf) format("truetype"),url(../fonts/star.svg#star) format("svg");font-weight:400;font-style:normal}@font-face{font-family:WooCommerce;src:url(../fonts/WooCommerce.eot);src:url(../fonts/WooCommerce.eot?#iefix) format("embedded-opentype"),url(../fonts/WooCommerce.woff) format("woff"),url(../fonts/WooCommerce.ttf) format("truetype"),url(../fonts/WooCommerce.svg#WooCommerce) format("svg");font-weight:400;font-style:normal}.blockUI.blockOverlay:before{height:1em;width:1em;position:absolute;top:50%;left:50%;margin-left:-.5em;margin-top:-.5em;display:block;content:"";-webkit-animation:spin 1s ease-in-out infinite;-moz-animation:spin 1s ease-in-out infinite;animation:spin 1s ease-in-out infinite;background:url(../images/icons/loader.svg) center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75)}.wc_addons_wrap .products{overflow:hidden}.wc_addons_wrap .products li{float:left;margin:0 1em 1em 0!important;padding:0;vertical-align:top;width:300px}.wc_addons_wrap .products li a{text-decoration:none;color:inherit;border:1px solid #ddd;display:block;min-height:220px;overflow:hidden;background:#f5f5f5;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1)}.wc_addons_wrap .products li a img{max-width:258px;max-height:24px;padding:17px 20px;display:block;margin:0;background:#fff;border-right:260px solid #fff}.wc_addons_wrap .products li a .price,.wc_addons_wrap .products li a img.extension-thumb+h3{display:none}.wc_addons_wrap .products li a h2,.wc_addons_wrap .products li a h3{margin:0!important;padding:20px!important;background:#fff}.wc_addons_wrap .products li a p{padding:20px!important;margin:0!important;border-top:1px solid #f1f1f1}.wc_addons_wrap .products li a:focus,.wc_addons_wrap .products li a:hover{background-color:#fff}.wc_addons_wrap .storefront{background:url(../images/storefront-bg.jpg) bottom right #f6f6f6;border:1px solid #ddd;padding:20px;overflow:hidden;zoom:1}.wc_addons_wrap .storefront img{width:278px;height:auto;float:left;margin:0 20px 0 0;box-shadow:0 1px 6px rgba(0,0,0,.1)}.wc_addons_wrap .storefront p{max-width:750px}.woocommerce-BlankState a.button-primary,.woocommerce-BlankState button.button-primary,.woocommerce-message a.button-primary,.woocommerce-message button.button-primary{background:#bb77ae;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;color:#fff;text-shadow:0 -1px 1px #A36597,1px 0 1px #A36597,0 1px 1px #A36597,-1px 0 1px #A36597}.woocommerce-BlankState a.button-primary:active,.woocommerce-BlankState a.button-primary:focus,.woocommerce-BlankState a.button-primary:hover,.woocommerce-BlankState button.button-primary:active,.woocommerce-BlankState button.button-primary:focus,.woocommerce-BlankState button.button-primary:hover,.woocommerce-message a.button-primary:active,.woocommerce-message a.button-primary:focus,.woocommerce-message a.button-primary:hover,.woocommerce-message button.button-primary:active,.woocommerce-message button.button-primary:focus,.woocommerce-message button.button-primary:hover{background:#A36597;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597}.woocommerce-message{position:relative;border-left-color:#cc99c2!important;overflow:hidden}.woocommerce-message a.docs,.woocommerce-message a.skip{text-decoration:none!important}.woocommerce-message a.woocommerce-message-close{position:absolute;top:10px;right:10px;padding:10px 15px 10px 21px;font-size:13px;line-height:1.23076923;text-decoration:none}.woocommerce-message a.woocommerce-message-close:before{position:absolute;top:8px;left:0;-webkit-transition:all .1s ease-in-out;transition:all .1s ease-in-out}.woocommerce-message .twitter-share-button{margin-top:-3px;margin-left:3px;vertical-align:middle}#variable_product_options #message,#variable_product_options .notice{margin:10px}.clear{clear:both}#woocommerce-fields-bulk.inline-edit-col label,#woocommerce-fields.inline-edit-col{clear:left}.wrap.woocommerce div.error,.wrap.woocommerce div.updated{margin-top:10px}mark.amount{background:0 0;color:inherit}.postbox,.woocommerce{input:invalid;input-border:1px solid #cc010b;input-background:#ffebe8}.simplify-commerce-banner{overflow:hidden}.simplify-commerce-banner img{float:right;padding:15px 0;margin-left:1em;width:200px}.woocommerce-help-tip{color:#666;display:inline-block;font-size:1.1em;font-style:normal;height:16px;line-height:16px;position:relative;vertical-align:middle;width:16px}.woocommerce-help-tip:after{font-family:Dashicons;font-weight:400;font-variant:normal;line-height:1;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";cursor:help}h2 .woocommerce-help-tip{margin-top:-5px;margin-left:.25em}table.wc_status_table{margin-bottom:1em}table.wc_status_table h2{font-size:14px;margin:0}table.wc_status_table tr:nth-child(2n) td,table.wc_status_table tr:nth-child(2n) th{background:#fcfcfc}table.wc_status_table th{font-weight:700;padding:9px}table.wc_status_table td:first-child{width:33%}table.wc_status_table td.help{width:1em}table.wc_status_table td{padding:9px;font-size:1.1em}table.wc_status_table td mark{background:0 0}table.wc_status_table td mark.yes{color:#7ad03a}table.wc_status_table td mark.no{color:#999}table.wc_status_table td mark.error{color:#a00}table.wc_status_table td ul{margin:0}table.wc_status_table .help_tip{cursor:help}#debug-report{display:none;margin:10px 0;padding:0;position:relative}#debug-report textarea{font-family:monospace;width:100%;margin:0;height:300px;padding:20px;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;resize:none;font-size:12px;line-height:20px;outline:0}#log-viewer-select{padding:10px 0 8px;line-height:180%}#log-viewer textarea{width:100%;resize:vertical}.inline-edit-product.quick-edit-row .inline-edit-col-center,.inline-edit-product.quick-edit-row .inline-edit-col-right{float:right!important}#woocommerce-fields.inline-edit-col label.featured,#woocommerce-fields.inline-edit-col label.manage_stock{margin-left:10px}#woocommerce-fields.inline-edit-col .dimensions div{display:block;margin:.2em 0}#woocommerce-fields.inline-edit-col .dimensions div span.title{display:block;float:left;width:5em}#woocommerce-fields.inline-edit-col .dimensions div span.input-text-wrap{display:block;margin-left:5em}#woocommerce-fields.inline-edit-col .text{box-sizing:border-box;width:99%;float:left;margin:1px 1% 1px 1px}#woocommerce-fields.inline-edit-col .height,#woocommerce-fields.inline-edit-col .length,#woocommerce-fields.inline-edit-col .width{width:32.33%}#woocommerce-fields.inline-edit-col .height{margin-right:0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group label{clear:none;width:49%;margin:.2em 0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group.dimensions label{width:75%;max-width:75%}#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .regular_price,#woocommerce-fields-bulk.inline-edit-col .sale_price,#woocommerce-fields-bulk.inline-edit-col .stock,#woocommerce-fields-bulk.inline-edit-col .weight{box-sizing:border-box;width:100%;margin-left:4.4em}#woocommerce-fields-bulk.inline-edit-col .height,#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .width{box-sizing:border-box;width:25%}.column-coupon_code{line-height:2.25em}.column-coupon_code,ul.wc_coupon_list{margin:0;overflow:hidden;zoom:1;clear:both}ul.wc_coupon_list li{margin:0}ul.wc_coupon_list li.code{display:inline-block}ul.wc_coupon_list li.code:after{content:", "}ul.wc_coupon_list li.code:last-of-type:after{display:none}ul.wc_coupon_list li.code .tips{cursor:pointer}ul.wc_coupon_list_block{margin:0;padding-bottom:2px}ul.wc_coupon_list_block li{border-top:1px solid #fff;border-bottom:1px solid #ccc;line-height:2.5em;margin:0;padding:.5em 0}ul.wc_coupon_list_block li:first-child{border-top:0;padding-top:0}ul.wc_coupon_list_block li:last-child{border-bottom:0;padding-bottom:0}.button.wc-reload{text-indent:-9999px;position:relative;padding:0;height:28px;width:28px!important;display:inline-block}.button.wc-reload:after{font-family:Dashicons;font-weight:400;font-variant:normal;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:28px}#order_data h2,#order_data p.order_number{font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif;font-weight:400}.tablenav .actions{overflow:visible}.tablenav .select2-container{float:left;max-width:200px;font-size:14px;vertical-align:middle;margin:1px 6px 1px 1px}#woocommerce-order-data .handlediv,#woocommerce-order-data .hndle{display:none}#woocommerce-order-data .inside{display:block!important}#order_data{padding:23px 24px 12px}#order_data h2{margin:0;font-size:21px;line-height:1.2;text-shadow:1px 1px 1px #fff;padding:0}#order_data h3{font-size:14px}#order_data h3,#order_data h4{color:#333;margin:1.33em 0 0}#order_data p{color:#777}#order_data p.order_number{margin:0;line-height:1.6em;font-size:16px}#order_data .order_data_column_container{clear:both}#order_data .order_data_column{width:32%;padding:0 2% 0 0;float:left}#order_data .order_data_column:last-child{padding-right:0}#order_data .order_data_column p{padding:0!important}#order_data .order_data_column .address strong{display:block}#order_data .order_data_column .form-field{float:left;width:48%;padding:0;margin:9px 0 0}#order_data .order_data_column .form-field label{display:block;padding:0 0 3px}#order_data .order_data_column .form-field input,#order_data .order_data_column .form-field select,#order_data .order_data_column .form-field textarea{width:100%}#order_data .order_data_column .form-field .select2-container{width:100%!important}#order_data .order_data_column .form-field .date-picker{width:50%}#order_data .order_data_column .form-field .hour,#order_data .order_data_column .form-field .minute{width:3em}#order_data .order_data_column .form-field small{display:block;margin:5px 0 0;color:#999}#order_data .order_data_column .form-field.last{float:right}#order_data .order_data_column .form-field-wide{width:100%;clear:both}#order_data .order_data_column .form-field-wide .wc-customer-search,#order_data .order_data_column .form-field-wide .wc-enhanced-select,#order_data .order_data_column .form-field-wide input,#order_data .order_data_column .form-field-wide select,#order_data .order_data_column .form-field-wide textarea{width:100%}#order_data .order_data_column p.none_set{color:#999}#order_data .order_data_column ._billing_address_1_field,#order_data .order_data_column ._billing_city_field,#order_data .order_data_column ._billing_country_field,#order_data .order_data_column ._billing_email_field,#order_data .order_data_column ._billing_first_name_field,#order_data .order_data_column ._shipping_address_1_field,#order_data .order_data_column ._shipping_city_field,#order_data .order_data_column ._shipping_country_field,#order_data .order_data_column ._shipping_first_name_field{float:left}#order_data .order_data_column ._billing_address_2_field,#order_data .order_data_column ._billing_last_name_field,#order_data .order_data_column ._billing_phone_field,#order_data .order_data_column ._billing_postcode_field,#order_data .order_data_column ._billing_state_field,#order_data .order_data_column ._shipping_address_2_field,#order_data .order_data_column ._shipping_last_name_field,#order_data .order_data_column ._shipping_postcode_field,#order_data .order_data_column ._shipping_state_field,#order_data .order_data_column .wc-customer-user label a,#order_data .order_data_column .wc-order-status label a{float:right}#order_data .order_data_column ._billing_company_field,#order_data .order_data_column ._shipping_company_field,#order_data .order_data_column ._transaction_id_field{clear:both;width:100%}#order_data .order_data_column ._billing_email_field{clear:left}#order_data .order_data_column div.edit_address{display:none;zoom:1;padding-right:1px}#order_data .order_data_column .billing-same-as-shipping,#order_data .order_data_column .load_customer_billing,#order_data .order_data_column .load_customer_shipping,#order_data .order_data_column a.edit_address{width:14px;height:0;padding:14px 0 0;margin:0 0 0 6px;overflow:hidden;position:relative;color:#999;border:0;float:right}#order_data .order_data_column .billing-same-as-shipping:focus,#order_data .order_data_column .billing-same-as-shipping:hover,#order_data .order_data_column .load_customer_billing:focus,#order_data .order_data_column .load_customer_billing:hover,#order_data .order_data_column .load_customer_shipping:focus,#order_data .order_data_column .load_customer_shipping:hover,#order_data .order_data_column a.edit_address:focus,#order_data .order_data_column a.edit_address:hover{color:#000}#order_data .order_data_column .billing-same-as-shipping:after,#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after,#order_data .order_data_column a.edit_address: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}#order_data .order_data_column .billing-same-as-shipping:after{content:"\e008"}#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after{content:"\e03a"}#order_data .order_data_column a.edit_address:after{font-family:Dashicons;content:"\f464"}.order_actions{margin:0;overflow:hidden;zoom:1}.order_actions li{border-top:1px solid #fff;border-bottom:1px solid #ddd;padding:6px 0;margin:0;line-height:1.6em;float:left;width:50%;text-align:center}.order_actions li a{float:none;text-align:center;text-decoration:underline}.order_actions li.wide{width:auto;float:none;clear:both;padding:6px;text-align:left;overflow:hidden}.order_actions li #delete-action{line-height:25px;vertical-align:middle;text-align:left;float:left}.order_actions li .save_order{float:right}.order_actions li#actions{overflow:hidden}.order_actions li#actions .button{width:24px;box-sizing:border-box;float:right}.order_actions li#actions select{width:225px;box-sizing:border-box;float:left}#woocommerce-order-items .inside{margin:0;padding:0;background:#fefefe}#woocommerce-order-items .wc-order-data-row{border-bottom:1px solid #DFDFDF;padding:1.5em 2em;background:#f8f8f8;line-height:2em;text-align:right}#woocommerce-order-items .wc-order-data-row:after,#woocommerce-order-items .wc-order-data-row:before{content:" ";display:table}#woocommerce-order-items .wc-order-data-row:after{clear:both}#woocommerce-order-items .wc-order-data-row p{margin:0;line-height:2em}#woocommerce-order-items .wc-order-data-row .wc-used-coupons{text-align:left}#woocommerce-order-items .wc-order-data-row .wc-used-coupons .tips{display:inline-block}#woocommerce-order-items .wc-order-add-item{background:#fff;vertical-align:top;border-top:none}#woocommerce-order-items .wc-order-add-item .add_item_id,#woocommerce-order-items .wc-order-add-item .select2-container{vertical-align:top}#woocommerce-order-items .wc-order-add-item .add_item_id .search-field input,#woocommerce-order-items .wc-order-add-item .select2-container .search-field input{min-width:100px}#woocommerce-order-items .wc-order-add-item .select2-container{width:400px!important;text-align:left}#woocommerce-order-items .wc-order-add-item .calculate-action,#woocommerce-order-items .wc-order-add-item .cancel-action,#woocommerce-order-items .wc-order-add-item .save-action{float:left;margin-right:2px}#woocommerce-order-items .wc-used-coupons{float:left;width:50%}#woocommerce-order-items .wc-order-totals{float:right;width:50%;margin:0;padding:0;text-align:right}#woocommerce-order-items .wc-order-totals .amount{font-weight:700}#woocommerce-order-items .wc-order-totals .label{vertical-align:top}#woocommerce-order-items .wc-order-totals .total{font-size:1em!important;width:10em;margin:0 0 0 .5em;box-sizing:border-box}#woocommerce-order-items .wc-order-totals .total input[type=text]{width:96%;float:right}#woocommerce-order-items .wc-order-totals .refunded-total{color:#a00}#woocommerce-order-items .refund-actions{margin-top:5px;padding-top:12px;border-top:1px solid #DFDFDF}#woocommerce-order-items .refund-actions .button{float:right;margin-left:4px}#woocommerce-order-items .refund-actions .cancel-action,#woocommerce-order-items .wc-order-item-bulk-edit .cancel-action{float:left;margin-left:0}#woocommerce-order-items .add_meta{margin-left:0!important}#woocommerce-order-items h3 small{color:#999}#woocommerce-order-items .amount{white-space:nowrap}#woocommerce-order-items .add-items .description{margin-right:10px}#woocommerce-order-items .add-items .button{float:left;margin-right:.25em}#woocommerce-order-items .add-items .button-primary{float:none;margin-right:0}#woocommerce-order-items .inside{display:block!important}#woocommerce-order-items .handlediv,#woocommerce-order-items .hndle{display:none}#woocommerce-order-items .woocommerce_order_items_wrapper{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items{width:100%;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th{text-align:left;padding:1em;font-weight:400;color:#999;background:#f8f8f8;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th.sortable{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th .wc-arrow{float:right;position:relative;margin-right:-1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td{padding:1.5em 1em 1em;text-align:left;line-height:1.5em;vertical-align:top;border-bottom:1px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td select{width:50%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{font-size:14px;padding:4px;color:#555}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr td{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected{background:#F5EBF3}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected td{border-color:#E6CCE1;opacity:.8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:last-child td{border-bottom:1px solid #dfdfdf}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:first-child td{border-top:8px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody#order_line_items tr:first-child td{border-top:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb{text-align:left;width:38px;padding-bottom:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail{width:38px;height:38px;border:2px solid #e8e8e8;background:#f8f8f8;color:#ccc;position:relative;font-size:21px;display:block;text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;height:100%;text-align:center;content:"";width:38px;line-height:38px;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail img{width:100%;height:100%;margin:0;padding:0;position:relative}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-sku,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-variation{display:block;margin-top:.5em;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item{min-width:200px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .center,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .variation-id{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class{text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label{white-space:nowrap;color:#999;font-size:.833em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label input{display:inline}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class input{width:70px;vertical-align:middle;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class select{width:85px;height:26px;vertical-align:middle;font-size:1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input{display:inline-block;background:#fff;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);margin:1px 0;min-width:80px;overflow:hidden;line-height:1em;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input{width:100%;box-sizing:border-box}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input label{font-size:.75em;padding:4px 6px 0;color:#555;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input{width:100%;box-sizing:border-box;border:0;box-shadow:none;margin:0;padding:0 6px 4px;color:#555;background:0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input::-webkit-input-placeholder{color:#ddd}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child{border-bottom:1px dashed #ddd;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child label{color:#ccc}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .view{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .edit{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes label{display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount{display:block;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{margin-right:.25em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input{text-align:center;width:50px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items span.subtotal{opacity:.5}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.tax_class,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.tax_class{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .calculated{border-color:#ae8ca2;border-style:dotted}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{margin:.5em 0 0;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{color:#ccc;top:0;left:0;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-align:center;font-family:WooCommerce}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr th{border:0;padding:0 4px .5em 0;line-height:1.5em;width:20%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td{padding:0 4px .5em 0;border:0;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input{width:100%;margin:0;position:relative;border-bottom:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .refund_by,ul.order_notes li p.meta .exact-date{border-bottom:1px dotted #999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td textarea{width:100%;height:4em;margin:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input:focus+textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input:focus+textarea{border-top-color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p{margin:0 0 .5em;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p:last-child{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method_name{width:100%;margin:0 0 .5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;float:right;font-size:14px;visibility:hidden;margin:3px -18px 0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:hover:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:hover:before{color:#a00}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax:hover .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax:hover .delete-order-tax{visibility:visible}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded{display:block;color:#a00;white-space:nowrap;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;width:100%;height:100%;text-align:center;content:"";position:relative;top:auto;left:auto;margin:-1px 4px 0 0;vertical-align:middle;line-height:1em}#woocommerce-order-items .wc-order-edit-line-item{padding-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions{width:44px;text-align:right;padding-left:0;vertical-align:middle}#woocommerce-order-items .wc-order-edit-line-item-actions a{color:#ccc;display:inline-block;cursor:pointer;padding:0 0 .5em;margin:0 0 0 12px;vertical-align:middle;text-decoration:none;line-height:16px;width:16px;overflow:hidden}#woocommerce-order-items .wc-order-edit-line-item-actions a:before{margin:0;padding:0;font-size:16px;width:16px;height:16px}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before,#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{font-family:Dashicons;-webkit-font-smoothing:antialiased;text-indent:0;top:0;left:0;width:100%;height:100%;margin:0;text-align:center;position:relative;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1}#woocommerce-order-items .wc-order-edit-line-item-actions a:hover:before{color:#999}#woocommerce-order-items .wc-order-edit-line-item-actions a:first-child{margin-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:hover:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:hover:before{color:#a00}#woocommerce-order-items tbody tr .wc-order-edit-line-item-actions{visibility:hidden}#woocommerce-order-items tbody tr:hover .wc-order-edit-line-item-actions{visibility:visible}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions{width:1.5em;visibility:visible!important}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions a{padding:0}#woocommerce-order-downloads .buttons{float:left;padding:0;margin:0;vertical-align:top}#woocommerce-order-downloads .buttons .add_item_id,#woocommerce-order-downloads .buttons .select2-container{width:400px!important;margin-right:9px;vertical-align:top;float:left}#woocommerce-order-downloads .buttons button{margin:2px 0 0}#woocommerce-order-downloads h3 small{color:#999}#poststuff #woocommerce-order-actions .inside{margin:0;padding:0}#poststuff #woocommerce-order-actions .inside ul.order_actions li{padding:6px 10px;box-sizing:border-box}#poststuff #woocommerce-order-actions .inside ul.order_actions li:last-child{border-bottom:0}#poststuff #woocommerce-order-notes .inside{margin:0;padding:0}#poststuff #woocommerce-order-notes .inside ul.order_notes li{padding:0 10px}#woocommerce_customers p.search-box{margin:6px 0 4px;float:left}#woocommerce_customers .tablenav{float:right;clear:none}.widefat.customers td{vertical-align:middle;padding:4px 7px}.widefat .column-order_title{width:15%}.widefat .column-order_title time{display:block;color:#999;margin:3px 0}.widefat .column-orders,.widefat .column-paying,.widefat .column-spent{text-align:center;width:8%}.widefat .column-last_order{width:11%}.widefat .column-order_actions,.widefat .column-user_actions,.widefat .column-wc_actions{width:110px}.widefat .column-order_actions a.button,.widefat .column-user_actions a.button,.widefat .column-wc_actions a.button{float:left;margin:0 4px 2px 0;cursor:pointer;padding:3px 4px;height:auto}.widefat .column-order_actions a.button img,.widefat .column-user_actions a.button img,.widefat .column-wc_actions a.button img{display:block;width:12px;height:auto}.widefat small.meta{display:block;color:#999;font-size:inherit;margin:3px 0}.widefat .column-order_date,.widefat .column-order_total{width:9%}.widefat .column-order_status{width:45px;text-align:center}.widefat .column-order_status mark{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;background:0 0;font-size:1.4em;margin:0 auto}.widefat .column-order_status mark.cancelled:after,.widefat .column-order_status mark.completed:after,.widefat .column-order_status mark.failed:after,.widefat .column-order_status mark.on-hold:after,.widefat .column-order_status mark.pending:after,.widefat .column-order_status mark.processing:after,.widefat .column-order_status mark.refunded:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.column-customer_message .note-on:after,.column-order_notes .note-on:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;left:0;text-align:center;line-height:16px;font-family:WooCommerce}.widefat .column-order_status mark.pending:after{content:"\e012";color:#ffba00}.widefat .column-order_status mark.completed:after{content:"\e015";color:#2ea2cc}.widefat .column-order_status mark.on-hold:after{content:"\e033";color:#999}.widefat .column-order_status mark.failed:after{content:"\e016";color:#d0c21f}.widefat .column-order_status mark.cancelled:after{content:"\e013";color:#a00}.widefat .column-order_status mark.processing:after{content:"\e011";color:#73a724}.widefat .column-order_status mark.refunded:after{content:"\e014";color:#999}.widefat td.column-order_status{padding-top:9px}.column-customer_message .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-customer_message .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.column-order_notes .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-order_notes .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.order_actions .complete,.order_actions .processing,.order_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.order_actions .processing:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.order_actions .complete:after,.order_actions .view:after{font-family:Dashicons;text-indent:0;position:absolute;width:100%;height:100%;left:0;line-height:1.85;margin:0;text-align:center;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;font-weight:400}.order_actions .complete:after{content:""}.order_actions .view:after{content:""}.user_actions .edit,.user_actions .link,.user_actions .refresh,.user_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.user_actions .edit:after,.user_actions .link:after,.user_actions .refresh:after,.user_actions .view:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.user_actions .edit:after{font-family:Dashicons;content:"\f464"}.user_actions .link:after{content:"\e00d"}.user_actions .view:after{content:"\e010"}.user_actions .refresh:after{content:"\e031"}.attributes-table td,.attributes-table th{width:15%;vertical-align:top}.attributes-table .attribute-terms{width:32%}.attributes-table .attribute-actions{width:2em}.attributes-table .attribute-actions .configure-terms{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.attributes-table .attribute-actions .configure-terms:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}ul.order_notes{padding:2px 0 0}ul.order_notes li .note_content{padding:10px;background:#efefef;position:relative}ul.order_notes li .note_content p{margin:0;padding:0;word-wrap:break-word}ul.order_notes li p.meta{padding:10px;color:#999;margin:0;font-size:11px}ul.order_notes li a.delete_note{color:#a00}table.wp-list-table .row-actions,table.wp-list-table span.na{color:#999}ul.order_notes li .note_content:after{content:"";display:block;position:absolute;bottom:-10px;left:20px;width:0;height:0;border-width:10px 10px 0 0;border-style:solid;border-color:#efefef transparent}ul.order_notes li.customer-note .note_content{background:#A7CEDC}ul.order_notes li.customer-note .note_content:after{border-color:#A7CEDC transparent}ul.order_notes li.system-note .note_content{background:#d7cad2}ul.order_notes li.system-note .note_content:after{border-color:#d7cad2 transparent}.add_note{border-top:1px solid #ddd;padding:10px 10px 0}.add_note h4{margin-top:5px!important}.add_note #add_order_note{width:100%;height:50px}table.wp-list-table .column-thumb{width:52px;text-align:center;white-space:nowrap}table.wp-list-table .column-name{width:22%}table.wp-list-table .column-product_cat,table.wp-list-table .column-product_tag{width:11%!important}table.wp-list-table .column-featured,table.wp-list-table .column-product_type{width:48px;text-align:left!important}table.wp-list-table .column-customer_message,table.wp-list-table .column-order_notes{width:48px;text-align:center}table.wp-list-table .column-customer_message img,table.wp-list-table .column-order_notes img{margin:0 auto;padding-top:0!important}table.wp-list-table .manage-column.column-featured img,table.wp-list-table .manage-column.column-product_type img{padding-left:2px}table.wp-list-table .column-price .woocommerce-price-suffix{display:none}table.wp-list-table img{margin:1px 2px}table.wp-list-table td.column-thumb img{margin:0;width:auto;height:auto;max-width:40px;max-height:40px;vertical-align:middle}table.wp-list-table .column-is_in_stock{text-align:left!important}table.wp-list-table span.wc-featured,table.wp-list-table span.wc-image,table.wp-list-table span.wc-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table span.wc-featured:before,table.wp-list-table span.wc-image:before,table.wp-list-table span.wc-type:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:""}table.wp-list-table span.wc-featured{margin:0;cursor:pointer}table.wp-list-table span.wc-featured:before{content:"\f155"}table.wp-list-table span.wc-featured.not-featured:before{content:"\f154"}table.wp-list-table td.column-featured span.wc-featured{font-size:1.6em}table.wp-list-table span.wc-type{margin:0}table.wp-list-table span.wc-type:before{font-family:WooCommerce;content:"\e006"}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after,table.wp-list-table span.product-type:before{font-family:WooCommerce;text-align:center;line-height:1;top:0;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;left:0}table.wp-list-table span.product-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.6em}table.wp-list-table span.product-type:before{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}table.wp-list-table span.product-type.grouped:before{content:"\e002"}table.wp-list-table span.product-type.external:before{content:"\e034"}table.wp-list-table span.product-type.variable:before{content:"\e003"}table.wp-list-table span.product-type.downloadable:before{content:"\e001"}table.wp-list-table span.product-type.virtual:before{content:"\e000"}table.wp-list-table mark.instock{font-weight:700;color:#7ad03a;background:0 0;line-height:1}table.wp-list-table mark.outofstock{font-weight:700;color:#a44;background:0 0;line-height:1}table.wp-list-table .notes_head,table.wp-list-table .order-notes_head,table.wp-list-table .status_head{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%}table.wc_emails .wc-email-settings-table-name,table.wc_emails td.name,table.wc_gateways .wc-email-settings-table-name,table.wc_gateways td.name,table.wc_shipping .wc-email-settings-table-name,table.wc_shipping td.name{font-weight:700}table.wp-list-table .order-notes_head:after{content:"\e028"}table.wp-list-table .notes_head:after{content:"\e026"}table.wp-list-table .status_head:after{content:"\e011"}table.wp-list-table .column-order_items{width:12%}table.wp-list-table .column-order_items table.order_items{width:100%;margin:3px 0 0;padding:0;display:none}table.wp-list-table .column-order_items table.order_items td{border:0;margin:0;padding:0 0 3px}table.wp-list-table .column-order_items table.order_items td.qty{color:#999;padding-right:6px;text-align:left}mark.notice{background:#fff;color:#a00;margin:0 0 0 10px}a.export_rates,a.import_rates{float:right;margin-left:9px;margin-top:-2px;margin-bottom:0}#rates-search{float:right}#rates-search input.wc-tax-rates-search-field{padding:4px 8px;font-size:1.2em}#rates-pagination{float:right;margin-right:.5em}#rates-pagination .tablenav{margin:0}table.wc_input_table,table.wc_tax_rates{width:100%}table.wc_input_table span.tips,table.wc_tax_rates span.tips{color:#2ea2cc}table.wc_input_table th,table.wc_tax_rates th{white-space:nowrap}table.wc_input_table td,table.wc_tax_rates td{padding:0;border-right:1px solid #DFDFDF;border-bottom:1px solid #DFDFDF;border-top:0;background:#fff;cursor:default}table.wc_input_table td input[type=text],table.wc_input_table td input[type=number],table.wc_tax_rates td input[type=text],table.wc_tax_rates td input[type=number]{width:100%;padding:5px 10px;margin:0;border:0;outline:0;background:0 0}table.wc_input_table td input[type=text]:focus,table.wc_input_table td input[type=number]:focus,table.wc_tax_rates td input[type=text]:focus,table.wc_tax_rates td input[type=number]:focus{outline:0;box-shadow:none}table.wc_input_table td.apply_to_shipping,table.wc_input_table td.compound,table.wc_tax_rates td.apply_to_shipping,table.wc_tax_rates td.compound{padding:5px 7px;vertical-align:middle}table.wc_input_table td.apply_to_shipping input,table.wc_input_table td.compound input,table.wc_tax_rates td.apply_to_shipping input,table.wc_tax_rates td.compound input{width:auto;padding:0}table.wc_input_table td:last-child,table.wc_tax_rates td:last-child{border-right:0}table.wc_input_table tr.current td,table.wc_tax_rates tr.current td{background-color:#fefbcc}table.wc_input_table .cost,table.wc_input_table .cost input,table.wc_input_table .item_cost,table.wc_input_table .item_cost input,table.wc_tax_rates .cost,table.wc_tax_rates .cost input,table.wc_tax_rates .item_cost,table.wc_tax_rates .item_cost input{text-align:right}table.wc_input_table th.sort,table.wc_tax_rates th.sort{width:17px;padding:0 4px}table.wc_input_table td.sort,table.wc_tax_rates td.sort{padding:0 4px}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort{cursor:move;font-size:15px;background:#f9f9f9;text-align:center;vertical-align:middle}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before{color:#333}table.wc_input_table .button,table.wc_tax_rates .button{float:left;margin-right:5px}table.wc_input_table .export,table.wc_input_table .import,table.wc_tax_rates .export,table.wc_tax_rates .import{float:right;margin-right:0;margin-left:5px}table.wc_input_table span.tips,table.wc_tax_rates span.tips{padding:0 3px}table.wc_input_table .pagination,table.wc_tax_rates .pagination{float:right}table.wc_input_table .pagination .button,table.wc_tax_rates .pagination .button{margin-left:5px;margin-right:0}table.wc_input_table .pagination .current,table.wc_tax_rates .pagination .current{background:#bbb;text-shadow:none}table.wc_input_table tr:last-child td,table.wc_tax_rates tr:last-child td{border-bottom:0}table.wc_emails,table.wc_gateways,table.wc_shipping{position:relative}table.wc_emails td,table.wc_gateways td,table.wc_shipping td{vertical-align:middle;padding:7px;line-height:2em}table.wc_emails tr:nth-child(odd) td,table.wc_gateways tr:nth-child(odd) td,table.wc_shipping tr:nth-child(odd) td{background:#f9f9f9}table.wc_emails th,table.wc_gateways th,table.wc_shipping th{padding:9px 7px!important;vertical-align:middle}table.wc_emails .settings,table.wc_gateways .settings,table.wc_shipping .settings{text-align:right}table.wc_emails .default,table.wc_emails .radio,table.wc_emails .status,table.wc_gateways .default,table.wc_gateways .radio,table.wc_gateways .status,table.wc_shipping .default,table.wc_shipping .radio,table.wc_shipping .status{text-align:center}table.wc_emails .default .tips,table.wc_emails .radio .tips,table.wc_emails .status .tips,table.wc_gateways .default .tips,table.wc_gateways .radio .tips,table.wc_gateways .status .tips,table.wc_shipping .default .tips,table.wc_shipping .radio .tips,table.wc_shipping .status .tips{margin:0 auto}table.wc_emails .default input,table.wc_emails .radio input,table.wc_emails .status input,table.wc_gateways .default input,table.wc_gateways .radio input,table.wc_gateways .status input,table.wc_shipping .default input,table.wc_shipping .radio input,table.wc_shipping .status input{margin:0}table.wc_emails th.sort,table.wc_gateways th.sort,table.wc_shipping th.sort{width:28px;padding:0}table.wc_emails td.sort,table.wc_gateways td.sort,table.wc_shipping td.sort{padding:0 7px;cursor:move;font-size:15px;text-align:center;vertical-align:middle}table.wc_emails td.sort:before,table.wc_gateways td.sort:before,table.wc_shipping td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_emails .wc-email-settings-table-name span,table.wc_gateways .wc-email-settings-table-name span,table.wc_shipping .wc-email-settings-table-name span{font-weight:400;color:#999;margin:0 0 0 4px!important}table.wc_emails .wc-email-settings-table-status,table.wc_gateways .wc-email-settings-table-status,table.wc_shipping .wc-email-settings-table-status{text-align:center;width:1em}table.wc_emails .wc-email-settings-table-status .tips,table.wc_gateways .wc-email-settings-table-status .tips,table.wc_shipping .wc-email-settings-table-status .tips{margin:0 auto}table.wc_emails .wc-email-settings-table-actions a,table.wc_gateways .wc-email-settings-table-actions a,table.wc_shipping .wc-email-settings-table-actions a{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}table.wc_emails .wc-email-settings-table-actions a:after,table.wc_gateways .wc-email-settings-table-actions a:after,table.wc_shipping .wc-email-settings-table-actions a:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}table.wc-shipping-classes td,table.wc-shipping-classes th,table.wc-shipping-zone-methods td,table.wc-shipping-zone-methods th,table.wc-shipping-zones td,table.wc-shipping-zones th{vertical-align:top;line-height:24px;padding:1em;font-size:14px;background:#fff}table.wc-shipping-classes td li,table.wc-shipping-classes th li,table.wc-shipping-zone-methods td li,table.wc-shipping-zone-methods th li,table.wc-shipping-zones td li,table.wc-shipping-zones th li{line-height:24px;font-size:14px}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state,table.wc-shipping-classes td.wc-shipping-zones-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state,table.wc-shipping-zones td.wc-shipping-zones-blank-state{background:#F7F1F6!important;overflow:hidden;position:relative;padding:7.5em 7.5%;border-bottom:2px solid #EEE2EC}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zones td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state p{color:#a46497;font-size:1.5em;line-height:1.5em;margin:0 0 1em;position:relative;z-index:1;text-shadow:1px 1px 1px #fff}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state p.main{font-size:2em}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state li{margin-left:1em;list-style:circle inside}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-classes td.wc-shipping-zones-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state:before,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zones td.wc-shipping-zones-blank-state:before{content:"\e01b";font-family:WooCommerce;text-align:center;line-height:1;color:#EEE2EC;display:block;width:1em;font-size:40em;top:50%;right:-3.75%;margin-top:-.1875em;position:absolute}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-classes td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zones-blank-state .button-primary{background-color:#804877;border-color:#804877;-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);margin:0;opacity:1;text-shadow:0 -1px 1px #8a4f7f,1px 0 1px #8a4f7f,0 1px 1px #8a4f7f,-1px 0 1px #8a4f7f;font-size:1.5em;padding:.75em 1em;height:auto;position:relative;z-index:1}table.wc-shipping-classes .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-classes .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-classes tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-classes tr.odd td,table.wc-shipping-zone-methods .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tr.odd td,table.wc-shipping-zones .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zones .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zones tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zones tr.odd td{background:#f9f9f9}table.wc-shipping-classes p,table.wc-shipping-classes ul,table.wc-shipping-zone-methods p,table.wc-shipping-zone-methods ul,table.wc-shipping-zones p,table.wc-shipping-zones ul{margin:0}table.wc-shipping-classes td.wc-shipping-zone-method-sort,table.wc-shipping-classes td.wc-shipping-zone-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-sort,table.wc-shipping-zones td.wc-shipping-zone-method-sort,table.wc-shipping-zones td.wc-shipping-zone-sort{cursor:move;font-size:15px;text-align:center}table.wc-shipping-classes td.wc-shipping-zone-method-sort:before,table.wc-shipping-classes td.wc-shipping-zone-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:before,table.wc-shipping-zones td.wc-shipping-zone-sort:before{content:"\f333";font-family:Dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-classes td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-sort:hover:before{color:#333}table.wc-shipping-classes td.wc-shipping-zone-worldwide,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide,table.wc-shipping-zones td.wc-shipping-zone-worldwide{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-worldwide:before,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide:before,table.wc-shipping-zones td.wc-shipping-zone-worldwide:before{content:"\f319";font-family:dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes .wc-shipping-zone-methods,table.wc-shipping-classes .wc-shipping-zone-name,table.wc-shipping-zone-methods .wc-shipping-zone-methods,table.wc-shipping-zone-methods .wc-shipping-zone-name,table.wc-shipping-zones .wc-shipping-zone-methods,table.wc-shipping-zones .wc-shipping-zone-name{width:25%}table.wc-shipping-classes .wc-shipping-class-description input,table.wc-shipping-classes .wc-shipping-class-description select,table.wc-shipping-classes .wc-shipping-class-description textarea,table.wc-shipping-classes .wc-shipping-class-name input,table.wc-shipping-classes .wc-shipping-class-name select,table.wc-shipping-classes .wc-shipping-class-name textarea,table.wc-shipping-classes .wc-shipping-class-slug input,table.wc-shipping-classes .wc-shipping-class-slug select,table.wc-shipping-classes .wc-shipping-class-slug textarea,table.wc-shipping-classes .wc-shipping-zone-name input,table.wc-shipping-classes .wc-shipping-zone-name select,table.wc-shipping-classes .wc-shipping-zone-name textarea,table.wc-shipping-classes .wc-shipping-zone-region input,table.wc-shipping-classes .wc-shipping-zone-region select,table.wc-shipping-classes .wc-shipping-zone-region textarea,table.wc-shipping-zone-methods .wc-shipping-class-description input,table.wc-shipping-zone-methods .wc-shipping-class-description select,table.wc-shipping-zone-methods .wc-shipping-class-description textarea,table.wc-shipping-zone-methods .wc-shipping-class-name input,table.wc-shipping-zone-methods .wc-shipping-class-name select,table.wc-shipping-zone-methods .wc-shipping-class-name textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug input,table.wc-shipping-zone-methods .wc-shipping-class-slug select,table.wc-shipping-zone-methods .wc-shipping-class-slug textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name input,table.wc-shipping-zone-methods .wc-shipping-zone-name select,table.wc-shipping-zone-methods .wc-shipping-zone-name textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region input,table.wc-shipping-zone-methods .wc-shipping-zone-region select,table.wc-shipping-zone-methods .wc-shipping-zone-region textarea,table.wc-shipping-zones .wc-shipping-class-description input,table.wc-shipping-zones .wc-shipping-class-description select,table.wc-shipping-zones .wc-shipping-class-description textarea,table.wc-shipping-zones .wc-shipping-class-name input,table.wc-shipping-zones .wc-shipping-class-name select,table.wc-shipping-zones .wc-shipping-class-name textarea,table.wc-shipping-zones .wc-shipping-class-slug input,table.wc-shipping-zones .wc-shipping-class-slug select,table.wc-shipping-zones .wc-shipping-class-slug textarea,table.wc-shipping-zones .wc-shipping-zone-name input,table.wc-shipping-zones .wc-shipping-zone-name select,table.wc-shipping-zones .wc-shipping-zone-name textarea,table.wc-shipping-zones .wc-shipping-zone-region input,table.wc-shipping-zones .wc-shipping-zone-region select,table.wc-shipping-zones .wc-shipping-zone-region textarea{width:100%}table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-zone-delete{color:red}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle{float:right;margin:0;font-size:.9em;text-decoration:underline}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes{display:none}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea{margin-top:1em}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes .description{font-size:.9em;color:#999}table.wc-shipping-classes .wc-shipping-class-count,table.wc-shipping-zone-methods .wc-shipping-class-count,table.wc-shipping-zones .wc-shipping-class-count{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-methods,table.wc-shipping-zone-methods td.wc-shipping-zone-methods,table.wc-shipping-zones td.wc-shipping-zone-methods{color:#999}table.wc-shipping-classes td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .method_disabled{text-decoration:line-through}table.wc-shipping-classes td.wc-shipping-zone-methods ul,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul,table.wc-shipping-zones td.wc-shipping-zone-methods ul{color:#999;position:relative;padding-right:32px}table.wc-shipping-classes td.wc-shipping-zone-methods ul li,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li,table.wc-shipping-zones td.wc-shipping-zone-methods ul li{display:inline;margin:0}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:before{content:", "}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-classes td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:nth-child(2):before{content:""}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child{display:block}table.wc-shipping-classes td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zones td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row{position:absolute;right:0;top:0}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method{display:block;width:24px;padding:24px 0 0;height:0;overflow:hidden;cursor:pointer}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method:before{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;font-family:Dashicons;content:"\f502";color:#999;vertical-align:middle;line-height:24px;font-size:16px;margin:0}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled:before{line-height:inherit}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled{margin-top:1px;display:inline-block}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled{cursor:not-allowed}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled:before{color:#ccc}table.wc-shipping-classes .wc-shipping-zone-method-title,table.wc-shipping-zone-methods .wc-shipping-zone-method-title,table.wc-shipping-zones .wc-shipping-zone-method-title{width:33%}table.wc-shipping-classes .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zone-methods .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zones .wc-shipping-zone-method-title .wc-shipping-zone-method-delete{color:red}table.wc-shipping-classes .wc-shipping-zone-method-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled{text-align:center}table.wc-shipping-classes tfoot input,table.wc-shipping-classes tfoot select,table.wc-shipping-zone-methods tfoot input,table.wc-shipping-zone-methods tfoot select,table.wc-shipping-zones tfoot input,table.wc-shipping-zones tfoot select{vertical-align:middle!important}table.wc-shipping-classes tfoot .button-secondary,table.wc-shipping-zone-methods tfoot .button-secondary,table.wc-shipping-zones tfoot .button-secondary{float:right}table.wc-shipping-classes .editing .wc-shipping-zone-edit,table.wc-shipping-classes .editing .wc-shipping-zone-view,table.wc-shipping-zone-methods .editing .wc-shipping-zone-edit,table.wc-shipping-zone-methods .editing .wc-shipping-zone-view,table.wc-shipping-zones .editing .wc-shipping-zone-edit,table.wc-shipping-zones .editing .wc-shipping-zone-view{display:none}.wc-modal-shipping-method-settings{background:#f8f8f8;padding:1em!important}.wc-modal-shipping-method-settings form .form-table{width:100%;background:#fff;margin:0 0 1.5em}.wc-modal-shipping-method-settings form .form-table tr th{width:30%;position:relative}.wc-modal-shipping-method-settings form .form-table tr th .woocommerce-help-tip{float:right;margin:-8px -.5em 0 0;vertical-align:middle;right:0;top:50%;position:absolute}.wc-modal-shipping-method-settings form .form-table tr td input,.wc-modal-shipping-method-settings form .form-table tr td select,.wc-modal-shipping-method-settings form .form-table tr td textarea{width:50%;min-width:250px}.wc-modal-shipping-method-settings form .form-table tr td input[type=checkbox]{width:auto;min-width:16px}.wc-modal-shipping-method-settings form .form-table tr td,.wc-modal-shipping-method-settings form .form-table tr th{vertical-align:middle;margin:0;line-height:24px;padding:1em;border-bottom:1px solid #f8f8f8}.wc-modal-shipping-method-settings form .form-table:last-of-type{margin-bottom:0}.wc-backbone-modal .wc-shipping-zone-method-selector p{margin-top:0}.wc-backbone-modal .wc-shipping-zone-method-selector .wc-shipping-zone-method-description{margin:.75em 1px 0;line-height:1.5em;color:#999;font-style:italic}.wc-backbone-modal .wc-shipping-zone-method-selector select{width:100%;cursor:pointer}img.help_tip{margin:0 0 0 9px;vertical-align:middle}.postbox img.help_tip{margin-top:0}.postbox .woocommerce-help-tip{margin:0 0 0 9px}.status-disabled,.status-enabled,.status-manual{font-size:1.4em;display:block;text-indent:-9999px;position:relative;height:1em;width:1em}.status-disabled:before,.status-enabled:before,.status-manual:before{font-family:WooCommerce;line-height:1;margin:0;position:absolute;width:100%;height:100%;text-indent:0;top:0;font-variant:normal;-webkit-font-smoothing:antialiased;font-weight:400;text-align:center;left:0;speak:none;text-transform:none}.status-manual:before{content:"";color:#999}.status-enabled:before{content:"";color:#a46497}.status-disabled:before{content:"";color:#ccc}.woocommerce h2.woo-nav-tab-wrapper{margin-bottom:1em}.woocommerce nav.woo-nav-tab-wrapper{margin:1.5em 0 1em;border-bottom:1px solid #ccc}.woocommerce .subsubsub{margin:-8px 0 0}.woocommerce .wc-admin-breadcrumb{margin-left:.5em}.woocommerce .wc-admin-breadcrumb a{color:#a46497}.woocommerce #template div{margin:0}.woocommerce #template div p .button{float:right;margin-left:10px;margin-top:-4px}.woocommerce #template div .editor textarea{margin-bottom:8px}.woocommerce textarea[disabled=disabled]{background:#DFDFDF!important}.woocommerce table.form-table{margin:0;position:relative}.woocommerce table.form-table .forminp-radio ul{margin:0}.woocommerce table.form-table .forminp-radio ul li{line-height:1.4em}.woocommerce table.form-table textarea.input-text{height:100%;min-width:150px;display:block}.woocommerce table.form-table input.regular-input{width:25em}.woocommerce table.form-table textarea.wide-input{width:100%}.woocommerce table.form-table .woocommerce-help-tip,.woocommerce table.form-table img.help_tip{padding:0;margin:-4px 0 0 5px;vertical-align:middle;cursor:help;line-height:1}.woocommerce table.form-table span.help_tip{cursor:help;color:#2ea2cc}.woocommerce table.form-table th{position:relative;padding-right:24px}.woocommerce table.form-table .select2-container{display:block;max-width:350px;vertical-align:top;margin-bottom:3px}.woocommerce table.form-table table.widefat th{padding-right:inherit}.woocommerce table.form-table th .woocommerce-help-tip,.woocommerce table.form-table th img.help_tip{margin:0 -24px 0 0;float:right}.woocommerce table.form-table .wp-list-table .woocommerce-help-tip{float:none}.woocommerce table.form-table fieldset{margin-top:4px}.woocommerce table.form-table fieldset .woocommerce-help-tip,.woocommerce table.form-table fieldset img.help_tip{margin:-3px 0 0 5px}.woocommerce table.form-table fieldset p.description{margin-bottom:8px}.woocommerce table.form-table fieldset:first-child{margin-top:0}.woocommerce table.form-table .iris-picker{z-index:100;display:none;position:absolute;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,.2)}.woocommerce table.form-table .iris-picker .ui-slider{border:0!important;margin:0!important;width:auto!important;height:auto!important;background:none!important}.woocommerce table.form-table .iris-picker .ui-slider .ui-slider-handle{margin-bottom:0!important}.woocommerce table.form-table .colorpickpreview{padding:3px 3px 3px 20px;border:1px solid #ddd;border-right:0}.woocommerce table.form-table .colorpick{border-left:0}.woocommerce table.form-table .image_width_settings{vertical-align:middle}.woocommerce table.form-table .image_width_settings label{margin-left:10px}.woocommerce table.form-table .wc_emails_wrapper{padding:0 15px 10px 0}.woocommerce #tabs-wrap table a.remove{margin-left:4px}.woocommerce #tabs-wrap table p{margin:0 0 4px!important;overflow:hidden;zoom:1}.woocommerce #tabs-wrap table p a.add{float:left}#wp-excerpt-editor-container{background:#fff}#product_variation-parent #parent_id{width:100%}#postimagediv img{border:1px solid #d5d5d5;max-width:100%}#woocommerce-product-images .inside{margin:0;padding:0}#woocommerce-product-images .inside .add_product_images{padding:0 12px 12px}#woocommerce-product-images .inside #product_images_container{padding:0 0 0 9px}#woocommerce-product-images .inside #product_images_container ul{margin:0;padding:0}#woocommerce-product-images .inside #product_images_container ul:after,#woocommerce-product-images .inside #product_images_container ul:before{content:" ";display:table}#woocommerce-product-images .inside #product_images_container ul:after{clear:both}#woocommerce-product-images .inside #product_images_container ul li.add,#woocommerce-product-images .inside #product_images_container ul li.image,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{width:80px;float:left;cursor:move;border:1px solid #d5d5d5;margin:9px 9px 0 0;background:#f7f7f7;border-radius:2px;position:relative;box-sizing:border-box}#woocommerce-product-images .inside #product_images_container ul li.add img,#woocommerce-product-images .inside #product_images_container ul li.image img,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder img{width:100%;height:auto;display:block}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{border:3px dashed #ddd;position:relative}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-size:2.618em;line-height:72px;color:#ddd}#woocommerce-product-images .inside #product_images_container ul ul.actions{position:absolute;top:-8px;right:-8px;padding:2px;display:none}#woocommerce-product-images .inside #product_images_container ul ul.actions li{float:right;margin:0 0 0 2px}#woocommerce-product-images .inside #product_images_container ul ul.actions li a{width:1em;margin:0;height:0;display:block;overflow:hidden}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.tips{cursor:pointer}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.4em}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:hover:before{color:#a00}#woocommerce-product-images .inside #product_images_container ul li:hover ul.actions{display:block}#woocommerce-product-data .hndle{padding:10px}#woocommerce-product-data .hndle span{display:block;vertical-align:middle;line-height:24px}#woocommerce-product-data .hndle span span{display:inline;line-height:inherit;vertical-align:baseline}#woocommerce-product-data .hndle label{padding-right:1em;font-size:12px;vertical-align:baseline}#woocommerce-product-data .hndle label:first-child{margin-right:1em;border-right:1px solid #dfdfdf}#woocommerce-product-data .hndle input,#woocommerce-product-data .hndle select{margin:-3px 0 0 .5em;vertical-align:middle}#woocommerce-product-data>.handlediv{margin-top:4px}#woocommerce-product-data .wrap{margin:0}#woocommerce-coupon-description{padding:3px 8px;font-size:1.7em;line-height:1.42em;height:auto;width:100%;outline:0;margin:10px 0;display:block}#woocommerce-coupon-description::-webkit-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description::-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-ms-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap{background:#fff}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{float:left;width:80%}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-product-data .woocommerce_options_panel .wc-radios{display:block;float:left;margin:0}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-product-data .woocommerce_options_panel .wc-radios li{display:block;padding:0 0 10px}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li input,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-product-data .woocommerce_options_panel .wc-radios li input{width:auto}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap,.woocommerce .panel-wrap{overflow:hidden}#woocommerce-coupon-data ul.wc-tabs,#woocommerce-product-data ul.wc-tabs,.woocommerce ul.wc-tabs{margin:0;width:20%;float:left;line-height:1em;padding:0 0 10px;position:relative;background-color:#fafafa;border-right:1px solid #eee;box-sizing:border-box}#woocommerce-coupon-data ul.wc-tabs:after,#woocommerce-product-data ul.wc-tabs:after,.woocommerce ul.wc-tabs:after{content:"";display:block;width:100%;height:9999em;position:absolute;bottom:-9999em;left:0;background-color:#fafafa;border-right:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li,#woocommerce-product-data ul.wc-tabs li,.woocommerce ul.wc-tabs li{margin:0;padding:0;display:block;position:relative}#woocommerce-coupon-data ul.wc-tabs li a,#woocommerce-product-data ul.wc-tabs li a,.woocommerce ul.wc-tabs li a{margin:0;padding:10px;display:block;box-shadow:none;text-decoration:none;line-height:20px!important;border-bottom:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li a:before,#woocommerce-product-data ul.wc-tabs li a:before,.woocommerce ul.wc-tabs li a:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}#woocommerce-coupon-data ul.wc-tabs li.general_options a:before,#woocommerce-product-data ul.wc-tabs li.general_options a:before,.woocommerce ul.wc-tabs li.general_options a:before{content:"\f107"}#woocommerce-coupon-data ul.wc-tabs li.inventory_options a:before,#woocommerce-product-data ul.wc-tabs li.inventory_options a:before,.woocommerce ul.wc-tabs li.inventory_options a:before{content:"\f481"}#woocommerce-coupon-data ul.wc-tabs li.shipping_options a:before,#woocommerce-product-data ul.wc-tabs li.shipping_options a:before,.woocommerce ul.wc-tabs li.shipping_options a:before{font-family:WooCommerce;content:"\e01a"}#woocommerce-coupon-data ul.wc-tabs li.linked_product_options a:before,#woocommerce-product-data ul.wc-tabs li.linked_product_options a:before,.woocommerce ul.wc-tabs li.linked_product_options a:before{content:"\f103"}#woocommerce-coupon-data ul.wc-tabs li.attribute_options a:before,#woocommerce-product-data ul.wc-tabs li.attribute_options a:before,.woocommerce ul.wc-tabs li.attribute_options a:before{content:"\f175"}#woocommerce-coupon-data ul.wc-tabs li.advanced_options a:before,#woocommerce-product-data ul.wc-tabs li.advanced_options a:before,.woocommerce ul.wc-tabs li.advanced_options a:before{font-family:Dashicons;content:"\f111"}#woocommerce-coupon-data ul.wc-tabs li.variations_options a:before,#woocommerce-product-data ul.wc-tabs li.variations_options a:before,.woocommerce ul.wc-tabs li.variations_options a:before{content:"\f509"}#woocommerce-coupon-data ul.wc-tabs li.usage_restriction_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_restriction_options a:before,.woocommerce ul.wc-tabs li.usage_restriction_options a:before{font-family:WooCommerce;content:"\e602"}#woocommerce-coupon-data ul.wc-tabs li.usage_limit_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_limit_options a:before,.woocommerce ul.wc-tabs li.usage_limit_options a:before{font-family:WooCommerce;content:"\e601"}#woocommerce-coupon-data ul.wc-tabs li.general_coupon_data a:before,#woocommerce-product-data ul.wc-tabs li.general_coupon_data a:before,.woocommerce ul.wc-tabs li.general_coupon_data a:before{font-family:WooCommerce;content:"\e600"}#woocommerce-coupon-data ul.wc-tabs li.active a,#woocommerce-product-data ul.wc-tabs li.active a,.woocommerce ul.wc-tabs li.active a{color:#555;position:relative;background-color:#eee}.woocommerce_page_wc-settings .shippingrows th.check-column{padding-top:20px}.woocommerce_page_wc-settings .shippingrows tfoot th{padding-left:10px}.woocommerce_page_wc-settings .shippingrows .add.button:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}.woocommerce_page_wc-settings h3.wc-settings-sub-title{font-size:1.2em}#woocommerce-coupon-data .inside,#woocommerce-order-data .inside,#woocommerce-order-downloads .inside,#woocommerce-product-data .inside,#woocommerce-product-type-options .inside{margin:0;padding:0}.panel,.woocommerce_options_panel{padding:9px;color:#555}.panel .form-field .woocommerce-help-tip,.woocommerce_options_panel .form-field .woocommerce-help-tip{font-size:1.4em}.panel,.woocommerce_page_settings .woocommerce_options_panel{padding:0}#woocommerce-product-specs .inside,#woocommerce-product-type-options .panel{margin:0;padding:9px}#woocommerce-product-type-options .panel p,.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p{margin:0 0 9px;font-size:12px;padding:5px 9px;line-height:24px}#woocommerce-product-type-options .panel p:after,.woocommerce_options_panel fieldset.form-field:after,.woocommerce_options_panel p:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce_options_panel .checkbox,.woocommerce_variable_attributes .checkbox{width:auto;margin:3px 0;vertical-align:middle}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{width:100%;padding:0!important}.woocommerce_options_panel .downloadable_files table th,.woocommerce_variations .downloadable_files table th{padding:7px 0 7px 7px!important}.woocommerce_options_panel .downloadable_files table th.sort,.woocommerce_variations .downloadable_files table th.sort{width:17px;padding:7px!important}.woocommerce_options_panel .downloadable_files table th .woocommerce-help-tip,.woocommerce_variations .downloadable_files table th .woocommerce-help-tip{font-size:1.1em;margin-left:0}.woocommerce_options_panel .downloadable_files table td,.woocommerce_variations .downloadable_files table td{vertical-align:middle!important;padding:4px 0 4px 7px!important;position:relative}.woocommerce_options_panel .downloadable_files table td:last-child,.woocommerce_variations .downloadable_files table td:last-child{padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td input.input_text,.woocommerce_variations .downloadable_files table td input.input_text{width:100%;float:none;min-width:0;margin:1px 0}.woocommerce_options_panel .downloadable_files table td .upload_file_button,.woocommerce_variations .downloadable_files table td .upload_file_button{width:auto;float:right;cursor:pointer}.woocommerce_options_panel .downloadable_files table td .delete,.woocommerce_variations .downloadable_files table td .delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.2em}.woocommerce_options_panel .downloadable_files table td .delete:before,.woocommerce_variations .downloadable_files table td .delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}.woocommerce_options_panel .downloadable_files table td .delete:hover:before,.woocommerce_variations .downloadable_files table td .delete:hover:before{color:#a00}.woocommerce_options_panel .downloadable_files table td.sort,.woocommerce_variations .downloadable_files table td.sort{width:17px;cursor:move;font-size:15px;text-align:center;background:#f9f9f9;padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td.sort:before,.woocommerce_variations .downloadable_files table td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_options_panel .downloadable_files table td.sort:hover:before,.woocommerce_variations .downloadable_files table td.sort:hover:before{color:#333}.woocommerce_variation h3 .sort{width:17px;height:26px;cursor:move;float:right;font-size:15px;font-weight:400;margin-right:.5em;visibility:hidden;text-align:center;vertical-align:middle}.woocommerce_variation h3 .sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:28px;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_variation h3 .sort:hover:before{color:#777}.woocommerce_variation h3:hover .sort,.woocommerce_variation.ui-sortable-helper .sort{visibility:visible}.woocommerce_options_panel{min-height:175px;box-sizing:border-box}.woocommerce_options_panel .downloadable_files{padding:0 9px 0 162px;position:relative;margin:9px 0}.woocommerce_options_panel .downloadable_files label{position:absolute;left:0;margin:0 0 0 12px;line-height:24px}.woocommerce_options_panel p{margin:9px 0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px 5px 162px!important}.woocommerce_options_panel .sale_price_dates_fields .short:first-of-type{margin-bottom:1em}.woocommerce_options_panel .sale_price_dates_fields .short:nth-of-type(2){clear:left}.woocommerce_options_panel label,.woocommerce_options_panel legend{float:left;width:150px;padding:0;margin:0 0 0 -150px}.woocommerce_options_panel label .req,.woocommerce_options_panel legend .req{font-weight:700;font-style:normal;color:#a00}.woocommerce_options_panel .description{padding:0;margin:0 0 0 7px;clear:none;display:inline}.woocommerce_options_panel .description-block{margin-left:0;display:block}.woocommerce_options_panel input,.woocommerce_options_panel select,.woocommerce_options_panel textarea{margin:0}.woocommerce_options_panel textarea{height:3.5em;line-height:1.5em;vertical-align:top}.woocommerce_options_panel input[type=text],.woocommerce_options_panel input[type=number],.woocommerce_options_panel input[type=email],.woocommerce_options_panel input[type=password]{width:50%;float:left}.woocommerce_options_panel input.button{width:auto;margin-left:8px}.woocommerce_options_panel select{float:left}.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:50%}.woocommerce_options_panel .sized{width:auto!important;margin-right:6px}.woocommerce_options_panel .options_group{border-top:1px solid #fff;border-bottom:1px solid #eee}.woocommerce_options_panel .options_group:first-child{border-top:0}.woocommerce_options_panel .options_group:last-child{border-bottom:0}.woocommerce_options_panel .options_group fieldset{margin:9px 0;font-size:12px;padding:5px 9px;line-height:24px}.woocommerce_options_panel .options_group fieldset label{width:auto;float:none}.woocommerce_options_panel .options_group fieldset ul{float:left;width:50%;margin:0;padding:0}.woocommerce_options_panel .options_group fieldset ul li{margin:0;width:auto}.woocommerce_options_panel .options_group fieldset ul li input{width:auto;float:none;margin-right:4px}.woocommerce_options_panel .options_group fieldset ul.wc-radios label{margin-left:0}.woocommerce_options_panel .dimensions_field .wrap{display:block;width:50%}.woocommerce_options_panel .dimensions_field .wrap input{width:30.75%;margin-right:3.8%}.woocommerce_options_panel .dimensions_field .wrap .last{margin-right:0}.woocommerce_options_panel.padded{padding:1em}#woocommerce-product-data input.dp-applied,.woocommerce_options_panel .select2-container{float:left}#grouped_product_options,#simple_product_options,#virtual_product_options{padding:12px;font-style:italic;color:#666}.wc-metaboxes-wrapper .toolbar{margin:0!important;border-top:1px solid #fff;border-bottom:1px solid #eee;padding:9px 12px!important}.wc-metaboxes-wrapper .toolbar:first-child{border-top:0}.wc-metaboxes-wrapper .toolbar:last-child{border-bottom:0}.wc-metaboxes-wrapper .toolbar .add_variation{float:right;margin-left:5px}.wc-metaboxes-wrapper .toolbar .cancel-variation-changes,.wc-metaboxes-wrapper .toolbar .save-variation-changes{float:left;margin-right:5px}.wc-metaboxes-wrapper p.toolbar{overflow:hidden;zoom:1}.wc-metaboxes-wrapper .expand-close{margin-right:2px;color:#777;font-size:12px;font-style:italic}.wc-metaboxes-wrapper .expand-close a{background:0 0;padding:0;font-size:12px;text-decoration:none}.wc-metaboxes-wrapper#product_attributes .expand-close{float:right;line-height:28px}.wc-metaboxes-wrapper .fr,.wc-metaboxes-wrapper button.add_variable_attribute{float:right;margin:0 0 0 6px}.wc-metaboxes-wrapper .wc-metaboxes{border-bottom:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox-sortable-placeholder{border-color:#bbb;background-color:#f5f5f5;margin-bottom:9px;border-width:1px;border-style:dashed}.wc-metaboxes-wrapper .wc-metabox{background:#fff;border-bottom:1px solid #eee;margin:0!important}.wc-metaboxes-wrapper .wc-metabox select{font-weight:400}.wc-metaboxes-wrapper .wc-metabox:last-of-type{border-bottom:0}.wc-metaboxes-wrapper .wc-metabox .handlediv{width:27px}.wc-metaboxes-wrapper .wc-metabox .handlediv:before{content:"\f142"!important;cursor:pointer;display:inline-block;font:400 20px/1 Dashicons;line-height:.5!important;padding:8px 10px;position:relative;right:12px;top:0}.wc-metaboxes-wrapper .wc-metabox.closed{border-radius:3px}.wc-metaboxes-wrapper .wc-metabox.closed .handlediv:before{content:"\f140"!important}.wc-metaboxes-wrapper .wc-metabox.closed h3{border:0}.wc-metaboxes-wrapper .wc-metabox h3{margin:0!important;padding:.75em .75em .75em 1em!important;font-size:1em!important;overflow:hidden;zoom:1;cursor:move}.wc-metaboxes-wrapper .wc-metabox h3 a.delete,.wc-metaboxes-wrapper .wc-metabox h3 button{float:right}.wc-metaboxes-wrapper .wc-metabox h3 a.delete{color:red;font-weight:400;line-height:26px;text-decoration:none;position:relative;visibility:hidden}.wc-metaboxes-wrapper .wc-metabox h3 strong{line-height:26px;font-weight:700}.wc-metaboxes-wrapper .wc-metabox h3 select{font-family:sans-serif;max-width:20%;margin:.25em .25em .25em 0}.wc-metaboxes-wrapper .wc-metabox h3 .handlediv{background-position:6px 5px!important;visibility:hidden;height:26px}.wc-metaboxes-wrapper .wc-metabox h3.fixed{cursor:pointer!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3{cursor:pointer;padding:.5em .75em .5em 1em!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .handlediv,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .sort,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 a.delete{margin-top:.25em}.wc-metaboxes-wrapper .wc-metabox h3:hover .handlediv,.wc-metaboxes-wrapper .wc-metabox h3:hover a.delete,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper .handlediv,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper a.delete{visibility:visible}.wc-metaboxes-wrapper .wc-metabox table{width:100%;position:relative;background-color:#fdfdfd;padding:1em;border-top:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox table td{text-align:left;padding:0 6px 1em 0;vertical-align:top;border:0}.wc-metaboxes-wrapper .wc-metabox table td label{text-align:left;display:block;line-height:21px}.wc-metaboxes-wrapper .wc-metabox table td input{float:left;min-width:200px}.wc-metaboxes-wrapper .wc-metabox table td input,.wc-metaboxes-wrapper .wc-metabox table td textarea{width:100%;margin:0;display:block;font-size:14px;padding:4px;color:#555}.wc-metaboxes-wrapper .wc-metabox table td .select2-container,.wc-metaboxes-wrapper .wc-metabox table td select{width:100%!important}.wc-metaboxes-wrapper .wc-metabox table td input.short{width:200px}.wc-metaboxes-wrapper .wc-metabox table td input.checkbox{width:16px;min-width:inherit;vertical-align:text-bottom;display:inline-block;float:none}.wc-metaboxes-wrapper .wc-metabox table td.attribute_name{width:200px}.wc-metaboxes-wrapper .wc-metabox table .minus,.wc-metaboxes-wrapper .wc-metabox table .plus{margin-top:6px}.wc-metaboxes-wrapper .wc-metabox table .fl{float:left}.wc-metaboxes-wrapper .wc-metabox table .fr{float:right}.variations-pagenav{float:right;line-height:24px}.variations-pagenav .displaying-num{color:#777;font-size:12px;font-style:italic}.variations-pagenav a{padding:0 10px 3px;background:rgba(0,0,0,.05);font-size:16px;font-weight:400;text-decoration:none}.variations-pagenav a.disabled,.variations-pagenav a.disabled:active,.variations-pagenav a.disabled:focus,.variations-pagenav a.disabled:hover{color:#A0A5AA;background:rgba(0,0,0,.05)}.variations-defaults{float:left}.variations-defaults select{margin:.25em .25em .25em 0}.woocommerce_variable_attributes{background-color:#fdfdfd;border-top:1px solid #eee}.woocommerce_variable_attributes .data{padding:1em 2em}.woocommerce_variable_attributes .data:after,.woocommerce_variable_attributes .data:before{content:" ";display:table}.woocommerce_variable_attributes .data:after{clear:both}.woocommerce_variable_attributes .upload_image_button{display:block;width:48px;height:48px;float:left;margin-right:20px;position:relative;cursor:pointer}.woocommerce_variable_attributes .upload_image_button img{width:100%;height:auto;display:none}.woocommerce_variable_attributes .upload_image_button:before{content:"\f128";font-family:Dashicons;position:absolute;top:0;left:0;right:0;bottom:0;text-align:center;line-height:48px;font-size:48px;font-weight:400;-webkit-font-smoothing:antialiased}.woocommerce_variable_attributes .upload_image_button.remove img{display:block}.woocommerce_variable_attributes .upload_image_button.remove:before{content:"\f335";display:none}.woocommerce_variable_attributes .upload_image_button.remove:hover:before{display:block}.woocommerce_variable_attributes .options{border:1px solid #eee;border-width:1px 0;padding:.25em 0}.woocommerce_variable_attributes .options label{display:inline-block;padding:4px 1em 2px 0}.woocommerce_variable_attributes .options input[type=checkbox]{margin-top:5px;margin-right:3px}.form-row label{display:block}.form-row input[type=number],.form-row input[type=text],.form-row select{width:100%}.form-row.dimensions_field input{width:25%;float:left;margin-right:1%}.form-row.dimensions_field input:last-of-type{margin-right:0}.form-row-first,.form-row-last{width:48%;float:right}.form-row-first{clear:both;float:left}.form-row-full{clear:both}.tips{cursor:help;text-decoration:none}img.tips{padding:5px 0 0}#tiptip_holder{display:none;position:absolute;top:0;left:0;z-index:9999999}#tiptip_holder.tip_top{padding-bottom:5px}#tiptip_holder.tip_top #tiptip_arrow_inner{margin-top:-7px;margin-left:-6px;border-top-color:#333}#tiptip_holder.tip_bottom{padding-top:5px}#tiptip_holder.tip_bottom #tiptip_arrow_inner{margin-top:-5px;margin-left:-6px;border-bottom-color:#333}#tiptip_holder.tip_right{padding-left:5px}#tiptip_holder.tip_right #tiptip_arrow_inner{margin-top:-6px;margin-left:-5px;border-right-color:#333}#tiptip_holder.tip_left{padding-right:5px}#tiptip_holder.tip_left #tiptip_arrow_inner{margin-top:-6px;margin-left:-7px;border-left-color:#333}#tiptip_content,.chart-tooltip,.wc_error_tip{color:#fff;font-size:.8em;max-width:150px;background:#333;text-align:center;border-radius:3px;padding:.618em 1em;box-shadow:0 1px 3px rgba(0,0,0,.2)}#tiptip_content code,.chart-tooltip code,.wc_error_tip code{padding:1px;background:#888}#tiptip_arrow,#tiptip_arrow_inner{position:absolute;border-color:transparent;border-style:solid;border-width:6px;height:0;width:0}.wc_error_tip{max-width:20em;line-height:1.8em;position:absolute;white-space:normal;background:#d82223;margin:1.5em 1px 0 -1em;z-index:9999999}.wc_error_tip:after{content:"";display:block;border:8px solid #d82223;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-3px;left:50%;margin:-1em 0 0 -3px}img.ui-datepicker-trigger{vertical-align:middle;margin-top:-1px;cursor:pointer}.wc-metabox-content img.ui-datepicker-trigger,.woocommerce_options_panel img.ui-datepicker-trigger{float:left;margin-right:8px;margin-top:4px;margin-left:4px}#ui-datepicker-div{display:none}.woocommerce-reports-wide.woocommerce-reports-wrap,.woocommerce-reports-wrap.woocommerce-reports-wrap{margin-left:300px;padding-top:18px}.woocommerce-reports-wide.halved,.woocommerce-reports-wrap.halved{margin:0;overflow:hidden;zoom:1}.woocommerce-reports-wide .widefat td,.woocommerce-reports-wrap .widefat td{vertical-align:top;padding:7px}.woocommerce-reports-wide .widefat td .description,.woocommerce-reports-wrap .widefat td .description{margin:4px 0 0}.woocommerce-reports-wide .postbox:after,.woocommerce-reports-wrap .postbox:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox h3,.woocommerce-reports-wrap .postbox h3{cursor:default!important}.woocommerce-reports-wide .postbox .inside,.woocommerce-reports-wrap .postbox .inside{padding:10px;margin:0!important}.woocommerce-reports-wide .postbox div.stats_range,.woocommerce-reports-wide .postbox h3.stats_range,.woocommerce-reports-wrap .postbox div.stats_range,.woocommerce-reports-wrap .postbox h3.stats_range{border-bottom-color:#dfdfdf;margin:0;padding:0!important}.woocommerce-reports-wide .postbox div.stats_range .export_csv,.woocommerce-reports-wide .postbox h3.stats_range .export_csv,.woocommerce-reports-wrap .postbox div.stats_range .export_csv,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv{float:right;line-height:26px;border-left:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range .export_csv:before,.woocommerce-reports-wide .postbox h3.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox div.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;content:"";text-decoration:none;margin-right:4px}.woocommerce-reports-wide .postbox div.stats_range ul,.woocommerce-reports-wide .postbox h3.stats_range ul,.woocommerce-reports-wrap .postbox div.stats_range ul,.woocommerce-reports-wrap .postbox h3.stats_range ul{list-style:none;margin:0;padding:0;zoom:1;background:#f5f5f5;border-bottom:1px solid #ccc}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox div.stats_range ul:before,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:before,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:before,.woocommerce-reports-wrap .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:before{content:" ";display:table}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:after{clear:both}.woocommerce-reports-wide .postbox div.stats_range ul li,.woocommerce-reports-wide .postbox h3.stats_range ul li,.woocommerce-reports-wrap .postbox div.stats_range ul li,.woocommerce-reports-wrap .postbox h3.stats_range ul li{float:left;margin:0;padding:0;line-height:26px;font-weight:700;font-size:14px}.woocommerce-reports-wide .postbox div.stats_range ul li a,.woocommerce-reports-wide .postbox h3.stats_range ul li a,.woocommerce-reports-wrap .postbox div.stats_range ul li a,.woocommerce-reports-wrap .postbox h3.stats_range ul li a{border-right:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range ul li.active,.woocommerce-reports-wide .postbox h3.stats_range ul li.active,.woocommerce-reports-wrap .postbox div.stats_range ul li.active,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active{background:#fff;-webkit-box-shadow:0 4px 0 0 #fff;box-shadow:0 4px 0 0 #fff}.woocommerce-reports-wide .postbox div.stats_range ul li.active a,.woocommerce-reports-wide .postbox h3.stats_range ul li.active a,.woocommerce-reports-wrap .postbox div.stats_range ul li.active a,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active a{color:#777}.woocommerce-reports-wide .postbox div.stats_range ul li.custom,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom{padding:9px 10px;vertical-align:middle}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form{display:inline;margin:0}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form input.range_datepicker{padding:0;margin:0 10px 0 0;background:0 0;border:0;color:#777;text-align:center;-webkit-box-shadow:none;box-shadow:none}.woocommerce-reports-wide .postbox .chart-with-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar{padding:12px 12px 12px 249px;margin:0!important}.woocommerce-reports-wide .postbox .chart-with-sidebar .chart-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar .chart-sidebar{width:225px;margin-left:-237px;float:left}.woocommerce-reports-wide .postbox .chart-widgets,.woocommerce-reports-wrap .postbox .chart-widgets{margin:0;padding:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget{margin:0 0 1em;background:#fafafa;border:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4{background:#fff;border:1px solid #dfdfdf;border-left-width:0;border-right-width:0;padding:10px;margin:0;color:#2ea2cc;border-top-width:0;background-image:-webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9));background-image:-webkit-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-moz-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-o-linear-gradient(bottom,#ececec,#f9f9f9);background-image:linear-gradient(to top,#ececec,#f9f9f9)}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr.active td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr.active td{background:#f5f5f5}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4.section_title:hover,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4.section_title:hover{color:#a00}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title{cursor:pointer}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span{display:block}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin-left:.618em;content:"";text-decoration:none;float:right;font-size:.9em;line-height:1.618}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open{color:#333}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open span:after{display:none}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section{border-bottom:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section .select2-container,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section .select2-container{width:100%!important}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section:last-of-type,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section:last-of-type{border-radius:0 0 3px 3px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td{padding:7px 10px;vertical-align:top;border-top:1px solid #e5e5e5;line-height:1.4em}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.sparkline,form.report_filters div,form.report_filters input,form.report_filters label,form.report_filters p{vertical-align:middle}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr:first-child td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr:first-child td{border-top:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name{max-width:175px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name a,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name a{word-wrap:break-word}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table .wc_sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table .wc_sparkline{width:32px;height:1em;display:block;float:right}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p{margin:0;padding:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p .submit{margin-top:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget #product_ids,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget #product_ids{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_none,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_none{float:right;color:#999;margin-left:4px;margin-top:10px}.woocommerce-reports-wide .postbox .chart-legend,.woocommerce-reports-wrap .postbox .chart-legend{list-style:none;margin:0 0 1em;padding:0;border:1px solid #dfdfdf;border-right-width:0;border-bottom-width:0;background:#fff}.woocommerce-reports-wide .postbox .chart-legend li,.woocommerce-reports-wrap .postbox .chart-legend li{border-right:5px solid #aaa;color:#aaa;padding:1em;display:block;margin:0;-webkit-transition:all ease .5s;box-shadow:inset 0 -1px 0 0 #dfdfdf}.woocommerce-reports-wide .postbox .chart-legend li strong,.woocommerce-reports-wrap .postbox .chart-legend li strong{font-size:1.618em;line-height:1.2em;color:#464646;font-weight:400;display:block;font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif}.woocommerce-reports-wide .postbox .chart-legend li strong del,.woocommerce-reports-wrap .postbox .chart-legend li strong del{color:#e74c3c;font-weight:400}.woocommerce-reports-wide .postbox .chart-legend li:hover,.woocommerce-reports-wrap .postbox .chart-legend li:hover{box-shadow:inset 0 -1px 0 0 #dfdfdf,inset 300px 0 0 rgba(156,93,144,.1);border-right:5px solid #9c5d90!important;padding-left:1.5em;color:#9c5d90}.woocommerce-reports-wide .postbox .pie-chart-legend,.woocommerce-reports-wrap .postbox .pie-chart-legend{margin:12px 0 0;overflow:hidden}.woocommerce-reports-wide .postbox .pie-chart-legend li,.woocommerce-reports-wrap .postbox .pie-chart-legend li{float:left;margin:0;padding:6px 0 0;border-top:4px solid #999;text-align:center;box-sizing:border-box;width:50%}.woocommerce-reports-wide .postbox .stat,.woocommerce-reports-wrap .postbox .stat{font-size:1.5em!important;font-weight:700;text-align:center}.woocommerce-reports-wide .postbox .chart-placeholder,.woocommerce-reports-wrap .postbox .chart-placeholder{width:100%;height:650px;overflow:hidden;position:relative}.woocommerce-reports-wide .postbox .chart-prompt,.woocommerce-reports-wrap .postbox .chart-prompt{line-height:650px;margin:0;color:#999;font-size:1.2em;font-style:italic;text-align:center}.woocommerce-reports-wide .postbox .chart-container,.woocommerce-reports-wrap .postbox .chart-container{background:#fff;padding:12px;position:relative;border:1px solid #dfdfdf;border-radius:3px}.woocommerce-reports-wide .postbox .main .chart-legend,.woocommerce-reports-wrap .postbox .main .chart-legend{margin-top:12px}.woocommerce-reports-wide .postbox .main .chart-legend li,.woocommerce-reports-wrap .postbox .main .chart-legend li{border-right:0;margin:0 8px 0 0;float:left;border-top:4px solid #aaa}.woocommerce-reports-wide .woocommerce-reports-main,.woocommerce-reports-wrap .woocommerce-reports-main{float:left;min-width:100%}.woocommerce-reports-wide .woocommerce-reports-main table td,.woocommerce-reports-wrap .woocommerce-reports-main table td{padding:9px}.woocommerce-reports-wide .woocommerce-reports-sidebar,.woocommerce-reports-wrap .woocommerce-reports-sidebar{display:inline;width:281px;margin-left:-300px;clear:both;float:left}.woocommerce-reports-wide .woocommerce-reports-left,.woocommerce-reports-wrap .woocommerce-reports-left{width:49.5%;float:left}.woocommerce-reports-wide .woocommerce-reports-right,.woocommerce-reports-wrap .woocommerce-reports-right{width:49.5%;float:right}.woocommerce-reports-wide .column-wc_actions a.edit,.woocommerce-reports-wide .column-wc_actions a.view,.woocommerce-reports-wrap .column-wc_actions a.edit,.woocommerce-reports-wrap .column-wc_actions a.view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;line-height:1.85}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after{content:"\f464"}.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{content:"\f177"}.woocommerce-wide-reports-wrap{padding-bottom:11px}.woocommerce-wide-reports-wrap .widefat .export-data{float:right}.woocommerce-wide-reports-wrap .widefat td,.woocommerce-wide-reports-wrap .widefat th{vertical-align:middle;padding:7px}.chart-tooltip{position:absolute;display:none;line-height:1}table.bar_chart{width:100%}table.bar_chart thead th{text-align:left;color:#ccc;padding:6px 0}table.bar_chart tbody th{padding:6px 0;width:25%;text-align:left!important;font-weight:400!important;border-bottom:1px solid #fee}table.bar_chart tbody td{text-align:right;line-height:24px;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td span{color:#8a4b75;display:block}table.bar_chart tbody td span.alt{color:#47a03e;margin-top:6px}table.bar_chart tbody td.bars{position:relative;text-align:left;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td.bars a,table.bar_chart tbody td.bars span{text-decoration:none;clear:both;background:#8a4b75;float:left;display:block;line-height:24px;height:24px;-moz-border-radius:3px;-webkit-border-radius:3px;-o-border-radius:3px;-khtml-border-radius:3px;border-radius:3px}.post-type-product .woocommerce-BlankState-message:before,.post-type-shop_coupon .woocommerce-BlankState-message:before,.post-type-shop_order .woocommerce-BlankState-message:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}table.bar_chart tbody td.bars span.alt{clear:both;background:#47a03e}table.bar_chart tbody td.bars span.alt span{margin:0;color:#c5dec2!important;text-shadow:0 1px 0 #47a03e;background:0 0}.post-type-shop_order .woocommerce-BlankState-message:before{content:""}.post-type-shop_coupon .woocommerce-BlankState-message:before{content:""}.post-type-product .woocommerce-BlankState-message:before{content:""}.woocommerce-BlankState{text-align:center;padding:5em 0 0}.woocommerce-BlankState .woocommerce-BlankState-message{color:#aaa;margin:0 auto 1.5em;line-height:1.5em;font-size:1.2em;max-width:500px}.woocommerce-BlankState .woocommerce-BlankState-message:before{color:#ddd;text-shadow:0 -1px 1px rgba(0,0,0,.2),0 1px 0 rgba(255,255,255,.8);font-size:8em;display:block;position:relative!important;top:auto;left:auto;line-height:1em;margin:0 0 .1875em}.woocommerce-BlankState .woocommerce-BlankState-cta{font-size:1.2em;padding:.75em 1.5em;height:auto}@media only screen and (max-width:1280px){#order_data .order_data_column{width:48%}#order_data .order_data_column:first-child{width:100%}.woocommerce_options_panel .description{display:block;clear:both;margin-left:0}.woocommerce_options_panel .dimensions_field .wrap,.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:80%}.woocommerce_options_panel .downloadable_files,.woocommerce_variations .downloadable_files{padding:0;clear:both}.woocommerce_options_panel .downloadable_files label,.woocommerce_variations .downloadable_files label{position:static}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{margin:0 12px 24px;width:94%}.woocommerce_options_panel .downloadable_files table .sort,.woocommerce_variations .downloadable_files table .sort{visibility:hidden}.woocommerce_options_panel .woocommerce_variable_attributes .downloadable_files table,.woocommerce_variations .woocommerce_variable_attributes .downloadable_files table{margin:0 0 1em;width:100%}}@media only screen and (max-width:900px){#woocommerce-coupon-data ul.coupon_data_tabs,#woocommerce-product-data .wc-tabs-back,#woocommerce-product-data ul.product_data_tabs{width:10%}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{width:90%}#woocommerce-coupon-data ul.coupon_data_tabs li a,#woocommerce-product-data ul.product_data_tabs li a{position:relative;text-indent:-999px;padding:10px}#woocommerce-coupon-data ul.coupon_data_tabs li a:before,#woocommerce-product-data ul.product_data_tabs li a:before{position:absolute;top:0;right:0;bottom:0;left:0;text-indent:0;text-align:center;line-height:40px;width:100%;height:40px}}@media only screen and (max-width:782px){#wp-excerpt-media-buttons a{font-size:16px;line-height:37px;height:39px;padding:0 20px 0 15px}#wp-excerpt-editor-tools{padding-top:20px;padding-right:15px;overflow:hidden;margin-bottom:-1px}.post-type-product .wp-list-table .is-expanded td:not(.hidden),.post-type-shop_order .wp-list-table .is-expanded td:not(.hidden){overflow:visible}#woocommerce-product-data .checkbox{width:25px}.variations-pagenav{float:none;text-align:center;font-size:18px}.variations-pagenav .displaying-num{font-size:16px}.variations-pagenav a{padding:8px 20px 11px;font-size:18px}.variations-pagenav select{padding:0 20px}.variations-defaults{float:none;text-align:center;margin-top:10px}.post-type-product .wp-list-table .column-thumb{display:none;text-align:left;padding-bottom:0}.post-type-product .wp-list-table .column-thumb:before{display:none!important}.post-type-product .wp-list-table .column-thumb img{max-width:32px}.post-type-product .wp-list-table .toggle-row{top:-28px}.post-type-shop_order .wp-list-table .column-order_status{display:none;text-align:left;padding-bottom:0}.post-type-shop_order .wp-list-table .column-order_status mark{margin:0}.post-type-shop_order .wp-list-table .column-order_status:before{display:none!important}.post-type-shop_order .wp-list-table .column-customer_message,.post-type-shop_order .wp-list-table .column-order_notes{text-align:inherit}.post-type-shop_order .wp-list-table .column-order_notes .note-on{font-size:1.3em;margin:0}.post-type-shop_order .wp-list-table .toggle-row{top:-15px}}@media only screen and (max-width:500px){.woocommerce_options_panel label,.woocommerce_options_panel legend{float:none;width:auto;display:block;margin:0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px!important}}.wc-backbone-modal *{box-sizing:border-box}.wc-backbone-modal .wc-backbone-modal-content{position:fixed;background:#fff;z-index:100000;left:50%;top:50%;transform:translate(-50%,-50%);width:500px}.wc-backbone-modal .wc-backbone-modal-content article{overflow:auto}.wc-backbone-modal.wc-backbone-modal-shipping-method-settings .wc-backbone-modal-content{width:75%;min-width:500px}.wc-backbone-modal-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;min-height:360px;background:#000;opacity:.7;z-index:99900}.wc-backbone-modal-main{padding-bottom:55px}.wc-backbone-modal-main article,.wc-backbone-modal-main header{display:block;position:relative}.wc-backbone-modal-main .wc-backbone-modal-header{height:auto;background:#fcfcfc;padding:1em 1.5em;border-bottom:1px solid #ddd}.wc-backbone-modal-main .wc-backbone-modal-header h1{margin:0;font-size:18px;font-weight:700;line-height:1.5em}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link{cursor:pointer;color:#777;height:54px;width:54px;padding:0;position:absolute;top:0;right:0;text-align:center;border:0;border-left:1px solid #ddd;background-color:transparent;-webkit-transition:color .1s ease-in-out,background .1s ease-in-out;transition:color .1s ease-in-out,background .1s ease-in-out}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:before{font:400 22px/50px dashicons!important;color:#666;display:block;content:'\f335';font-weight:300}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus,.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:hover{background:#ddd;border-color:#ccc;color:#000}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus{outline:0}.wc-backbone-modal-main article{padding:1.5em}.wc-backbone-modal-main article p{margin:1.5em 0}.wc-backbone-modal-main article p:last-child,.wc-backbone-modal-main footer .inner .button{margin-bottom:0}.wc-backbone-modal-main article p:first-child{margin-top:0}.wc-backbone-modal-main article .pagination{padding:10px 0 0;text-align:center}.wc-backbone-modal-main footer{position:absolute;left:0;right:0;bottom:0;z-index:100;padding:1em 1.5em;background:#fcfcfc;border-top:1px solid #dfdfdf;box-shadow:0 -4px 4px -4px rgba(0,0,0,.1)}.wc-backbone-modal-main footer .inner{float:right;line-height:23px}.select2-drop{z-index:999999!important}.select2-container-multi .select2-choices .select2-search-field input{font-family:inherit;font-size:inherit;font-weight:inherit;padding:3px 5px}.select2-container{line-height:1.85em;font-size:14px} \ No newline at end of file diff --git a/assets/css/admin.scss b/assets/css/admin.scss index bf0f9457d61..52ba29e12a9 100644 --- a/assets/css/admin.scss +++ b/assets/css/admin.scss @@ -2055,7 +2055,13 @@ table.wc_input_table { padding: 5px 10px; margin: 0; border: 0; + outline: 0; background: transparent none; + + &:focus { + outline: 0; + box-shadow: none; + } } &.compound, diff --git a/includes/class-wc-tax.php b/includes/class-wc-tax.php index 7de38350d95..318164655cc 100644 --- a/includes/class-wc-tax.php +++ b/includes/class-wc-tax.php @@ -266,19 +266,48 @@ class WC_Tax { return $shipping_rates; } + /** + * Does the sort comparison. + */ + private static function sort_rates_callback( $rate1, $rate2 ) { + if ( $rate1->tax_rate_priority !== $rate2->tax_rate_priority ) { + return $rate1->tax_rate_priority < $rate2->tax_rate_priority ? -1 : 1; // ASC + } elseif ( $rate1->tax_rate_country !== $rate2->tax_rate_country ) { + if ( '' === $rate1->tax_rate_country ) { + return 1; + } + if ( '' === $rate2->tax_rate_country ) { + return -1; + } + return strcmp( $rate1->tax_rate_country, $rate2->tax_rate_country ) > 0 ? 1 : -1; + } elseif ( $rate1->tax_rate_state !== $rate2->tax_rate_state ) { + if ( '' === $rate1->tax_rate_state ) { + return 1; + } + if ( '' === $rate2->tax_rate_state ) { + return -1; + } + return strcmp( $rate1->tax_rate_state, $rate2->tax_rate_state ) > 0 ? 1 : -1; + } else { + return $rate1->tax_rate_id < $rate2->tax_rate_id ? -1 : 1; // Identical - use ID + } + } + /** * Logical sort order for tax rates based on the following in order of priority: * - Priority * - County code * - State code - * - # of zip codes - * - # of cities * @param array $rates * @return array * @todo remove tax_rate_order column */ private static function sort_rates( $rates ) { - + uasort( $rates, __CLASS__ . '::sort_rates_callback' ); + $i = 0; + foreach ( $rates as $key => $rate ) { + $rates[ $key ]->tax_rate_order = $i++; + } return $rates; } From 3b42677b83c5f0381e4d4cdb76b46812b2415cb2 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 27 Jul 2016 11:39:50 +0100 Subject: [PATCH 159/298] Padding --- assets/css/admin.css | 2 +- assets/css/admin.scss | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/css/admin.css b/assets/css/admin.css index 538b0962c3e..b0ef0d8f505 100644 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -1 +1 @@ -@charset "UTF-8";.button.wc-reload:after,.woocommerce-help-tip:after{speak:none;text-transform:none;-webkit-font-smoothing:antialiased}@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg)}}@-moz-keyframes spin{100%{-moz-transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}.select2-container{margin:0;position:relative;display:block!important;zoom:1;vertical-align:middle}.select2-container,.select2-drop,.select2-search,.select2-search input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{display:block;padding:0 0 0 8px;overflow:hidden;position:relative;border:1px solid #ccc;white-space:nowrap;color:#444;text-decoration:none;border-radius:3px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;font-weight:400}html[dir=rtl] .select2-container .select2-choice{padding:0 8px 0 0}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#ccc;border-radius:0 0 4px 4px}.select2-container.select2-allowclear .select2-choice .select2-chosen{margin-right:42px}.select2-container .select2-choice>.select2-chosen{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:none;width:auto}html[dir=rtl] .select2-container .select2-choice>.select2-chosen{margin-left:26px;margin-right:0}.select2-container .select2-choice abbr{display:none;width:12px;height:12px;position:absolute;right:24px;top:5px;font-size:1px;text-decoration:none;border:0;background:url(../images/select2.png) right top no-repeat;cursor:pointer;outline:0}.select2-container.select2-allowclear .select2-choice abbr{display:inline-block}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop-mask{border:0;margin:0;padding:0;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:9998;background-color:#fff;filter:alpha(opacity=0)}.select2-drop{width:100%;margin-top:-1px;position:absolute;top:100%;background:#fff;color:#000;border:1px solid #ccc;border-top:0;border-radius:0 0 3px 3px}.select2-drop.select2-drop-above{margin-top:1px;border-top:1px solid #ccc;border-bottom:0;border-radius:3px 3px 0 0}.select2-drop-active{border:1px solid #666;border-top:none}.select2-drop.select2-drop-above.select2-drop-active{border-top:1px solid #666}.select2-drop-auto-width{border-top:1px solid #ccc;width:auto}.select2-drop-auto-width .select2-search{padding-top:4px}.select2-container .select2-choice .select2-arrow{display:inline-block;width:18px;height:100%;position:absolute;right:0;top:0;border-radius:0 3px 3px 0;background-clip:padding-box}html[dir=rtl] .select2-container .select2-choice .select2-arrow{left:0;right:auto;border-radius:3px 0 0 3px}.select2-container .select2-choice .select2-arrow b{display:block;width:100%;height:100%;position:relative}.select2-container .select2-choice .select2-arrow b:after{position:absolute;display:block;content:"";top:50%;left:50%;border:4px solid transparent;border-top-color:#666;margin-left:-7px;margin-top:-2px}.select2-search{display:inline-block;width:100%;margin:0;padding-left:4px;padding-right:4px;position:relative;z-index:10000;white-space:nowrap;padding-bottom:4px}.select2-search input{width:100%;height:auto!important;padding:4px 20px 4px 5px!important;margin:0;outline:0;font-family:sans-serif;font-size:1em;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none;background:url(../images/select2.png) 100% -22px no-repeat #fff}html[dir=rtl] .select2-search input{padding:4px 5px 4px 20px;background:url(../images/select2.png) -37px -22px no-repeat #fff}.select2-drop.select2-drop-above .select2-search input{margin-top:4px}.select2-search input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff}.select2-container-active .select2-choice,.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-dropdown-open .select2-choice{border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-dropdown-open .select2-choice .select2-arrow b:after{border-top-color:transparent;border-bottom-color:#666;margin-top:-6px}.select2-dropdown-open.select2-drop-above .select2-choice,.select2-dropdown-open.select2-drop-above .select2-choices{border:1px solid #666;border-top-color:transparent}.select2-dropdown-open .select2-choice .select2-arrow{background:0 0;border-left:none;filter:none}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow{border-right:none}.select2-dropdown-open .select2-choice .select2-arrow b{background-position:-18px 1px}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow b{background-position:-16px 1px}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.select2-results{max-height:200px;padding:4px;margin:0;position:relative;overflow-x:hidden;overflow-y:auto;-webkit-tap-highlight-color:transparent;background:#fafafa}html[dir=rtl] .select2-results{padding:0 4px 0 0;margin:4px 0 4px 4px}.select2-results ul.select2-result-sub{margin:0;padding-left:0}.select2-results li{list-style:none;display:list-item;background-image:none;margin:3px 0}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:700}.select2-results .select2-result-label{padding:5px 7px;margin:0;cursor:pointer;min-height:1em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select2-results-dept-1 .select2-result-label{padding-left:20px}.select2-results-dept-2 .select2-result-label{padding-left:40px}.select2-results-dept-3 .select2-result-label{padding-left:60px}.select2-results-dept-4 .select2-result-label{padding-left:80px}.select2-results-dept-5 .select2-result-label{padding-left:100px}.select2-results-dept-6 .select2-result-label{padding-left:110px}.select2-results-dept-7 .select2-result-label{padding-left:120px}.select2-results .select2-highlighted{background:#f1f1f1;color:#000;border-radius:3px}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:0 0}.select2-results .select2-highlighted ul{background:#fff;color:#000}.select2-results .select2-ajax-error,.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item;padding-left:5px}.select2-results .select2-disabled.select2-highlighted{color:#666;background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-disabled{background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-selected{display:none}.select2-more-results.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #f4f4f4}.select2-results .select2-ajax-error{background:rgba(255,50,50,.2)}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice .select2-arrow{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container.select2-container-disabled .select2-choice abbr{display:none}.select2-container-multi .select2-choices{height:auto!important;height:1%;margin:0;padding:0 5px 0 0;position:relative;border:1px solid #ccc;cursor:text;overflow:hidden;background-color:#fff;min-height:26px}html[dir=rtl] .select2-container-multi .select2-choices{padding:0 0 0 5px}.select2-locked{padding:3px 5px!important}.select2-container-multi.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-container-multi .select2-choices li{float:left;list-style:none}html[dir=rtl] .select2-container-multi .select2-choices li{float:right}.select2-container-multi .select2-choices .select2-search-field{margin:0;padding:0;white-space:nowrap}.select2-container-multi .select2-choices .select2-search-field:first-child{width:100%}.select2-container-multi .select2-choices .select2-search-field input{margin:1px 0;outline:0;border:0;-webkit-box-shadow:none;box-shadow:none;background:0 0!important}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff!important}.select2-default{color:#999!important}.select2-container-multi .select2-choices .select2-search-choice{padding:5px 8px 5px 24px;margin:3px 0 3px 5px;position:relative;line-height:15px;color:#333;cursor:default;border-radius:2px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#e4e4e4}html[dir=rtl] .select2-container-multi .select2-choices .select2-search-choice{margin:3px 5px 3px 0;padding:5px 24px 5px 8px}.select2-container-multi .select2-choices .select2-search-choice .select2-chosen{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;width:12px;height:13px;position:absolute;right:7px;top:6px;font-size:1px;outline:0;background:url(../images/select2.png) right top no-repeat}html[dir=rtl] .select2-search-choice-close{right:auto;left:7px}.select2-container-multi .select2-search-choice-close{left:7px}html[dir=rtl] .select2-container-multi .select2-search-choice-close{left:auto;right:7px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover,.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{padding:3px 5px;border:1px solid #ddd;background-image:none;background-color:#f4f4f4}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none;background:0 0}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-match{text-decoration:underline}.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.select2-display-none{display:none}.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:2dppx){.select2-search input{background-image:url(../images/select2x2.png)!important;background-repeat:no-repeat!important;background-size:60px 40px!important;background-position:100% -21px!important}}@font-face{font-family:star;src:url(../fonts/star.eot);src:url(../fonts/star.eot?#iefix) format("embedded-opentype"),url(../fonts/star.woff) format("woff"),url(../fonts/star.ttf) format("truetype"),url(../fonts/star.svg#star) format("svg");font-weight:400;font-style:normal}@font-face{font-family:WooCommerce;src:url(../fonts/WooCommerce.eot);src:url(../fonts/WooCommerce.eot?#iefix) format("embedded-opentype"),url(../fonts/WooCommerce.woff) format("woff"),url(../fonts/WooCommerce.ttf) format("truetype"),url(../fonts/WooCommerce.svg#WooCommerce) format("svg");font-weight:400;font-style:normal}.blockUI.blockOverlay:before{height:1em;width:1em;position:absolute;top:50%;left:50%;margin-left:-.5em;margin-top:-.5em;display:block;content:"";-webkit-animation:spin 1s ease-in-out infinite;-moz-animation:spin 1s ease-in-out infinite;animation:spin 1s ease-in-out infinite;background:url(../images/icons/loader.svg) center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75)}.wc_addons_wrap .products{overflow:hidden}.wc_addons_wrap .products li{float:left;margin:0 1em 1em 0!important;padding:0;vertical-align:top;width:300px}.wc_addons_wrap .products li a{text-decoration:none;color:inherit;border:1px solid #ddd;display:block;min-height:220px;overflow:hidden;background:#f5f5f5;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1)}.wc_addons_wrap .products li a img{max-width:258px;max-height:24px;padding:17px 20px;display:block;margin:0;background:#fff;border-right:260px solid #fff}.wc_addons_wrap .products li a .price,.wc_addons_wrap .products li a img.extension-thumb+h3{display:none}.wc_addons_wrap .products li a h2,.wc_addons_wrap .products li a h3{margin:0!important;padding:20px!important;background:#fff}.wc_addons_wrap .products li a p{padding:20px!important;margin:0!important;border-top:1px solid #f1f1f1}.wc_addons_wrap .products li a:focus,.wc_addons_wrap .products li a:hover{background-color:#fff}.wc_addons_wrap .storefront{background:url(../images/storefront-bg.jpg) bottom right #f6f6f6;border:1px solid #ddd;padding:20px;overflow:hidden;zoom:1}.wc_addons_wrap .storefront img{width:278px;height:auto;float:left;margin:0 20px 0 0;box-shadow:0 1px 6px rgba(0,0,0,.1)}.wc_addons_wrap .storefront p{max-width:750px}.woocommerce-BlankState a.button-primary,.woocommerce-BlankState button.button-primary,.woocommerce-message a.button-primary,.woocommerce-message button.button-primary{background:#bb77ae;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;color:#fff;text-shadow:0 -1px 1px #A36597,1px 0 1px #A36597,0 1px 1px #A36597,-1px 0 1px #A36597}.woocommerce-BlankState a.button-primary:active,.woocommerce-BlankState a.button-primary:focus,.woocommerce-BlankState a.button-primary:hover,.woocommerce-BlankState button.button-primary:active,.woocommerce-BlankState button.button-primary:focus,.woocommerce-BlankState button.button-primary:hover,.woocommerce-message a.button-primary:active,.woocommerce-message a.button-primary:focus,.woocommerce-message a.button-primary:hover,.woocommerce-message button.button-primary:active,.woocommerce-message button.button-primary:focus,.woocommerce-message button.button-primary:hover{background:#A36597;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597}.woocommerce-message{position:relative;border-left-color:#cc99c2!important;overflow:hidden}.woocommerce-message a.docs,.woocommerce-message a.skip{text-decoration:none!important}.woocommerce-message a.woocommerce-message-close{position:absolute;top:10px;right:10px;padding:10px 15px 10px 21px;font-size:13px;line-height:1.23076923;text-decoration:none}.woocommerce-message a.woocommerce-message-close:before{position:absolute;top:8px;left:0;-webkit-transition:all .1s ease-in-out;transition:all .1s ease-in-out}.woocommerce-message .twitter-share-button{margin-top:-3px;margin-left:3px;vertical-align:middle}#variable_product_options #message,#variable_product_options .notice{margin:10px}.clear{clear:both}#woocommerce-fields-bulk.inline-edit-col label,#woocommerce-fields.inline-edit-col{clear:left}.wrap.woocommerce div.error,.wrap.woocommerce div.updated{margin-top:10px}mark.amount{background:0 0;color:inherit}.postbox,.woocommerce{input:invalid;input-border:1px solid #cc010b;input-background:#ffebe8}.simplify-commerce-banner{overflow:hidden}.simplify-commerce-banner img{float:right;padding:15px 0;margin-left:1em;width:200px}.woocommerce-help-tip{color:#666;display:inline-block;font-size:1.1em;font-style:normal;height:16px;line-height:16px;position:relative;vertical-align:middle;width:16px}.woocommerce-help-tip:after{font-family:Dashicons;font-weight:400;font-variant:normal;line-height:1;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";cursor:help}h2 .woocommerce-help-tip{margin-top:-5px;margin-left:.25em}table.wc_status_table{margin-bottom:1em}table.wc_status_table h2{font-size:14px;margin:0}table.wc_status_table tr:nth-child(2n) td,table.wc_status_table tr:nth-child(2n) th{background:#fcfcfc}table.wc_status_table th{font-weight:700;padding:9px}table.wc_status_table td:first-child{width:33%}table.wc_status_table td.help{width:1em}table.wc_status_table td{padding:9px;font-size:1.1em}table.wc_status_table td mark{background:0 0}table.wc_status_table td mark.yes{color:#7ad03a}table.wc_status_table td mark.no{color:#999}table.wc_status_table td mark.error{color:#a00}table.wc_status_table td ul{margin:0}table.wc_status_table .help_tip{cursor:help}#debug-report{display:none;margin:10px 0;padding:0;position:relative}#debug-report textarea{font-family:monospace;width:100%;margin:0;height:300px;padding:20px;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;resize:none;font-size:12px;line-height:20px;outline:0}#log-viewer-select{padding:10px 0 8px;line-height:180%}#log-viewer textarea{width:100%;resize:vertical}.inline-edit-product.quick-edit-row .inline-edit-col-center,.inline-edit-product.quick-edit-row .inline-edit-col-right{float:right!important}#woocommerce-fields.inline-edit-col label.featured,#woocommerce-fields.inline-edit-col label.manage_stock{margin-left:10px}#woocommerce-fields.inline-edit-col .dimensions div{display:block;margin:.2em 0}#woocommerce-fields.inline-edit-col .dimensions div span.title{display:block;float:left;width:5em}#woocommerce-fields.inline-edit-col .dimensions div span.input-text-wrap{display:block;margin-left:5em}#woocommerce-fields.inline-edit-col .text{box-sizing:border-box;width:99%;float:left;margin:1px 1% 1px 1px}#woocommerce-fields.inline-edit-col .height,#woocommerce-fields.inline-edit-col .length,#woocommerce-fields.inline-edit-col .width{width:32.33%}#woocommerce-fields.inline-edit-col .height{margin-right:0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group label{clear:none;width:49%;margin:.2em 0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group.dimensions label{width:75%;max-width:75%}#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .regular_price,#woocommerce-fields-bulk.inline-edit-col .sale_price,#woocommerce-fields-bulk.inline-edit-col .stock,#woocommerce-fields-bulk.inline-edit-col .weight{box-sizing:border-box;width:100%;margin-left:4.4em}#woocommerce-fields-bulk.inline-edit-col .height,#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .width{box-sizing:border-box;width:25%}.column-coupon_code{line-height:2.25em}.column-coupon_code,ul.wc_coupon_list{margin:0;overflow:hidden;zoom:1;clear:both}ul.wc_coupon_list li{margin:0}ul.wc_coupon_list li.code{display:inline-block}ul.wc_coupon_list li.code:after{content:", "}ul.wc_coupon_list li.code:last-of-type:after{display:none}ul.wc_coupon_list li.code .tips{cursor:pointer}ul.wc_coupon_list_block{margin:0;padding-bottom:2px}ul.wc_coupon_list_block li{border-top:1px solid #fff;border-bottom:1px solid #ccc;line-height:2.5em;margin:0;padding:.5em 0}ul.wc_coupon_list_block li:first-child{border-top:0;padding-top:0}ul.wc_coupon_list_block li:last-child{border-bottom:0;padding-bottom:0}.button.wc-reload{text-indent:-9999px;position:relative;padding:0;height:28px;width:28px!important;display:inline-block}.button.wc-reload:after{font-family:Dashicons;font-weight:400;font-variant:normal;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:28px}#order_data h2,#order_data p.order_number{font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif;font-weight:400}.tablenav .actions{overflow:visible}.tablenav .select2-container{float:left;max-width:200px;font-size:14px;vertical-align:middle;margin:1px 6px 1px 1px}#woocommerce-order-data .handlediv,#woocommerce-order-data .hndle{display:none}#woocommerce-order-data .inside{display:block!important}#order_data{padding:23px 24px 12px}#order_data h2{margin:0;font-size:21px;line-height:1.2;text-shadow:1px 1px 1px #fff;padding:0}#order_data h3{font-size:14px}#order_data h3,#order_data h4{color:#333;margin:1.33em 0 0}#order_data p{color:#777}#order_data p.order_number{margin:0;line-height:1.6em;font-size:16px}#order_data .order_data_column_container{clear:both}#order_data .order_data_column{width:32%;padding:0 2% 0 0;float:left}#order_data .order_data_column:last-child{padding-right:0}#order_data .order_data_column p{padding:0!important}#order_data .order_data_column .address strong{display:block}#order_data .order_data_column .form-field{float:left;width:48%;padding:0;margin:9px 0 0}#order_data .order_data_column .form-field label{display:block;padding:0 0 3px}#order_data .order_data_column .form-field input,#order_data .order_data_column .form-field select,#order_data .order_data_column .form-field textarea{width:100%}#order_data .order_data_column .form-field .select2-container{width:100%!important}#order_data .order_data_column .form-field .date-picker{width:50%}#order_data .order_data_column .form-field .hour,#order_data .order_data_column .form-field .minute{width:3em}#order_data .order_data_column .form-field small{display:block;margin:5px 0 0;color:#999}#order_data .order_data_column .form-field.last{float:right}#order_data .order_data_column .form-field-wide{width:100%;clear:both}#order_data .order_data_column .form-field-wide .wc-customer-search,#order_data .order_data_column .form-field-wide .wc-enhanced-select,#order_data .order_data_column .form-field-wide input,#order_data .order_data_column .form-field-wide select,#order_data .order_data_column .form-field-wide textarea{width:100%}#order_data .order_data_column p.none_set{color:#999}#order_data .order_data_column ._billing_address_1_field,#order_data .order_data_column ._billing_city_field,#order_data .order_data_column ._billing_country_field,#order_data .order_data_column ._billing_email_field,#order_data .order_data_column ._billing_first_name_field,#order_data .order_data_column ._shipping_address_1_field,#order_data .order_data_column ._shipping_city_field,#order_data .order_data_column ._shipping_country_field,#order_data .order_data_column ._shipping_first_name_field{float:left}#order_data .order_data_column ._billing_address_2_field,#order_data .order_data_column ._billing_last_name_field,#order_data .order_data_column ._billing_phone_field,#order_data .order_data_column ._billing_postcode_field,#order_data .order_data_column ._billing_state_field,#order_data .order_data_column ._shipping_address_2_field,#order_data .order_data_column ._shipping_last_name_field,#order_data .order_data_column ._shipping_postcode_field,#order_data .order_data_column ._shipping_state_field,#order_data .order_data_column .wc-customer-user label a,#order_data .order_data_column .wc-order-status label a{float:right}#order_data .order_data_column ._billing_company_field,#order_data .order_data_column ._shipping_company_field,#order_data .order_data_column ._transaction_id_field{clear:both;width:100%}#order_data .order_data_column ._billing_email_field{clear:left}#order_data .order_data_column div.edit_address{display:none;zoom:1;padding-right:1px}#order_data .order_data_column .billing-same-as-shipping,#order_data .order_data_column .load_customer_billing,#order_data .order_data_column .load_customer_shipping,#order_data .order_data_column a.edit_address{width:14px;height:0;padding:14px 0 0;margin:0 0 0 6px;overflow:hidden;position:relative;color:#999;border:0;float:right}#order_data .order_data_column .billing-same-as-shipping:focus,#order_data .order_data_column .billing-same-as-shipping:hover,#order_data .order_data_column .load_customer_billing:focus,#order_data .order_data_column .load_customer_billing:hover,#order_data .order_data_column .load_customer_shipping:focus,#order_data .order_data_column .load_customer_shipping:hover,#order_data .order_data_column a.edit_address:focus,#order_data .order_data_column a.edit_address:hover{color:#000}#order_data .order_data_column .billing-same-as-shipping:after,#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after,#order_data .order_data_column a.edit_address: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}#order_data .order_data_column .billing-same-as-shipping:after{content:"\e008"}#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after{content:"\e03a"}#order_data .order_data_column a.edit_address:after{font-family:Dashicons;content:"\f464"}.order_actions{margin:0;overflow:hidden;zoom:1}.order_actions li{border-top:1px solid #fff;border-bottom:1px solid #ddd;padding:6px 0;margin:0;line-height:1.6em;float:left;width:50%;text-align:center}.order_actions li a{float:none;text-align:center;text-decoration:underline}.order_actions li.wide{width:auto;float:none;clear:both;padding:6px;text-align:left;overflow:hidden}.order_actions li #delete-action{line-height:25px;vertical-align:middle;text-align:left;float:left}.order_actions li .save_order{float:right}.order_actions li#actions{overflow:hidden}.order_actions li#actions .button{width:24px;box-sizing:border-box;float:right}.order_actions li#actions select{width:225px;box-sizing:border-box;float:left}#woocommerce-order-items .inside{margin:0;padding:0;background:#fefefe}#woocommerce-order-items .wc-order-data-row{border-bottom:1px solid #DFDFDF;padding:1.5em 2em;background:#f8f8f8;line-height:2em;text-align:right}#woocommerce-order-items .wc-order-data-row:after,#woocommerce-order-items .wc-order-data-row:before{content:" ";display:table}#woocommerce-order-items .wc-order-data-row:after{clear:both}#woocommerce-order-items .wc-order-data-row p{margin:0;line-height:2em}#woocommerce-order-items .wc-order-data-row .wc-used-coupons{text-align:left}#woocommerce-order-items .wc-order-data-row .wc-used-coupons .tips{display:inline-block}#woocommerce-order-items .wc-order-add-item{background:#fff;vertical-align:top;border-top:none}#woocommerce-order-items .wc-order-add-item .add_item_id,#woocommerce-order-items .wc-order-add-item .select2-container{vertical-align:top}#woocommerce-order-items .wc-order-add-item .add_item_id .search-field input,#woocommerce-order-items .wc-order-add-item .select2-container .search-field input{min-width:100px}#woocommerce-order-items .wc-order-add-item .select2-container{width:400px!important;text-align:left}#woocommerce-order-items .wc-order-add-item .calculate-action,#woocommerce-order-items .wc-order-add-item .cancel-action,#woocommerce-order-items .wc-order-add-item .save-action{float:left;margin-right:2px}#woocommerce-order-items .wc-used-coupons{float:left;width:50%}#woocommerce-order-items .wc-order-totals{float:right;width:50%;margin:0;padding:0;text-align:right}#woocommerce-order-items .wc-order-totals .amount{font-weight:700}#woocommerce-order-items .wc-order-totals .label{vertical-align:top}#woocommerce-order-items .wc-order-totals .total{font-size:1em!important;width:10em;margin:0 0 0 .5em;box-sizing:border-box}#woocommerce-order-items .wc-order-totals .total input[type=text]{width:96%;float:right}#woocommerce-order-items .wc-order-totals .refunded-total{color:#a00}#woocommerce-order-items .refund-actions{margin-top:5px;padding-top:12px;border-top:1px solid #DFDFDF}#woocommerce-order-items .refund-actions .button{float:right;margin-left:4px}#woocommerce-order-items .refund-actions .cancel-action,#woocommerce-order-items .wc-order-item-bulk-edit .cancel-action{float:left;margin-left:0}#woocommerce-order-items .add_meta{margin-left:0!important}#woocommerce-order-items h3 small{color:#999}#woocommerce-order-items .amount{white-space:nowrap}#woocommerce-order-items .add-items .description{margin-right:10px}#woocommerce-order-items .add-items .button{float:left;margin-right:.25em}#woocommerce-order-items .add-items .button-primary{float:none;margin-right:0}#woocommerce-order-items .inside{display:block!important}#woocommerce-order-items .handlediv,#woocommerce-order-items .hndle{display:none}#woocommerce-order-items .woocommerce_order_items_wrapper{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items{width:100%;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th{text-align:left;padding:1em;font-weight:400;color:#999;background:#f8f8f8;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th.sortable{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th .wc-arrow{float:right;position:relative;margin-right:-1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td{padding:1.5em 1em 1em;text-align:left;line-height:1.5em;vertical-align:top;border-bottom:1px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td select{width:50%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{font-size:14px;padding:4px;color:#555}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr td{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected{background:#F5EBF3}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected td{border-color:#E6CCE1;opacity:.8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:last-child td{border-bottom:1px solid #dfdfdf}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:first-child td{border-top:8px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody#order_line_items tr:first-child td{border-top:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb{text-align:left;width:38px;padding-bottom:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail{width:38px;height:38px;border:2px solid #e8e8e8;background:#f8f8f8;color:#ccc;position:relative;font-size:21px;display:block;text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;height:100%;text-align:center;content:"";width:38px;line-height:38px;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail img{width:100%;height:100%;margin:0;padding:0;position:relative}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-sku,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-variation{display:block;margin-top:.5em;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item{min-width:200px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .center,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .variation-id{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class{text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label{white-space:nowrap;color:#999;font-size:.833em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label input{display:inline}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class input{width:70px;vertical-align:middle;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class select{width:85px;height:26px;vertical-align:middle;font-size:1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input{display:inline-block;background:#fff;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);margin:1px 0;min-width:80px;overflow:hidden;line-height:1em;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input{width:100%;box-sizing:border-box}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input label{font-size:.75em;padding:4px 6px 0;color:#555;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input{width:100%;box-sizing:border-box;border:0;box-shadow:none;margin:0;padding:0 6px 4px;color:#555;background:0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input::-webkit-input-placeholder{color:#ddd}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child{border-bottom:1px dashed #ddd;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child label{color:#ccc}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .view{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .edit{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes label{display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount{display:block;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{margin-right:.25em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input{text-align:center;width:50px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items span.subtotal{opacity:.5}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.tax_class,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.tax_class{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .calculated{border-color:#ae8ca2;border-style:dotted}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{margin:.5em 0 0;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{color:#ccc;top:0;left:0;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-align:center;font-family:WooCommerce}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr th{border:0;padding:0 4px .5em 0;line-height:1.5em;width:20%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td{padding:0 4px .5em 0;border:0;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input{width:100%;margin:0;position:relative;border-bottom:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .refund_by,ul.order_notes li p.meta .exact-date{border-bottom:1px dotted #999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td textarea{width:100%;height:4em;margin:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input:focus+textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input:focus+textarea{border-top-color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p{margin:0 0 .5em;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p:last-child{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method_name{width:100%;margin:0 0 .5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;float:right;font-size:14px;visibility:hidden;margin:3px -18px 0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:hover:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:hover:before{color:#a00}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax:hover .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax:hover .delete-order-tax{visibility:visible}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded{display:block;color:#a00;white-space:nowrap;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;width:100%;height:100%;text-align:center;content:"";position:relative;top:auto;left:auto;margin:-1px 4px 0 0;vertical-align:middle;line-height:1em}#woocommerce-order-items .wc-order-edit-line-item{padding-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions{width:44px;text-align:right;padding-left:0;vertical-align:middle}#woocommerce-order-items .wc-order-edit-line-item-actions a{color:#ccc;display:inline-block;cursor:pointer;padding:0 0 .5em;margin:0 0 0 12px;vertical-align:middle;text-decoration:none;line-height:16px;width:16px;overflow:hidden}#woocommerce-order-items .wc-order-edit-line-item-actions a:before{margin:0;padding:0;font-size:16px;width:16px;height:16px}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before,#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{font-family:Dashicons;-webkit-font-smoothing:antialiased;text-indent:0;top:0;left:0;width:100%;height:100%;margin:0;text-align:center;position:relative;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1}#woocommerce-order-items .wc-order-edit-line-item-actions a:hover:before{color:#999}#woocommerce-order-items .wc-order-edit-line-item-actions a:first-child{margin-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:hover:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:hover:before{color:#a00}#woocommerce-order-items tbody tr .wc-order-edit-line-item-actions{visibility:hidden}#woocommerce-order-items tbody tr:hover .wc-order-edit-line-item-actions{visibility:visible}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions{width:1.5em;visibility:visible!important}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions a{padding:0}#woocommerce-order-downloads .buttons{float:left;padding:0;margin:0;vertical-align:top}#woocommerce-order-downloads .buttons .add_item_id,#woocommerce-order-downloads .buttons .select2-container{width:400px!important;margin-right:9px;vertical-align:top;float:left}#woocommerce-order-downloads .buttons button{margin:2px 0 0}#woocommerce-order-downloads h3 small{color:#999}#poststuff #woocommerce-order-actions .inside{margin:0;padding:0}#poststuff #woocommerce-order-actions .inside ul.order_actions li{padding:6px 10px;box-sizing:border-box}#poststuff #woocommerce-order-actions .inside ul.order_actions li:last-child{border-bottom:0}#poststuff #woocommerce-order-notes .inside{margin:0;padding:0}#poststuff #woocommerce-order-notes .inside ul.order_notes li{padding:0 10px}#woocommerce_customers p.search-box{margin:6px 0 4px;float:left}#woocommerce_customers .tablenav{float:right;clear:none}.widefat.customers td{vertical-align:middle;padding:4px 7px}.widefat .column-order_title{width:15%}.widefat .column-order_title time{display:block;color:#999;margin:3px 0}.widefat .column-orders,.widefat .column-paying,.widefat .column-spent{text-align:center;width:8%}.widefat .column-last_order{width:11%}.widefat .column-order_actions,.widefat .column-user_actions,.widefat .column-wc_actions{width:110px}.widefat .column-order_actions a.button,.widefat .column-user_actions a.button,.widefat .column-wc_actions a.button{float:left;margin:0 4px 2px 0;cursor:pointer;padding:3px 4px;height:auto}.widefat .column-order_actions a.button img,.widefat .column-user_actions a.button img,.widefat .column-wc_actions a.button img{display:block;width:12px;height:auto}.widefat small.meta{display:block;color:#999;font-size:inherit;margin:3px 0}.widefat .column-order_date,.widefat .column-order_total{width:9%}.widefat .column-order_status{width:45px;text-align:center}.widefat .column-order_status mark{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;background:0 0;font-size:1.4em;margin:0 auto}.widefat .column-order_status mark.cancelled:after,.widefat .column-order_status mark.completed:after,.widefat .column-order_status mark.failed:after,.widefat .column-order_status mark.on-hold:after,.widefat .column-order_status mark.pending:after,.widefat .column-order_status mark.processing:after,.widefat .column-order_status mark.refunded:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.column-customer_message .note-on:after,.column-order_notes .note-on:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;left:0;text-align:center;line-height:16px;font-family:WooCommerce}.widefat .column-order_status mark.pending:after{content:"\e012";color:#ffba00}.widefat .column-order_status mark.completed:after{content:"\e015";color:#2ea2cc}.widefat .column-order_status mark.on-hold:after{content:"\e033";color:#999}.widefat .column-order_status mark.failed:after{content:"\e016";color:#d0c21f}.widefat .column-order_status mark.cancelled:after{content:"\e013";color:#a00}.widefat .column-order_status mark.processing:after{content:"\e011";color:#73a724}.widefat .column-order_status mark.refunded:after{content:"\e014";color:#999}.widefat td.column-order_status{padding-top:9px}.column-customer_message .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-customer_message .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.column-order_notes .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-order_notes .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.order_actions .complete,.order_actions .processing,.order_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.order_actions .processing:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.order_actions .complete:after,.order_actions .view:after{font-family:Dashicons;text-indent:0;position:absolute;width:100%;height:100%;left:0;line-height:1.85;margin:0;text-align:center;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;font-weight:400}.order_actions .complete:after{content:""}.order_actions .view:after{content:""}.user_actions .edit,.user_actions .link,.user_actions .refresh,.user_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.user_actions .edit:after,.user_actions .link:after,.user_actions .refresh:after,.user_actions .view:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.user_actions .edit:after{font-family:Dashicons;content:"\f464"}.user_actions .link:after{content:"\e00d"}.user_actions .view:after{content:"\e010"}.user_actions .refresh:after{content:"\e031"}.attributes-table td,.attributes-table th{width:15%;vertical-align:top}.attributes-table .attribute-terms{width:32%}.attributes-table .attribute-actions{width:2em}.attributes-table .attribute-actions .configure-terms{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.attributes-table .attribute-actions .configure-terms:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}ul.order_notes{padding:2px 0 0}ul.order_notes li .note_content{padding:10px;background:#efefef;position:relative}ul.order_notes li .note_content p{margin:0;padding:0;word-wrap:break-word}ul.order_notes li p.meta{padding:10px;color:#999;margin:0;font-size:11px}ul.order_notes li a.delete_note{color:#a00}table.wp-list-table .row-actions,table.wp-list-table span.na{color:#999}ul.order_notes li .note_content:after{content:"";display:block;position:absolute;bottom:-10px;left:20px;width:0;height:0;border-width:10px 10px 0 0;border-style:solid;border-color:#efefef transparent}ul.order_notes li.customer-note .note_content{background:#A7CEDC}ul.order_notes li.customer-note .note_content:after{border-color:#A7CEDC transparent}ul.order_notes li.system-note .note_content{background:#d7cad2}ul.order_notes li.system-note .note_content:after{border-color:#d7cad2 transparent}.add_note{border-top:1px solid #ddd;padding:10px 10px 0}.add_note h4{margin-top:5px!important}.add_note #add_order_note{width:100%;height:50px}table.wp-list-table .column-thumb{width:52px;text-align:center;white-space:nowrap}table.wp-list-table .column-name{width:22%}table.wp-list-table .column-product_cat,table.wp-list-table .column-product_tag{width:11%!important}table.wp-list-table .column-featured,table.wp-list-table .column-product_type{width:48px;text-align:left!important}table.wp-list-table .column-customer_message,table.wp-list-table .column-order_notes{width:48px;text-align:center}table.wp-list-table .column-customer_message img,table.wp-list-table .column-order_notes img{margin:0 auto;padding-top:0!important}table.wp-list-table .manage-column.column-featured img,table.wp-list-table .manage-column.column-product_type img{padding-left:2px}table.wp-list-table .column-price .woocommerce-price-suffix{display:none}table.wp-list-table img{margin:1px 2px}table.wp-list-table td.column-thumb img{margin:0;width:auto;height:auto;max-width:40px;max-height:40px;vertical-align:middle}table.wp-list-table .column-is_in_stock{text-align:left!important}table.wp-list-table span.wc-featured,table.wp-list-table span.wc-image,table.wp-list-table span.wc-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table span.wc-featured:before,table.wp-list-table span.wc-image:before,table.wp-list-table span.wc-type:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:""}table.wp-list-table span.wc-featured{margin:0;cursor:pointer}table.wp-list-table span.wc-featured:before{content:"\f155"}table.wp-list-table span.wc-featured.not-featured:before{content:"\f154"}table.wp-list-table td.column-featured span.wc-featured{font-size:1.6em}table.wp-list-table span.wc-type{margin:0}table.wp-list-table span.wc-type:before{font-family:WooCommerce;content:"\e006"}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after,table.wp-list-table span.product-type:before{font-family:WooCommerce;text-align:center;line-height:1;top:0;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;left:0}table.wp-list-table span.product-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.6em}table.wp-list-table span.product-type:before{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}table.wp-list-table span.product-type.grouped:before{content:"\e002"}table.wp-list-table span.product-type.external:before{content:"\e034"}table.wp-list-table span.product-type.variable:before{content:"\e003"}table.wp-list-table span.product-type.downloadable:before{content:"\e001"}table.wp-list-table span.product-type.virtual:before{content:"\e000"}table.wp-list-table mark.instock{font-weight:700;color:#7ad03a;background:0 0;line-height:1}table.wp-list-table mark.outofstock{font-weight:700;color:#a44;background:0 0;line-height:1}table.wp-list-table .notes_head,table.wp-list-table .order-notes_head,table.wp-list-table .status_head{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%}table.wc_emails .wc-email-settings-table-name,table.wc_emails td.name,table.wc_gateways .wc-email-settings-table-name,table.wc_gateways td.name,table.wc_shipping .wc-email-settings-table-name,table.wc_shipping td.name{font-weight:700}table.wp-list-table .order-notes_head:after{content:"\e028"}table.wp-list-table .notes_head:after{content:"\e026"}table.wp-list-table .status_head:after{content:"\e011"}table.wp-list-table .column-order_items{width:12%}table.wp-list-table .column-order_items table.order_items{width:100%;margin:3px 0 0;padding:0;display:none}table.wp-list-table .column-order_items table.order_items td{border:0;margin:0;padding:0 0 3px}table.wp-list-table .column-order_items table.order_items td.qty{color:#999;padding-right:6px;text-align:left}mark.notice{background:#fff;color:#a00;margin:0 0 0 10px}a.export_rates,a.import_rates{float:right;margin-left:9px;margin-top:-2px;margin-bottom:0}#rates-search{float:right}#rates-search input.wc-tax-rates-search-field{padding:4px 8px;font-size:1.2em}#rates-pagination{float:right;margin-right:.5em}#rates-pagination .tablenav{margin:0}table.wc_input_table,table.wc_tax_rates{width:100%}table.wc_input_table span.tips,table.wc_tax_rates span.tips{color:#2ea2cc}table.wc_input_table th,table.wc_tax_rates th{white-space:nowrap}table.wc_input_table td,table.wc_tax_rates td{padding:0;border-right:1px solid #DFDFDF;border-bottom:1px solid #DFDFDF;border-top:0;background:#fff;cursor:default}table.wc_input_table td input[type=text],table.wc_input_table td input[type=number],table.wc_tax_rates td input[type=text],table.wc_tax_rates td input[type=number]{width:100%;padding:5px 10px;margin:0;border:0;outline:0;background:0 0}table.wc_input_table td input[type=text]:focus,table.wc_input_table td input[type=number]:focus,table.wc_tax_rates td input[type=text]:focus,table.wc_tax_rates td input[type=number]:focus{outline:0;box-shadow:none}table.wc_input_table td.apply_to_shipping,table.wc_input_table td.compound,table.wc_tax_rates td.apply_to_shipping,table.wc_tax_rates td.compound{padding:5px 7px;vertical-align:middle}table.wc_input_table td.apply_to_shipping input,table.wc_input_table td.compound input,table.wc_tax_rates td.apply_to_shipping input,table.wc_tax_rates td.compound input{width:auto;padding:0}table.wc_input_table td:last-child,table.wc_tax_rates td:last-child{border-right:0}table.wc_input_table tr.current td,table.wc_tax_rates tr.current td{background-color:#fefbcc}table.wc_input_table .cost,table.wc_input_table .cost input,table.wc_input_table .item_cost,table.wc_input_table .item_cost input,table.wc_tax_rates .cost,table.wc_tax_rates .cost input,table.wc_tax_rates .item_cost,table.wc_tax_rates .item_cost input{text-align:right}table.wc_input_table th.sort,table.wc_tax_rates th.sort{width:17px;padding:0 4px}table.wc_input_table td.sort,table.wc_tax_rates td.sort{padding:0 4px}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort{cursor:move;font-size:15px;background:#f9f9f9;text-align:center;vertical-align:middle}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before{color:#333}table.wc_input_table .button,table.wc_tax_rates .button{float:left;margin-right:5px}table.wc_input_table .export,table.wc_input_table .import,table.wc_tax_rates .export,table.wc_tax_rates .import{float:right;margin-right:0;margin-left:5px}table.wc_input_table span.tips,table.wc_tax_rates span.tips{padding:0 3px}table.wc_input_table .pagination,table.wc_tax_rates .pagination{float:right}table.wc_input_table .pagination .button,table.wc_tax_rates .pagination .button{margin-left:5px;margin-right:0}table.wc_input_table .pagination .current,table.wc_tax_rates .pagination .current{background:#bbb;text-shadow:none}table.wc_input_table tr:last-child td,table.wc_tax_rates tr:last-child td{border-bottom:0}table.wc_emails,table.wc_gateways,table.wc_shipping{position:relative}table.wc_emails td,table.wc_gateways td,table.wc_shipping td{vertical-align:middle;padding:7px;line-height:2em}table.wc_emails tr:nth-child(odd) td,table.wc_gateways tr:nth-child(odd) td,table.wc_shipping tr:nth-child(odd) td{background:#f9f9f9}table.wc_emails th,table.wc_gateways th,table.wc_shipping th{padding:9px 7px!important;vertical-align:middle}table.wc_emails .settings,table.wc_gateways .settings,table.wc_shipping .settings{text-align:right}table.wc_emails .default,table.wc_emails .radio,table.wc_emails .status,table.wc_gateways .default,table.wc_gateways .radio,table.wc_gateways .status,table.wc_shipping .default,table.wc_shipping .radio,table.wc_shipping .status{text-align:center}table.wc_emails .default .tips,table.wc_emails .radio .tips,table.wc_emails .status .tips,table.wc_gateways .default .tips,table.wc_gateways .radio .tips,table.wc_gateways .status .tips,table.wc_shipping .default .tips,table.wc_shipping .radio .tips,table.wc_shipping .status .tips{margin:0 auto}table.wc_emails .default input,table.wc_emails .radio input,table.wc_emails .status input,table.wc_gateways .default input,table.wc_gateways .radio input,table.wc_gateways .status input,table.wc_shipping .default input,table.wc_shipping .radio input,table.wc_shipping .status input{margin:0}table.wc_emails th.sort,table.wc_gateways th.sort,table.wc_shipping th.sort{width:28px;padding:0}table.wc_emails td.sort,table.wc_gateways td.sort,table.wc_shipping td.sort{padding:0 7px;cursor:move;font-size:15px;text-align:center;vertical-align:middle}table.wc_emails td.sort:before,table.wc_gateways td.sort:before,table.wc_shipping td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_emails .wc-email-settings-table-name span,table.wc_gateways .wc-email-settings-table-name span,table.wc_shipping .wc-email-settings-table-name span{font-weight:400;color:#999;margin:0 0 0 4px!important}table.wc_emails .wc-email-settings-table-status,table.wc_gateways .wc-email-settings-table-status,table.wc_shipping .wc-email-settings-table-status{text-align:center;width:1em}table.wc_emails .wc-email-settings-table-status .tips,table.wc_gateways .wc-email-settings-table-status .tips,table.wc_shipping .wc-email-settings-table-status .tips{margin:0 auto}table.wc_emails .wc-email-settings-table-actions a,table.wc_gateways .wc-email-settings-table-actions a,table.wc_shipping .wc-email-settings-table-actions a{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}table.wc_emails .wc-email-settings-table-actions a:after,table.wc_gateways .wc-email-settings-table-actions a:after,table.wc_shipping .wc-email-settings-table-actions a:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}table.wc-shipping-classes td,table.wc-shipping-classes th,table.wc-shipping-zone-methods td,table.wc-shipping-zone-methods th,table.wc-shipping-zones td,table.wc-shipping-zones th{vertical-align:top;line-height:24px;padding:1em;font-size:14px;background:#fff}table.wc-shipping-classes td li,table.wc-shipping-classes th li,table.wc-shipping-zone-methods td li,table.wc-shipping-zone-methods th li,table.wc-shipping-zones td li,table.wc-shipping-zones th li{line-height:24px;font-size:14px}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state,table.wc-shipping-classes td.wc-shipping-zones-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state,table.wc-shipping-zones td.wc-shipping-zones-blank-state{background:#F7F1F6!important;overflow:hidden;position:relative;padding:7.5em 7.5%;border-bottom:2px solid #EEE2EC}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zones td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state p{color:#a46497;font-size:1.5em;line-height:1.5em;margin:0 0 1em;position:relative;z-index:1;text-shadow:1px 1px 1px #fff}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state p.main{font-size:2em}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state li{margin-left:1em;list-style:circle inside}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-classes td.wc-shipping-zones-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state:before,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zones td.wc-shipping-zones-blank-state:before{content:"\e01b";font-family:WooCommerce;text-align:center;line-height:1;color:#EEE2EC;display:block;width:1em;font-size:40em;top:50%;right:-3.75%;margin-top:-.1875em;position:absolute}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-classes td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zones-blank-state .button-primary{background-color:#804877;border-color:#804877;-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);margin:0;opacity:1;text-shadow:0 -1px 1px #8a4f7f,1px 0 1px #8a4f7f,0 1px 1px #8a4f7f,-1px 0 1px #8a4f7f;font-size:1.5em;padding:.75em 1em;height:auto;position:relative;z-index:1}table.wc-shipping-classes .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-classes .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-classes tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-classes tr.odd td,table.wc-shipping-zone-methods .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tr.odd td,table.wc-shipping-zones .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zones .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zones tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zones tr.odd td{background:#f9f9f9}table.wc-shipping-classes p,table.wc-shipping-classes ul,table.wc-shipping-zone-methods p,table.wc-shipping-zone-methods ul,table.wc-shipping-zones p,table.wc-shipping-zones ul{margin:0}table.wc-shipping-classes td.wc-shipping-zone-method-sort,table.wc-shipping-classes td.wc-shipping-zone-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-sort,table.wc-shipping-zones td.wc-shipping-zone-method-sort,table.wc-shipping-zones td.wc-shipping-zone-sort{cursor:move;font-size:15px;text-align:center}table.wc-shipping-classes td.wc-shipping-zone-method-sort:before,table.wc-shipping-classes td.wc-shipping-zone-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:before,table.wc-shipping-zones td.wc-shipping-zone-sort:before{content:"\f333";font-family:Dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-classes td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-sort:hover:before{color:#333}table.wc-shipping-classes td.wc-shipping-zone-worldwide,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide,table.wc-shipping-zones td.wc-shipping-zone-worldwide{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-worldwide:before,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide:before,table.wc-shipping-zones td.wc-shipping-zone-worldwide:before{content:"\f319";font-family:dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes .wc-shipping-zone-methods,table.wc-shipping-classes .wc-shipping-zone-name,table.wc-shipping-zone-methods .wc-shipping-zone-methods,table.wc-shipping-zone-methods .wc-shipping-zone-name,table.wc-shipping-zones .wc-shipping-zone-methods,table.wc-shipping-zones .wc-shipping-zone-name{width:25%}table.wc-shipping-classes .wc-shipping-class-description input,table.wc-shipping-classes .wc-shipping-class-description select,table.wc-shipping-classes .wc-shipping-class-description textarea,table.wc-shipping-classes .wc-shipping-class-name input,table.wc-shipping-classes .wc-shipping-class-name select,table.wc-shipping-classes .wc-shipping-class-name textarea,table.wc-shipping-classes .wc-shipping-class-slug input,table.wc-shipping-classes .wc-shipping-class-slug select,table.wc-shipping-classes .wc-shipping-class-slug textarea,table.wc-shipping-classes .wc-shipping-zone-name input,table.wc-shipping-classes .wc-shipping-zone-name select,table.wc-shipping-classes .wc-shipping-zone-name textarea,table.wc-shipping-classes .wc-shipping-zone-region input,table.wc-shipping-classes .wc-shipping-zone-region select,table.wc-shipping-classes .wc-shipping-zone-region textarea,table.wc-shipping-zone-methods .wc-shipping-class-description input,table.wc-shipping-zone-methods .wc-shipping-class-description select,table.wc-shipping-zone-methods .wc-shipping-class-description textarea,table.wc-shipping-zone-methods .wc-shipping-class-name input,table.wc-shipping-zone-methods .wc-shipping-class-name select,table.wc-shipping-zone-methods .wc-shipping-class-name textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug input,table.wc-shipping-zone-methods .wc-shipping-class-slug select,table.wc-shipping-zone-methods .wc-shipping-class-slug textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name input,table.wc-shipping-zone-methods .wc-shipping-zone-name select,table.wc-shipping-zone-methods .wc-shipping-zone-name textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region input,table.wc-shipping-zone-methods .wc-shipping-zone-region select,table.wc-shipping-zone-methods .wc-shipping-zone-region textarea,table.wc-shipping-zones .wc-shipping-class-description input,table.wc-shipping-zones .wc-shipping-class-description select,table.wc-shipping-zones .wc-shipping-class-description textarea,table.wc-shipping-zones .wc-shipping-class-name input,table.wc-shipping-zones .wc-shipping-class-name select,table.wc-shipping-zones .wc-shipping-class-name textarea,table.wc-shipping-zones .wc-shipping-class-slug input,table.wc-shipping-zones .wc-shipping-class-slug select,table.wc-shipping-zones .wc-shipping-class-slug textarea,table.wc-shipping-zones .wc-shipping-zone-name input,table.wc-shipping-zones .wc-shipping-zone-name select,table.wc-shipping-zones .wc-shipping-zone-name textarea,table.wc-shipping-zones .wc-shipping-zone-region input,table.wc-shipping-zones .wc-shipping-zone-region select,table.wc-shipping-zones .wc-shipping-zone-region textarea{width:100%}table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-zone-delete{color:red}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle{float:right;margin:0;font-size:.9em;text-decoration:underline}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes{display:none}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea{margin-top:1em}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes .description{font-size:.9em;color:#999}table.wc-shipping-classes .wc-shipping-class-count,table.wc-shipping-zone-methods .wc-shipping-class-count,table.wc-shipping-zones .wc-shipping-class-count{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-methods,table.wc-shipping-zone-methods td.wc-shipping-zone-methods,table.wc-shipping-zones td.wc-shipping-zone-methods{color:#999}table.wc-shipping-classes td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .method_disabled{text-decoration:line-through}table.wc-shipping-classes td.wc-shipping-zone-methods ul,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul,table.wc-shipping-zones td.wc-shipping-zone-methods ul{color:#999;position:relative;padding-right:32px}table.wc-shipping-classes td.wc-shipping-zone-methods ul li,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li,table.wc-shipping-zones td.wc-shipping-zone-methods ul li{display:inline;margin:0}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:before{content:", "}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-classes td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:nth-child(2):before{content:""}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child{display:block}table.wc-shipping-classes td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zones td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row{position:absolute;right:0;top:0}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method{display:block;width:24px;padding:24px 0 0;height:0;overflow:hidden;cursor:pointer}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method:before{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;font-family:Dashicons;content:"\f502";color:#999;vertical-align:middle;line-height:24px;font-size:16px;margin:0}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled:before{line-height:inherit}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled{margin-top:1px;display:inline-block}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled{cursor:not-allowed}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled:before{color:#ccc}table.wc-shipping-classes .wc-shipping-zone-method-title,table.wc-shipping-zone-methods .wc-shipping-zone-method-title,table.wc-shipping-zones .wc-shipping-zone-method-title{width:33%}table.wc-shipping-classes .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zone-methods .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zones .wc-shipping-zone-method-title .wc-shipping-zone-method-delete{color:red}table.wc-shipping-classes .wc-shipping-zone-method-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled{text-align:center}table.wc-shipping-classes tfoot input,table.wc-shipping-classes tfoot select,table.wc-shipping-zone-methods tfoot input,table.wc-shipping-zone-methods tfoot select,table.wc-shipping-zones tfoot input,table.wc-shipping-zones tfoot select{vertical-align:middle!important}table.wc-shipping-classes tfoot .button-secondary,table.wc-shipping-zone-methods tfoot .button-secondary,table.wc-shipping-zones tfoot .button-secondary{float:right}table.wc-shipping-classes .editing .wc-shipping-zone-edit,table.wc-shipping-classes .editing .wc-shipping-zone-view,table.wc-shipping-zone-methods .editing .wc-shipping-zone-edit,table.wc-shipping-zone-methods .editing .wc-shipping-zone-view,table.wc-shipping-zones .editing .wc-shipping-zone-edit,table.wc-shipping-zones .editing .wc-shipping-zone-view{display:none}.wc-modal-shipping-method-settings{background:#f8f8f8;padding:1em!important}.wc-modal-shipping-method-settings form .form-table{width:100%;background:#fff;margin:0 0 1.5em}.wc-modal-shipping-method-settings form .form-table tr th{width:30%;position:relative}.wc-modal-shipping-method-settings form .form-table tr th .woocommerce-help-tip{float:right;margin:-8px -.5em 0 0;vertical-align:middle;right:0;top:50%;position:absolute}.wc-modal-shipping-method-settings form .form-table tr td input,.wc-modal-shipping-method-settings form .form-table tr td select,.wc-modal-shipping-method-settings form .form-table tr td textarea{width:50%;min-width:250px}.wc-modal-shipping-method-settings form .form-table tr td input[type=checkbox]{width:auto;min-width:16px}.wc-modal-shipping-method-settings form .form-table tr td,.wc-modal-shipping-method-settings form .form-table tr th{vertical-align:middle;margin:0;line-height:24px;padding:1em;border-bottom:1px solid #f8f8f8}.wc-modal-shipping-method-settings form .form-table:last-of-type{margin-bottom:0}.wc-backbone-modal .wc-shipping-zone-method-selector p{margin-top:0}.wc-backbone-modal .wc-shipping-zone-method-selector .wc-shipping-zone-method-description{margin:.75em 1px 0;line-height:1.5em;color:#999;font-style:italic}.wc-backbone-modal .wc-shipping-zone-method-selector select{width:100%;cursor:pointer}img.help_tip{margin:0 0 0 9px;vertical-align:middle}.postbox img.help_tip{margin-top:0}.postbox .woocommerce-help-tip{margin:0 0 0 9px}.status-disabled,.status-enabled,.status-manual{font-size:1.4em;display:block;text-indent:-9999px;position:relative;height:1em;width:1em}.status-disabled:before,.status-enabled:before,.status-manual:before{font-family:WooCommerce;line-height:1;margin:0;position:absolute;width:100%;height:100%;text-indent:0;top:0;font-variant:normal;-webkit-font-smoothing:antialiased;font-weight:400;text-align:center;left:0;speak:none;text-transform:none}.status-manual:before{content:"";color:#999}.status-enabled:before{content:"";color:#a46497}.status-disabled:before{content:"";color:#ccc}.woocommerce h2.woo-nav-tab-wrapper{margin-bottom:1em}.woocommerce nav.woo-nav-tab-wrapper{margin:1.5em 0 1em;border-bottom:1px solid #ccc}.woocommerce .subsubsub{margin:-8px 0 0}.woocommerce .wc-admin-breadcrumb{margin-left:.5em}.woocommerce .wc-admin-breadcrumb a{color:#a46497}.woocommerce #template div{margin:0}.woocommerce #template div p .button{float:right;margin-left:10px;margin-top:-4px}.woocommerce #template div .editor textarea{margin-bottom:8px}.woocommerce textarea[disabled=disabled]{background:#DFDFDF!important}.woocommerce table.form-table{margin:0;position:relative}.woocommerce table.form-table .forminp-radio ul{margin:0}.woocommerce table.form-table .forminp-radio ul li{line-height:1.4em}.woocommerce table.form-table textarea.input-text{height:100%;min-width:150px;display:block}.woocommerce table.form-table input.regular-input{width:25em}.woocommerce table.form-table textarea.wide-input{width:100%}.woocommerce table.form-table .woocommerce-help-tip,.woocommerce table.form-table img.help_tip{padding:0;margin:-4px 0 0 5px;vertical-align:middle;cursor:help;line-height:1}.woocommerce table.form-table span.help_tip{cursor:help;color:#2ea2cc}.woocommerce table.form-table th{position:relative;padding-right:24px}.woocommerce table.form-table .select2-container{display:block;max-width:350px;vertical-align:top;margin-bottom:3px}.woocommerce table.form-table table.widefat th{padding-right:inherit}.woocommerce table.form-table th .woocommerce-help-tip,.woocommerce table.form-table th img.help_tip{margin:0 -24px 0 0;float:right}.woocommerce table.form-table .wp-list-table .woocommerce-help-tip{float:none}.woocommerce table.form-table fieldset{margin-top:4px}.woocommerce table.form-table fieldset .woocommerce-help-tip,.woocommerce table.form-table fieldset img.help_tip{margin:-3px 0 0 5px}.woocommerce table.form-table fieldset p.description{margin-bottom:8px}.woocommerce table.form-table fieldset:first-child{margin-top:0}.woocommerce table.form-table .iris-picker{z-index:100;display:none;position:absolute;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,.2)}.woocommerce table.form-table .iris-picker .ui-slider{border:0!important;margin:0!important;width:auto!important;height:auto!important;background:none!important}.woocommerce table.form-table .iris-picker .ui-slider .ui-slider-handle{margin-bottom:0!important}.woocommerce table.form-table .colorpickpreview{padding:3px 3px 3px 20px;border:1px solid #ddd;border-right:0}.woocommerce table.form-table .colorpick{border-left:0}.woocommerce table.form-table .image_width_settings{vertical-align:middle}.woocommerce table.form-table .image_width_settings label{margin-left:10px}.woocommerce table.form-table .wc_emails_wrapper{padding:0 15px 10px 0}.woocommerce #tabs-wrap table a.remove{margin-left:4px}.woocommerce #tabs-wrap table p{margin:0 0 4px!important;overflow:hidden;zoom:1}.woocommerce #tabs-wrap table p a.add{float:left}#wp-excerpt-editor-container{background:#fff}#product_variation-parent #parent_id{width:100%}#postimagediv img{border:1px solid #d5d5d5;max-width:100%}#woocommerce-product-images .inside{margin:0;padding:0}#woocommerce-product-images .inside .add_product_images{padding:0 12px 12px}#woocommerce-product-images .inside #product_images_container{padding:0 0 0 9px}#woocommerce-product-images .inside #product_images_container ul{margin:0;padding:0}#woocommerce-product-images .inside #product_images_container ul:after,#woocommerce-product-images .inside #product_images_container ul:before{content:" ";display:table}#woocommerce-product-images .inside #product_images_container ul:after{clear:both}#woocommerce-product-images .inside #product_images_container ul li.add,#woocommerce-product-images .inside #product_images_container ul li.image,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{width:80px;float:left;cursor:move;border:1px solid #d5d5d5;margin:9px 9px 0 0;background:#f7f7f7;border-radius:2px;position:relative;box-sizing:border-box}#woocommerce-product-images .inside #product_images_container ul li.add img,#woocommerce-product-images .inside #product_images_container ul li.image img,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder img{width:100%;height:auto;display:block}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{border:3px dashed #ddd;position:relative}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-size:2.618em;line-height:72px;color:#ddd}#woocommerce-product-images .inside #product_images_container ul ul.actions{position:absolute;top:-8px;right:-8px;padding:2px;display:none}#woocommerce-product-images .inside #product_images_container ul ul.actions li{float:right;margin:0 0 0 2px}#woocommerce-product-images .inside #product_images_container ul ul.actions li a{width:1em;margin:0;height:0;display:block;overflow:hidden}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.tips{cursor:pointer}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.4em}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:hover:before{color:#a00}#woocommerce-product-images .inside #product_images_container ul li:hover ul.actions{display:block}#woocommerce-product-data .hndle{padding:10px}#woocommerce-product-data .hndle span{display:block;vertical-align:middle;line-height:24px}#woocommerce-product-data .hndle span span{display:inline;line-height:inherit;vertical-align:baseline}#woocommerce-product-data .hndle label{padding-right:1em;font-size:12px;vertical-align:baseline}#woocommerce-product-data .hndle label:first-child{margin-right:1em;border-right:1px solid #dfdfdf}#woocommerce-product-data .hndle input,#woocommerce-product-data .hndle select{margin:-3px 0 0 .5em;vertical-align:middle}#woocommerce-product-data>.handlediv{margin-top:4px}#woocommerce-product-data .wrap{margin:0}#woocommerce-coupon-description{padding:3px 8px;font-size:1.7em;line-height:1.42em;height:auto;width:100%;outline:0;margin:10px 0;display:block}#woocommerce-coupon-description::-webkit-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description::-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-ms-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap{background:#fff}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{float:left;width:80%}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-product-data .woocommerce_options_panel .wc-radios{display:block;float:left;margin:0}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-product-data .woocommerce_options_panel .wc-radios li{display:block;padding:0 0 10px}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li input,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-product-data .woocommerce_options_panel .wc-radios li input{width:auto}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap,.woocommerce .panel-wrap{overflow:hidden}#woocommerce-coupon-data ul.wc-tabs,#woocommerce-product-data ul.wc-tabs,.woocommerce ul.wc-tabs{margin:0;width:20%;float:left;line-height:1em;padding:0 0 10px;position:relative;background-color:#fafafa;border-right:1px solid #eee;box-sizing:border-box}#woocommerce-coupon-data ul.wc-tabs:after,#woocommerce-product-data ul.wc-tabs:after,.woocommerce ul.wc-tabs:after{content:"";display:block;width:100%;height:9999em;position:absolute;bottom:-9999em;left:0;background-color:#fafafa;border-right:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li,#woocommerce-product-data ul.wc-tabs li,.woocommerce ul.wc-tabs li{margin:0;padding:0;display:block;position:relative}#woocommerce-coupon-data ul.wc-tabs li a,#woocommerce-product-data ul.wc-tabs li a,.woocommerce ul.wc-tabs li a{margin:0;padding:10px;display:block;box-shadow:none;text-decoration:none;line-height:20px!important;border-bottom:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li a:before,#woocommerce-product-data ul.wc-tabs li a:before,.woocommerce ul.wc-tabs li a:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}#woocommerce-coupon-data ul.wc-tabs li.general_options a:before,#woocommerce-product-data ul.wc-tabs li.general_options a:before,.woocommerce ul.wc-tabs li.general_options a:before{content:"\f107"}#woocommerce-coupon-data ul.wc-tabs li.inventory_options a:before,#woocommerce-product-data ul.wc-tabs li.inventory_options a:before,.woocommerce ul.wc-tabs li.inventory_options a:before{content:"\f481"}#woocommerce-coupon-data ul.wc-tabs li.shipping_options a:before,#woocommerce-product-data ul.wc-tabs li.shipping_options a:before,.woocommerce ul.wc-tabs li.shipping_options a:before{font-family:WooCommerce;content:"\e01a"}#woocommerce-coupon-data ul.wc-tabs li.linked_product_options a:before,#woocommerce-product-data ul.wc-tabs li.linked_product_options a:before,.woocommerce ul.wc-tabs li.linked_product_options a:before{content:"\f103"}#woocommerce-coupon-data ul.wc-tabs li.attribute_options a:before,#woocommerce-product-data ul.wc-tabs li.attribute_options a:before,.woocommerce ul.wc-tabs li.attribute_options a:before{content:"\f175"}#woocommerce-coupon-data ul.wc-tabs li.advanced_options a:before,#woocommerce-product-data ul.wc-tabs li.advanced_options a:before,.woocommerce ul.wc-tabs li.advanced_options a:before{font-family:Dashicons;content:"\f111"}#woocommerce-coupon-data ul.wc-tabs li.variations_options a:before,#woocommerce-product-data ul.wc-tabs li.variations_options a:before,.woocommerce ul.wc-tabs li.variations_options a:before{content:"\f509"}#woocommerce-coupon-data ul.wc-tabs li.usage_restriction_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_restriction_options a:before,.woocommerce ul.wc-tabs li.usage_restriction_options a:before{font-family:WooCommerce;content:"\e602"}#woocommerce-coupon-data ul.wc-tabs li.usage_limit_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_limit_options a:before,.woocommerce ul.wc-tabs li.usage_limit_options a:before{font-family:WooCommerce;content:"\e601"}#woocommerce-coupon-data ul.wc-tabs li.general_coupon_data a:before,#woocommerce-product-data ul.wc-tabs li.general_coupon_data a:before,.woocommerce ul.wc-tabs li.general_coupon_data a:before{font-family:WooCommerce;content:"\e600"}#woocommerce-coupon-data ul.wc-tabs li.active a,#woocommerce-product-data ul.wc-tabs li.active a,.woocommerce ul.wc-tabs li.active a{color:#555;position:relative;background-color:#eee}.woocommerce_page_wc-settings .shippingrows th.check-column{padding-top:20px}.woocommerce_page_wc-settings .shippingrows tfoot th{padding-left:10px}.woocommerce_page_wc-settings .shippingrows .add.button:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}.woocommerce_page_wc-settings h3.wc-settings-sub-title{font-size:1.2em}#woocommerce-coupon-data .inside,#woocommerce-order-data .inside,#woocommerce-order-downloads .inside,#woocommerce-product-data .inside,#woocommerce-product-type-options .inside{margin:0;padding:0}.panel,.woocommerce_options_panel{padding:9px;color:#555}.panel .form-field .woocommerce-help-tip,.woocommerce_options_panel .form-field .woocommerce-help-tip{font-size:1.4em}.panel,.woocommerce_page_settings .woocommerce_options_panel{padding:0}#woocommerce-product-specs .inside,#woocommerce-product-type-options .panel{margin:0;padding:9px}#woocommerce-product-type-options .panel p,.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p{margin:0 0 9px;font-size:12px;padding:5px 9px;line-height:24px}#woocommerce-product-type-options .panel p:after,.woocommerce_options_panel fieldset.form-field:after,.woocommerce_options_panel p:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce_options_panel .checkbox,.woocommerce_variable_attributes .checkbox{width:auto;margin:3px 0;vertical-align:middle}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{width:100%;padding:0!important}.woocommerce_options_panel .downloadable_files table th,.woocommerce_variations .downloadable_files table th{padding:7px 0 7px 7px!important}.woocommerce_options_panel .downloadable_files table th.sort,.woocommerce_variations .downloadable_files table th.sort{width:17px;padding:7px!important}.woocommerce_options_panel .downloadable_files table th .woocommerce-help-tip,.woocommerce_variations .downloadable_files table th .woocommerce-help-tip{font-size:1.1em;margin-left:0}.woocommerce_options_panel .downloadable_files table td,.woocommerce_variations .downloadable_files table td{vertical-align:middle!important;padding:4px 0 4px 7px!important;position:relative}.woocommerce_options_panel .downloadable_files table td:last-child,.woocommerce_variations .downloadable_files table td:last-child{padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td input.input_text,.woocommerce_variations .downloadable_files table td input.input_text{width:100%;float:none;min-width:0;margin:1px 0}.woocommerce_options_panel .downloadable_files table td .upload_file_button,.woocommerce_variations .downloadable_files table td .upload_file_button{width:auto;float:right;cursor:pointer}.woocommerce_options_panel .downloadable_files table td .delete,.woocommerce_variations .downloadable_files table td .delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.2em}.woocommerce_options_panel .downloadable_files table td .delete:before,.woocommerce_variations .downloadable_files table td .delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}.woocommerce_options_panel .downloadable_files table td .delete:hover:before,.woocommerce_variations .downloadable_files table td .delete:hover:before{color:#a00}.woocommerce_options_panel .downloadable_files table td.sort,.woocommerce_variations .downloadable_files table td.sort{width:17px;cursor:move;font-size:15px;text-align:center;background:#f9f9f9;padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td.sort:before,.woocommerce_variations .downloadable_files table td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_options_panel .downloadable_files table td.sort:hover:before,.woocommerce_variations .downloadable_files table td.sort:hover:before{color:#333}.woocommerce_variation h3 .sort{width:17px;height:26px;cursor:move;float:right;font-size:15px;font-weight:400;margin-right:.5em;visibility:hidden;text-align:center;vertical-align:middle}.woocommerce_variation h3 .sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:28px;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_variation h3 .sort:hover:before{color:#777}.woocommerce_variation h3:hover .sort,.woocommerce_variation.ui-sortable-helper .sort{visibility:visible}.woocommerce_options_panel{min-height:175px;box-sizing:border-box}.woocommerce_options_panel .downloadable_files{padding:0 9px 0 162px;position:relative;margin:9px 0}.woocommerce_options_panel .downloadable_files label{position:absolute;left:0;margin:0 0 0 12px;line-height:24px}.woocommerce_options_panel p{margin:9px 0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px 5px 162px!important}.woocommerce_options_panel .sale_price_dates_fields .short:first-of-type{margin-bottom:1em}.woocommerce_options_panel .sale_price_dates_fields .short:nth-of-type(2){clear:left}.woocommerce_options_panel label,.woocommerce_options_panel legend{float:left;width:150px;padding:0;margin:0 0 0 -150px}.woocommerce_options_panel label .req,.woocommerce_options_panel legend .req{font-weight:700;font-style:normal;color:#a00}.woocommerce_options_panel .description{padding:0;margin:0 0 0 7px;clear:none;display:inline}.woocommerce_options_panel .description-block{margin-left:0;display:block}.woocommerce_options_panel input,.woocommerce_options_panel select,.woocommerce_options_panel textarea{margin:0}.woocommerce_options_panel textarea{height:3.5em;line-height:1.5em;vertical-align:top}.woocommerce_options_panel input[type=text],.woocommerce_options_panel input[type=number],.woocommerce_options_panel input[type=email],.woocommerce_options_panel input[type=password]{width:50%;float:left}.woocommerce_options_panel input.button{width:auto;margin-left:8px}.woocommerce_options_panel select{float:left}.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:50%}.woocommerce_options_panel .sized{width:auto!important;margin-right:6px}.woocommerce_options_panel .options_group{border-top:1px solid #fff;border-bottom:1px solid #eee}.woocommerce_options_panel .options_group:first-child{border-top:0}.woocommerce_options_panel .options_group:last-child{border-bottom:0}.woocommerce_options_panel .options_group fieldset{margin:9px 0;font-size:12px;padding:5px 9px;line-height:24px}.woocommerce_options_panel .options_group fieldset label{width:auto;float:none}.woocommerce_options_panel .options_group fieldset ul{float:left;width:50%;margin:0;padding:0}.woocommerce_options_panel .options_group fieldset ul li{margin:0;width:auto}.woocommerce_options_panel .options_group fieldset ul li input{width:auto;float:none;margin-right:4px}.woocommerce_options_panel .options_group fieldset ul.wc-radios label{margin-left:0}.woocommerce_options_panel .dimensions_field .wrap{display:block;width:50%}.woocommerce_options_panel .dimensions_field .wrap input{width:30.75%;margin-right:3.8%}.woocommerce_options_panel .dimensions_field .wrap .last{margin-right:0}.woocommerce_options_panel.padded{padding:1em}#woocommerce-product-data input.dp-applied,.woocommerce_options_panel .select2-container{float:left}#grouped_product_options,#simple_product_options,#virtual_product_options{padding:12px;font-style:italic;color:#666}.wc-metaboxes-wrapper .toolbar{margin:0!important;border-top:1px solid #fff;border-bottom:1px solid #eee;padding:9px 12px!important}.wc-metaboxes-wrapper .toolbar:first-child{border-top:0}.wc-metaboxes-wrapper .toolbar:last-child{border-bottom:0}.wc-metaboxes-wrapper .toolbar .add_variation{float:right;margin-left:5px}.wc-metaboxes-wrapper .toolbar .cancel-variation-changes,.wc-metaboxes-wrapper .toolbar .save-variation-changes{float:left;margin-right:5px}.wc-metaboxes-wrapper p.toolbar{overflow:hidden;zoom:1}.wc-metaboxes-wrapper .expand-close{margin-right:2px;color:#777;font-size:12px;font-style:italic}.wc-metaboxes-wrapper .expand-close a{background:0 0;padding:0;font-size:12px;text-decoration:none}.wc-metaboxes-wrapper#product_attributes .expand-close{float:right;line-height:28px}.wc-metaboxes-wrapper .fr,.wc-metaboxes-wrapper button.add_variable_attribute{float:right;margin:0 0 0 6px}.wc-metaboxes-wrapper .wc-metaboxes{border-bottom:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox-sortable-placeholder{border-color:#bbb;background-color:#f5f5f5;margin-bottom:9px;border-width:1px;border-style:dashed}.wc-metaboxes-wrapper .wc-metabox{background:#fff;border-bottom:1px solid #eee;margin:0!important}.wc-metaboxes-wrapper .wc-metabox select{font-weight:400}.wc-metaboxes-wrapper .wc-metabox:last-of-type{border-bottom:0}.wc-metaboxes-wrapper .wc-metabox .handlediv{width:27px}.wc-metaboxes-wrapper .wc-metabox .handlediv:before{content:"\f142"!important;cursor:pointer;display:inline-block;font:400 20px/1 Dashicons;line-height:.5!important;padding:8px 10px;position:relative;right:12px;top:0}.wc-metaboxes-wrapper .wc-metabox.closed{border-radius:3px}.wc-metaboxes-wrapper .wc-metabox.closed .handlediv:before{content:"\f140"!important}.wc-metaboxes-wrapper .wc-metabox.closed h3{border:0}.wc-metaboxes-wrapper .wc-metabox h3{margin:0!important;padding:.75em .75em .75em 1em!important;font-size:1em!important;overflow:hidden;zoom:1;cursor:move}.wc-metaboxes-wrapper .wc-metabox h3 a.delete,.wc-metaboxes-wrapper .wc-metabox h3 button{float:right}.wc-metaboxes-wrapper .wc-metabox h3 a.delete{color:red;font-weight:400;line-height:26px;text-decoration:none;position:relative;visibility:hidden}.wc-metaboxes-wrapper .wc-metabox h3 strong{line-height:26px;font-weight:700}.wc-metaboxes-wrapper .wc-metabox h3 select{font-family:sans-serif;max-width:20%;margin:.25em .25em .25em 0}.wc-metaboxes-wrapper .wc-metabox h3 .handlediv{background-position:6px 5px!important;visibility:hidden;height:26px}.wc-metaboxes-wrapper .wc-metabox h3.fixed{cursor:pointer!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3{cursor:pointer;padding:.5em .75em .5em 1em!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .handlediv,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .sort,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 a.delete{margin-top:.25em}.wc-metaboxes-wrapper .wc-metabox h3:hover .handlediv,.wc-metaboxes-wrapper .wc-metabox h3:hover a.delete,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper .handlediv,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper a.delete{visibility:visible}.wc-metaboxes-wrapper .wc-metabox table{width:100%;position:relative;background-color:#fdfdfd;padding:1em;border-top:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox table td{text-align:left;padding:0 6px 1em 0;vertical-align:top;border:0}.wc-metaboxes-wrapper .wc-metabox table td label{text-align:left;display:block;line-height:21px}.wc-metaboxes-wrapper .wc-metabox table td input{float:left;min-width:200px}.wc-metaboxes-wrapper .wc-metabox table td input,.wc-metaboxes-wrapper .wc-metabox table td textarea{width:100%;margin:0;display:block;font-size:14px;padding:4px;color:#555}.wc-metaboxes-wrapper .wc-metabox table td .select2-container,.wc-metaboxes-wrapper .wc-metabox table td select{width:100%!important}.wc-metaboxes-wrapper .wc-metabox table td input.short{width:200px}.wc-metaboxes-wrapper .wc-metabox table td input.checkbox{width:16px;min-width:inherit;vertical-align:text-bottom;display:inline-block;float:none}.wc-metaboxes-wrapper .wc-metabox table td.attribute_name{width:200px}.wc-metaboxes-wrapper .wc-metabox table .minus,.wc-metaboxes-wrapper .wc-metabox table .plus{margin-top:6px}.wc-metaboxes-wrapper .wc-metabox table .fl{float:left}.wc-metaboxes-wrapper .wc-metabox table .fr{float:right}.variations-pagenav{float:right;line-height:24px}.variations-pagenav .displaying-num{color:#777;font-size:12px;font-style:italic}.variations-pagenav a{padding:0 10px 3px;background:rgba(0,0,0,.05);font-size:16px;font-weight:400;text-decoration:none}.variations-pagenav a.disabled,.variations-pagenav a.disabled:active,.variations-pagenav a.disabled:focus,.variations-pagenav a.disabled:hover{color:#A0A5AA;background:rgba(0,0,0,.05)}.variations-defaults{float:left}.variations-defaults select{margin:.25em .25em .25em 0}.woocommerce_variable_attributes{background-color:#fdfdfd;border-top:1px solid #eee}.woocommerce_variable_attributes .data{padding:1em 2em}.woocommerce_variable_attributes .data:after,.woocommerce_variable_attributes .data:before{content:" ";display:table}.woocommerce_variable_attributes .data:after{clear:both}.woocommerce_variable_attributes .upload_image_button{display:block;width:48px;height:48px;float:left;margin-right:20px;position:relative;cursor:pointer}.woocommerce_variable_attributes .upload_image_button img{width:100%;height:auto;display:none}.woocommerce_variable_attributes .upload_image_button:before{content:"\f128";font-family:Dashicons;position:absolute;top:0;left:0;right:0;bottom:0;text-align:center;line-height:48px;font-size:48px;font-weight:400;-webkit-font-smoothing:antialiased}.woocommerce_variable_attributes .upload_image_button.remove img{display:block}.woocommerce_variable_attributes .upload_image_button.remove:before{content:"\f335";display:none}.woocommerce_variable_attributes .upload_image_button.remove:hover:before{display:block}.woocommerce_variable_attributes .options{border:1px solid #eee;border-width:1px 0;padding:.25em 0}.woocommerce_variable_attributes .options label{display:inline-block;padding:4px 1em 2px 0}.woocommerce_variable_attributes .options input[type=checkbox]{margin-top:5px;margin-right:3px}.form-row label{display:block}.form-row input[type=number],.form-row input[type=text],.form-row select{width:100%}.form-row.dimensions_field input{width:25%;float:left;margin-right:1%}.form-row.dimensions_field input:last-of-type{margin-right:0}.form-row-first,.form-row-last{width:48%;float:right}.form-row-first{clear:both;float:left}.form-row-full{clear:both}.tips{cursor:help;text-decoration:none}img.tips{padding:5px 0 0}#tiptip_holder{display:none;position:absolute;top:0;left:0;z-index:9999999}#tiptip_holder.tip_top{padding-bottom:5px}#tiptip_holder.tip_top #tiptip_arrow_inner{margin-top:-7px;margin-left:-6px;border-top-color:#333}#tiptip_holder.tip_bottom{padding-top:5px}#tiptip_holder.tip_bottom #tiptip_arrow_inner{margin-top:-5px;margin-left:-6px;border-bottom-color:#333}#tiptip_holder.tip_right{padding-left:5px}#tiptip_holder.tip_right #tiptip_arrow_inner{margin-top:-6px;margin-left:-5px;border-right-color:#333}#tiptip_holder.tip_left{padding-right:5px}#tiptip_holder.tip_left #tiptip_arrow_inner{margin-top:-6px;margin-left:-7px;border-left-color:#333}#tiptip_content,.chart-tooltip,.wc_error_tip{color:#fff;font-size:.8em;max-width:150px;background:#333;text-align:center;border-radius:3px;padding:.618em 1em;box-shadow:0 1px 3px rgba(0,0,0,.2)}#tiptip_content code,.chart-tooltip code,.wc_error_tip code{padding:1px;background:#888}#tiptip_arrow,#tiptip_arrow_inner{position:absolute;border-color:transparent;border-style:solid;border-width:6px;height:0;width:0}.wc_error_tip{max-width:20em;line-height:1.8em;position:absolute;white-space:normal;background:#d82223;margin:1.5em 1px 0 -1em;z-index:9999999}.wc_error_tip:after{content:"";display:block;border:8px solid #d82223;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-3px;left:50%;margin:-1em 0 0 -3px}img.ui-datepicker-trigger{vertical-align:middle;margin-top:-1px;cursor:pointer}.wc-metabox-content img.ui-datepicker-trigger,.woocommerce_options_panel img.ui-datepicker-trigger{float:left;margin-right:8px;margin-top:4px;margin-left:4px}#ui-datepicker-div{display:none}.woocommerce-reports-wide.woocommerce-reports-wrap,.woocommerce-reports-wrap.woocommerce-reports-wrap{margin-left:300px;padding-top:18px}.woocommerce-reports-wide.halved,.woocommerce-reports-wrap.halved{margin:0;overflow:hidden;zoom:1}.woocommerce-reports-wide .widefat td,.woocommerce-reports-wrap .widefat td{vertical-align:top;padding:7px}.woocommerce-reports-wide .widefat td .description,.woocommerce-reports-wrap .widefat td .description{margin:4px 0 0}.woocommerce-reports-wide .postbox:after,.woocommerce-reports-wrap .postbox:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox h3,.woocommerce-reports-wrap .postbox h3{cursor:default!important}.woocommerce-reports-wide .postbox .inside,.woocommerce-reports-wrap .postbox .inside{padding:10px;margin:0!important}.woocommerce-reports-wide .postbox div.stats_range,.woocommerce-reports-wide .postbox h3.stats_range,.woocommerce-reports-wrap .postbox div.stats_range,.woocommerce-reports-wrap .postbox h3.stats_range{border-bottom-color:#dfdfdf;margin:0;padding:0!important}.woocommerce-reports-wide .postbox div.stats_range .export_csv,.woocommerce-reports-wide .postbox h3.stats_range .export_csv,.woocommerce-reports-wrap .postbox div.stats_range .export_csv,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv{float:right;line-height:26px;border-left:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range .export_csv:before,.woocommerce-reports-wide .postbox h3.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox div.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;content:"";text-decoration:none;margin-right:4px}.woocommerce-reports-wide .postbox div.stats_range ul,.woocommerce-reports-wide .postbox h3.stats_range ul,.woocommerce-reports-wrap .postbox div.stats_range ul,.woocommerce-reports-wrap .postbox h3.stats_range ul{list-style:none;margin:0;padding:0;zoom:1;background:#f5f5f5;border-bottom:1px solid #ccc}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox div.stats_range ul:before,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:before,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:before,.woocommerce-reports-wrap .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:before{content:" ";display:table}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:after{clear:both}.woocommerce-reports-wide .postbox div.stats_range ul li,.woocommerce-reports-wide .postbox h3.stats_range ul li,.woocommerce-reports-wrap .postbox div.stats_range ul li,.woocommerce-reports-wrap .postbox h3.stats_range ul li{float:left;margin:0;padding:0;line-height:26px;font-weight:700;font-size:14px}.woocommerce-reports-wide .postbox div.stats_range ul li a,.woocommerce-reports-wide .postbox h3.stats_range ul li a,.woocommerce-reports-wrap .postbox div.stats_range ul li a,.woocommerce-reports-wrap .postbox h3.stats_range ul li a{border-right:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range ul li.active,.woocommerce-reports-wide .postbox h3.stats_range ul li.active,.woocommerce-reports-wrap .postbox div.stats_range ul li.active,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active{background:#fff;-webkit-box-shadow:0 4px 0 0 #fff;box-shadow:0 4px 0 0 #fff}.woocommerce-reports-wide .postbox div.stats_range ul li.active a,.woocommerce-reports-wide .postbox h3.stats_range ul li.active a,.woocommerce-reports-wrap .postbox div.stats_range ul li.active a,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active a{color:#777}.woocommerce-reports-wide .postbox div.stats_range ul li.custom,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom{padding:9px 10px;vertical-align:middle}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form{display:inline;margin:0}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form input.range_datepicker{padding:0;margin:0 10px 0 0;background:0 0;border:0;color:#777;text-align:center;-webkit-box-shadow:none;box-shadow:none}.woocommerce-reports-wide .postbox .chart-with-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar{padding:12px 12px 12px 249px;margin:0!important}.woocommerce-reports-wide .postbox .chart-with-sidebar .chart-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar .chart-sidebar{width:225px;margin-left:-237px;float:left}.woocommerce-reports-wide .postbox .chart-widgets,.woocommerce-reports-wrap .postbox .chart-widgets{margin:0;padding:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget{margin:0 0 1em;background:#fafafa;border:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4{background:#fff;border:1px solid #dfdfdf;border-left-width:0;border-right-width:0;padding:10px;margin:0;color:#2ea2cc;border-top-width:0;background-image:-webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9));background-image:-webkit-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-moz-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-o-linear-gradient(bottom,#ececec,#f9f9f9);background-image:linear-gradient(to top,#ececec,#f9f9f9)}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr.active td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr.active td{background:#f5f5f5}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4.section_title:hover,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4.section_title:hover{color:#a00}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title{cursor:pointer}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span{display:block}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin-left:.618em;content:"";text-decoration:none;float:right;font-size:.9em;line-height:1.618}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open{color:#333}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open span:after{display:none}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section{border-bottom:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section .select2-container,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section .select2-container{width:100%!important}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section:last-of-type,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section:last-of-type{border-radius:0 0 3px 3px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td{padding:7px 10px;vertical-align:top;border-top:1px solid #e5e5e5;line-height:1.4em}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.sparkline,form.report_filters div,form.report_filters input,form.report_filters label,form.report_filters p{vertical-align:middle}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr:first-child td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr:first-child td{border-top:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name{max-width:175px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name a,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name a{word-wrap:break-word}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table .wc_sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table .wc_sparkline{width:32px;height:1em;display:block;float:right}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p{margin:0;padding:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p .submit{margin-top:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget #product_ids,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget #product_ids{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_none,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_none{float:right;color:#999;margin-left:4px;margin-top:10px}.woocommerce-reports-wide .postbox .chart-legend,.woocommerce-reports-wrap .postbox .chart-legend{list-style:none;margin:0 0 1em;padding:0;border:1px solid #dfdfdf;border-right-width:0;border-bottom-width:0;background:#fff}.woocommerce-reports-wide .postbox .chart-legend li,.woocommerce-reports-wrap .postbox .chart-legend li{border-right:5px solid #aaa;color:#aaa;padding:1em;display:block;margin:0;-webkit-transition:all ease .5s;box-shadow:inset 0 -1px 0 0 #dfdfdf}.woocommerce-reports-wide .postbox .chart-legend li strong,.woocommerce-reports-wrap .postbox .chart-legend li strong{font-size:1.618em;line-height:1.2em;color:#464646;font-weight:400;display:block;font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif}.woocommerce-reports-wide .postbox .chart-legend li strong del,.woocommerce-reports-wrap .postbox .chart-legend li strong del{color:#e74c3c;font-weight:400}.woocommerce-reports-wide .postbox .chart-legend li:hover,.woocommerce-reports-wrap .postbox .chart-legend li:hover{box-shadow:inset 0 -1px 0 0 #dfdfdf,inset 300px 0 0 rgba(156,93,144,.1);border-right:5px solid #9c5d90!important;padding-left:1.5em;color:#9c5d90}.woocommerce-reports-wide .postbox .pie-chart-legend,.woocommerce-reports-wrap .postbox .pie-chart-legend{margin:12px 0 0;overflow:hidden}.woocommerce-reports-wide .postbox .pie-chart-legend li,.woocommerce-reports-wrap .postbox .pie-chart-legend li{float:left;margin:0;padding:6px 0 0;border-top:4px solid #999;text-align:center;box-sizing:border-box;width:50%}.woocommerce-reports-wide .postbox .stat,.woocommerce-reports-wrap .postbox .stat{font-size:1.5em!important;font-weight:700;text-align:center}.woocommerce-reports-wide .postbox .chart-placeholder,.woocommerce-reports-wrap .postbox .chart-placeholder{width:100%;height:650px;overflow:hidden;position:relative}.woocommerce-reports-wide .postbox .chart-prompt,.woocommerce-reports-wrap .postbox .chart-prompt{line-height:650px;margin:0;color:#999;font-size:1.2em;font-style:italic;text-align:center}.woocommerce-reports-wide .postbox .chart-container,.woocommerce-reports-wrap .postbox .chart-container{background:#fff;padding:12px;position:relative;border:1px solid #dfdfdf;border-radius:3px}.woocommerce-reports-wide .postbox .main .chart-legend,.woocommerce-reports-wrap .postbox .main .chart-legend{margin-top:12px}.woocommerce-reports-wide .postbox .main .chart-legend li,.woocommerce-reports-wrap .postbox .main .chart-legend li{border-right:0;margin:0 8px 0 0;float:left;border-top:4px solid #aaa}.woocommerce-reports-wide .woocommerce-reports-main,.woocommerce-reports-wrap .woocommerce-reports-main{float:left;min-width:100%}.woocommerce-reports-wide .woocommerce-reports-main table td,.woocommerce-reports-wrap .woocommerce-reports-main table td{padding:9px}.woocommerce-reports-wide .woocommerce-reports-sidebar,.woocommerce-reports-wrap .woocommerce-reports-sidebar{display:inline;width:281px;margin-left:-300px;clear:both;float:left}.woocommerce-reports-wide .woocommerce-reports-left,.woocommerce-reports-wrap .woocommerce-reports-left{width:49.5%;float:left}.woocommerce-reports-wide .woocommerce-reports-right,.woocommerce-reports-wrap .woocommerce-reports-right{width:49.5%;float:right}.woocommerce-reports-wide .column-wc_actions a.edit,.woocommerce-reports-wide .column-wc_actions a.view,.woocommerce-reports-wrap .column-wc_actions a.edit,.woocommerce-reports-wrap .column-wc_actions a.view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;line-height:1.85}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after{content:"\f464"}.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{content:"\f177"}.woocommerce-wide-reports-wrap{padding-bottom:11px}.woocommerce-wide-reports-wrap .widefat .export-data{float:right}.woocommerce-wide-reports-wrap .widefat td,.woocommerce-wide-reports-wrap .widefat th{vertical-align:middle;padding:7px}.chart-tooltip{position:absolute;display:none;line-height:1}table.bar_chart{width:100%}table.bar_chart thead th{text-align:left;color:#ccc;padding:6px 0}table.bar_chart tbody th{padding:6px 0;width:25%;text-align:left!important;font-weight:400!important;border-bottom:1px solid #fee}table.bar_chart tbody td{text-align:right;line-height:24px;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td span{color:#8a4b75;display:block}table.bar_chart tbody td span.alt{color:#47a03e;margin-top:6px}table.bar_chart tbody td.bars{position:relative;text-align:left;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td.bars a,table.bar_chart tbody td.bars span{text-decoration:none;clear:both;background:#8a4b75;float:left;display:block;line-height:24px;height:24px;-moz-border-radius:3px;-webkit-border-radius:3px;-o-border-radius:3px;-khtml-border-radius:3px;border-radius:3px}.post-type-product .woocommerce-BlankState-message:before,.post-type-shop_coupon .woocommerce-BlankState-message:before,.post-type-shop_order .woocommerce-BlankState-message:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}table.bar_chart tbody td.bars span.alt{clear:both;background:#47a03e}table.bar_chart tbody td.bars span.alt span{margin:0;color:#c5dec2!important;text-shadow:0 1px 0 #47a03e;background:0 0}.post-type-shop_order .woocommerce-BlankState-message:before{content:""}.post-type-shop_coupon .woocommerce-BlankState-message:before{content:""}.post-type-product .woocommerce-BlankState-message:before{content:""}.woocommerce-BlankState{text-align:center;padding:5em 0 0}.woocommerce-BlankState .woocommerce-BlankState-message{color:#aaa;margin:0 auto 1.5em;line-height:1.5em;font-size:1.2em;max-width:500px}.woocommerce-BlankState .woocommerce-BlankState-message:before{color:#ddd;text-shadow:0 -1px 1px rgba(0,0,0,.2),0 1px 0 rgba(255,255,255,.8);font-size:8em;display:block;position:relative!important;top:auto;left:auto;line-height:1em;margin:0 0 .1875em}.woocommerce-BlankState .woocommerce-BlankState-cta{font-size:1.2em;padding:.75em 1.5em;height:auto}@media only screen and (max-width:1280px){#order_data .order_data_column{width:48%}#order_data .order_data_column:first-child{width:100%}.woocommerce_options_panel .description{display:block;clear:both;margin-left:0}.woocommerce_options_panel .dimensions_field .wrap,.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:80%}.woocommerce_options_panel .downloadable_files,.woocommerce_variations .downloadable_files{padding:0;clear:both}.woocommerce_options_panel .downloadable_files label,.woocommerce_variations .downloadable_files label{position:static}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{margin:0 12px 24px;width:94%}.woocommerce_options_panel .downloadable_files table .sort,.woocommerce_variations .downloadable_files table .sort{visibility:hidden}.woocommerce_options_panel .woocommerce_variable_attributes .downloadable_files table,.woocommerce_variations .woocommerce_variable_attributes .downloadable_files table{margin:0 0 1em;width:100%}}@media only screen and (max-width:900px){#woocommerce-coupon-data ul.coupon_data_tabs,#woocommerce-product-data .wc-tabs-back,#woocommerce-product-data ul.product_data_tabs{width:10%}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{width:90%}#woocommerce-coupon-data ul.coupon_data_tabs li a,#woocommerce-product-data ul.product_data_tabs li a{position:relative;text-indent:-999px;padding:10px}#woocommerce-coupon-data ul.coupon_data_tabs li a:before,#woocommerce-product-data ul.product_data_tabs li a:before{position:absolute;top:0;right:0;bottom:0;left:0;text-indent:0;text-align:center;line-height:40px;width:100%;height:40px}}@media only screen and (max-width:782px){#wp-excerpt-media-buttons a{font-size:16px;line-height:37px;height:39px;padding:0 20px 0 15px}#wp-excerpt-editor-tools{padding-top:20px;padding-right:15px;overflow:hidden;margin-bottom:-1px}.post-type-product .wp-list-table .is-expanded td:not(.hidden),.post-type-shop_order .wp-list-table .is-expanded td:not(.hidden){overflow:visible}#woocommerce-product-data .checkbox{width:25px}.variations-pagenav{float:none;text-align:center;font-size:18px}.variations-pagenav .displaying-num{font-size:16px}.variations-pagenav a{padding:8px 20px 11px;font-size:18px}.variations-pagenav select{padding:0 20px}.variations-defaults{float:none;text-align:center;margin-top:10px}.post-type-product .wp-list-table .column-thumb{display:none;text-align:left;padding-bottom:0}.post-type-product .wp-list-table .column-thumb:before{display:none!important}.post-type-product .wp-list-table .column-thumb img{max-width:32px}.post-type-product .wp-list-table .toggle-row{top:-28px}.post-type-shop_order .wp-list-table .column-order_status{display:none;text-align:left;padding-bottom:0}.post-type-shop_order .wp-list-table .column-order_status mark{margin:0}.post-type-shop_order .wp-list-table .column-order_status:before{display:none!important}.post-type-shop_order .wp-list-table .column-customer_message,.post-type-shop_order .wp-list-table .column-order_notes{text-align:inherit}.post-type-shop_order .wp-list-table .column-order_notes .note-on{font-size:1.3em;margin:0}.post-type-shop_order .wp-list-table .toggle-row{top:-15px}}@media only screen and (max-width:500px){.woocommerce_options_panel label,.woocommerce_options_panel legend{float:none;width:auto;display:block;margin:0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px!important}}.wc-backbone-modal *{box-sizing:border-box}.wc-backbone-modal .wc-backbone-modal-content{position:fixed;background:#fff;z-index:100000;left:50%;top:50%;transform:translate(-50%,-50%);width:500px}.wc-backbone-modal .wc-backbone-modal-content article{overflow:auto}.wc-backbone-modal.wc-backbone-modal-shipping-method-settings .wc-backbone-modal-content{width:75%;min-width:500px}.wc-backbone-modal-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;min-height:360px;background:#000;opacity:.7;z-index:99900}.wc-backbone-modal-main{padding-bottom:55px}.wc-backbone-modal-main article,.wc-backbone-modal-main header{display:block;position:relative}.wc-backbone-modal-main .wc-backbone-modal-header{height:auto;background:#fcfcfc;padding:1em 1.5em;border-bottom:1px solid #ddd}.wc-backbone-modal-main .wc-backbone-modal-header h1{margin:0;font-size:18px;font-weight:700;line-height:1.5em}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link{cursor:pointer;color:#777;height:54px;width:54px;padding:0;position:absolute;top:0;right:0;text-align:center;border:0;border-left:1px solid #ddd;background-color:transparent;-webkit-transition:color .1s ease-in-out,background .1s ease-in-out;transition:color .1s ease-in-out,background .1s ease-in-out}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:before{font:400 22px/50px dashicons!important;color:#666;display:block;content:'\f335';font-weight:300}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus,.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:hover{background:#ddd;border-color:#ccc;color:#000}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus{outline:0}.wc-backbone-modal-main article{padding:1.5em}.wc-backbone-modal-main article p{margin:1.5em 0}.wc-backbone-modal-main article p:last-child,.wc-backbone-modal-main footer .inner .button{margin-bottom:0}.wc-backbone-modal-main article p:first-child{margin-top:0}.wc-backbone-modal-main article .pagination{padding:10px 0 0;text-align:center}.wc-backbone-modal-main footer{position:absolute;left:0;right:0;bottom:0;z-index:100;padding:1em 1.5em;background:#fcfcfc;border-top:1px solid #dfdfdf;box-shadow:0 -4px 4px -4px rgba(0,0,0,.1)}.wc-backbone-modal-main footer .inner{float:right;line-height:23px}.select2-drop{z-index:999999!important}.select2-container-multi .select2-choices .select2-search-field input{font-family:inherit;font-size:inherit;font-weight:inherit;padding:3px 5px}.select2-container{line-height:1.85em;font-size:14px} \ No newline at end of file +@charset "UTF-8";.button.wc-reload:after,.woocommerce-help-tip:after{speak:none;text-transform:none;-webkit-font-smoothing:antialiased}@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg)}}@-moz-keyframes spin{100%{-moz-transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}.select2-container{margin:0;position:relative;display:block!important;zoom:1;vertical-align:middle}.select2-container,.select2-drop,.select2-search,.select2-search input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{display:block;padding:0 0 0 8px;overflow:hidden;position:relative;border:1px solid #ccc;white-space:nowrap;color:#444;text-decoration:none;border-radius:3px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;font-weight:400}html[dir=rtl] .select2-container .select2-choice{padding:0 8px 0 0}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#ccc;border-radius:0 0 4px 4px}.select2-container.select2-allowclear .select2-choice .select2-chosen{margin-right:42px}.select2-container .select2-choice>.select2-chosen{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:none;width:auto}html[dir=rtl] .select2-container .select2-choice>.select2-chosen{margin-left:26px;margin-right:0}.select2-container .select2-choice abbr{display:none;width:12px;height:12px;position:absolute;right:24px;top:5px;font-size:1px;text-decoration:none;border:0;background:url(../images/select2.png) right top no-repeat;cursor:pointer;outline:0}.select2-container.select2-allowclear .select2-choice abbr{display:inline-block}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop-mask{border:0;margin:0;padding:0;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:9998;background-color:#fff;filter:alpha(opacity=0)}.select2-drop{width:100%;margin-top:-1px;position:absolute;top:100%;background:#fff;color:#000;border:1px solid #ccc;border-top:0;border-radius:0 0 3px 3px}.select2-drop.select2-drop-above{margin-top:1px;border-top:1px solid #ccc;border-bottom:0;border-radius:3px 3px 0 0}.select2-drop-active{border:1px solid #666;border-top:none}.select2-drop.select2-drop-above.select2-drop-active{border-top:1px solid #666}.select2-drop-auto-width{border-top:1px solid #ccc;width:auto}.select2-drop-auto-width .select2-search{padding-top:4px}.select2-container .select2-choice .select2-arrow{display:inline-block;width:18px;height:100%;position:absolute;right:0;top:0;border-radius:0 3px 3px 0;background-clip:padding-box}html[dir=rtl] .select2-container .select2-choice .select2-arrow{left:0;right:auto;border-radius:3px 0 0 3px}.select2-container .select2-choice .select2-arrow b{display:block;width:100%;height:100%;position:relative}.select2-container .select2-choice .select2-arrow b:after{position:absolute;display:block;content:"";top:50%;left:50%;border:4px solid transparent;border-top-color:#666;margin-left:-7px;margin-top:-2px}.select2-search{display:inline-block;width:100%;margin:0;padding-left:4px;padding-right:4px;position:relative;z-index:10000;white-space:nowrap;padding-bottom:4px}.select2-search input{width:100%;height:auto!important;padding:4px 20px 4px 5px!important;margin:0;outline:0;font-family:sans-serif;font-size:1em;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none;background:url(../images/select2.png) 100% -22px no-repeat #fff}html[dir=rtl] .select2-search input{padding:4px 5px 4px 20px;background:url(../images/select2.png) -37px -22px no-repeat #fff}.select2-drop.select2-drop-above .select2-search input{margin-top:4px}.select2-search input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff}.select2-container-active .select2-choice,.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-dropdown-open .select2-choice{border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-dropdown-open .select2-choice .select2-arrow b:after{border-top-color:transparent;border-bottom-color:#666;margin-top:-6px}.select2-dropdown-open.select2-drop-above .select2-choice,.select2-dropdown-open.select2-drop-above .select2-choices{border:1px solid #666;border-top-color:transparent}.select2-dropdown-open .select2-choice .select2-arrow{background:0 0;border-left:none;filter:none}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow{border-right:none}.select2-dropdown-open .select2-choice .select2-arrow b{background-position:-18px 1px}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow b{background-position:-16px 1px}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.select2-results{max-height:200px;padding:4px;margin:0;position:relative;overflow-x:hidden;overflow-y:auto;-webkit-tap-highlight-color:transparent;background:#fafafa}html[dir=rtl] .select2-results{padding:0 4px 0 0;margin:4px 0 4px 4px}.select2-results ul.select2-result-sub{margin:0;padding-left:0}.select2-results li{list-style:none;display:list-item;background-image:none;margin:3px 0}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:700}.select2-results .select2-result-label{padding:5px 7px;margin:0;cursor:pointer;min-height:1em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select2-results-dept-1 .select2-result-label{padding-left:20px}.select2-results-dept-2 .select2-result-label{padding-left:40px}.select2-results-dept-3 .select2-result-label{padding-left:60px}.select2-results-dept-4 .select2-result-label{padding-left:80px}.select2-results-dept-5 .select2-result-label{padding-left:100px}.select2-results-dept-6 .select2-result-label{padding-left:110px}.select2-results-dept-7 .select2-result-label{padding-left:120px}.select2-results .select2-highlighted{background:#f1f1f1;color:#000;border-radius:3px}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:0 0}.select2-results .select2-highlighted ul{background:#fff;color:#000}.select2-results .select2-ajax-error,.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item;padding-left:5px}.select2-results .select2-disabled.select2-highlighted{color:#666;background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-disabled{background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-selected{display:none}.select2-more-results.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #f4f4f4}.select2-results .select2-ajax-error{background:rgba(255,50,50,.2)}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice .select2-arrow{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container.select2-container-disabled .select2-choice abbr{display:none}.select2-container-multi .select2-choices{height:auto!important;height:1%;margin:0;padding:0 5px 0 0;position:relative;border:1px solid #ccc;cursor:text;overflow:hidden;background-color:#fff;min-height:26px}html[dir=rtl] .select2-container-multi .select2-choices{padding:0 0 0 5px}.select2-locked{padding:3px 5px!important}.select2-container-multi.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-container-multi .select2-choices li{float:left;list-style:none}html[dir=rtl] .select2-container-multi .select2-choices li{float:right}.select2-container-multi .select2-choices .select2-search-field{margin:0;padding:0;white-space:nowrap}.select2-container-multi .select2-choices .select2-search-field:first-child{width:100%}.select2-container-multi .select2-choices .select2-search-field input{margin:1px 0;outline:0;border:0;-webkit-box-shadow:none;box-shadow:none;background:0 0!important}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff!important}.select2-default{color:#999!important}.select2-container-multi .select2-choices .select2-search-choice{padding:5px 8px 5px 24px;margin:3px 0 3px 5px;position:relative;line-height:15px;color:#333;cursor:default;border-radius:2px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#e4e4e4}html[dir=rtl] .select2-container-multi .select2-choices .select2-search-choice{margin:3px 5px 3px 0;padding:5px 24px 5px 8px}.select2-container-multi .select2-choices .select2-search-choice .select2-chosen{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;width:12px;height:13px;position:absolute;right:7px;top:6px;font-size:1px;outline:0;background:url(../images/select2.png) right top no-repeat}html[dir=rtl] .select2-search-choice-close{right:auto;left:7px}.select2-container-multi .select2-search-choice-close{left:7px}html[dir=rtl] .select2-container-multi .select2-search-choice-close{left:auto;right:7px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover,.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{padding:3px 5px;border:1px solid #ddd;background-image:none;background-color:#f4f4f4}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none;background:0 0}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-match{text-decoration:underline}.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.select2-display-none{display:none}.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:2dppx){.select2-search input{background-image:url(../images/select2x2.png)!important;background-repeat:no-repeat!important;background-size:60px 40px!important;background-position:100% -21px!important}}@font-face{font-family:star;src:url(../fonts/star.eot);src:url(../fonts/star.eot?#iefix) format("embedded-opentype"),url(../fonts/star.woff) format("woff"),url(../fonts/star.ttf) format("truetype"),url(../fonts/star.svg#star) format("svg");font-weight:400;font-style:normal}@font-face{font-family:WooCommerce;src:url(../fonts/WooCommerce.eot);src:url(../fonts/WooCommerce.eot?#iefix) format("embedded-opentype"),url(../fonts/WooCommerce.woff) format("woff"),url(../fonts/WooCommerce.ttf) format("truetype"),url(../fonts/WooCommerce.svg#WooCommerce) format("svg");font-weight:400;font-style:normal}.blockUI.blockOverlay:before{height:1em;width:1em;position:absolute;top:50%;left:50%;margin-left:-.5em;margin-top:-.5em;display:block;content:"";-webkit-animation:spin 1s ease-in-out infinite;-moz-animation:spin 1s ease-in-out infinite;animation:spin 1s ease-in-out infinite;background:url(../images/icons/loader.svg) center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75)}.wc_addons_wrap .products{overflow:hidden}.wc_addons_wrap .products li{float:left;margin:0 1em 1em 0!important;padding:0;vertical-align:top;width:300px}.wc_addons_wrap .products li a{text-decoration:none;color:inherit;border:1px solid #ddd;display:block;min-height:220px;overflow:hidden;background:#f5f5f5;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1)}.wc_addons_wrap .products li a img{max-width:258px;max-height:24px;padding:17px 20px;display:block;margin:0;background:#fff;border-right:260px solid #fff}.wc_addons_wrap .products li a .price,.wc_addons_wrap .products li a img.extension-thumb+h3{display:none}.wc_addons_wrap .products li a h2,.wc_addons_wrap .products li a h3{margin:0!important;padding:20px!important;background:#fff}.wc_addons_wrap .products li a p{padding:20px!important;margin:0!important;border-top:1px solid #f1f1f1}.wc_addons_wrap .products li a:focus,.wc_addons_wrap .products li a:hover{background-color:#fff}.wc_addons_wrap .storefront{background:url(../images/storefront-bg.jpg) bottom right #f6f6f6;border:1px solid #ddd;padding:20px;overflow:hidden;zoom:1}.wc_addons_wrap .storefront img{width:278px;height:auto;float:left;margin:0 20px 0 0;box-shadow:0 1px 6px rgba(0,0,0,.1)}.wc_addons_wrap .storefront p{max-width:750px}.woocommerce-BlankState a.button-primary,.woocommerce-BlankState button.button-primary,.woocommerce-message a.button-primary,.woocommerce-message button.button-primary{background:#bb77ae;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;color:#fff;text-shadow:0 -1px 1px #A36597,1px 0 1px #A36597,0 1px 1px #A36597,-1px 0 1px #A36597}.woocommerce-BlankState a.button-primary:active,.woocommerce-BlankState a.button-primary:focus,.woocommerce-BlankState a.button-primary:hover,.woocommerce-BlankState button.button-primary:active,.woocommerce-BlankState button.button-primary:focus,.woocommerce-BlankState button.button-primary:hover,.woocommerce-message a.button-primary:active,.woocommerce-message a.button-primary:focus,.woocommerce-message a.button-primary:hover,.woocommerce-message button.button-primary:active,.woocommerce-message button.button-primary:focus,.woocommerce-message button.button-primary:hover{background:#A36597;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597}.woocommerce-message{position:relative;border-left-color:#cc99c2!important;overflow:hidden}.woocommerce-message a.docs,.woocommerce-message a.skip{text-decoration:none!important}.woocommerce-message a.woocommerce-message-close{position:absolute;top:10px;right:10px;padding:10px 15px 10px 21px;font-size:13px;line-height:1.23076923;text-decoration:none}.woocommerce-message a.woocommerce-message-close:before{position:absolute;top:8px;left:0;-webkit-transition:all .1s ease-in-out;transition:all .1s ease-in-out}.woocommerce-message .twitter-share-button{margin-top:-3px;margin-left:3px;vertical-align:middle}#variable_product_options #message,#variable_product_options .notice{margin:10px}.clear{clear:both}#woocommerce-fields-bulk.inline-edit-col label,#woocommerce-fields.inline-edit-col{clear:left}.wrap.woocommerce div.error,.wrap.woocommerce div.updated{margin-top:10px}mark.amount{background:0 0;color:inherit}.postbox,.woocommerce{input:invalid;input-border:1px solid #cc010b;input-background:#ffebe8}.simplify-commerce-banner{overflow:hidden}.simplify-commerce-banner img{float:right;padding:15px 0;margin-left:1em;width:200px}.woocommerce-help-tip{color:#666;display:inline-block;font-size:1.1em;font-style:normal;height:16px;line-height:16px;position:relative;vertical-align:middle;width:16px}.woocommerce-help-tip:after{font-family:Dashicons;font-weight:400;font-variant:normal;line-height:1;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";cursor:help}h2 .woocommerce-help-tip{margin-top:-5px;margin-left:.25em}table.wc_status_table{margin-bottom:1em}table.wc_status_table h2{font-size:14px;margin:0}table.wc_status_table tr:nth-child(2n) td,table.wc_status_table tr:nth-child(2n) th{background:#fcfcfc}table.wc_status_table th{font-weight:700;padding:9px}table.wc_status_table td:first-child{width:33%}table.wc_status_table td.help{width:1em}table.wc_status_table td{padding:9px;font-size:1.1em}table.wc_status_table td mark{background:0 0}table.wc_status_table td mark.yes{color:#7ad03a}table.wc_status_table td mark.no{color:#999}table.wc_status_table td mark.error{color:#a00}table.wc_status_table td ul{margin:0}table.wc_status_table .help_tip{cursor:help}#debug-report{display:none;margin:10px 0;padding:0;position:relative}#debug-report textarea{font-family:monospace;width:100%;margin:0;height:300px;padding:20px;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;resize:none;font-size:12px;line-height:20px;outline:0}#log-viewer-select{padding:10px 0 8px;line-height:180%}#log-viewer textarea{width:100%;resize:vertical}.inline-edit-product.quick-edit-row .inline-edit-col-center,.inline-edit-product.quick-edit-row .inline-edit-col-right{float:right!important}#woocommerce-fields.inline-edit-col label.featured,#woocommerce-fields.inline-edit-col label.manage_stock{margin-left:10px}#woocommerce-fields.inline-edit-col .dimensions div{display:block;margin:.2em 0}#woocommerce-fields.inline-edit-col .dimensions div span.title{display:block;float:left;width:5em}#woocommerce-fields.inline-edit-col .dimensions div span.input-text-wrap{display:block;margin-left:5em}#woocommerce-fields.inline-edit-col .text{box-sizing:border-box;width:99%;float:left;margin:1px 1% 1px 1px}#woocommerce-fields.inline-edit-col .height,#woocommerce-fields.inline-edit-col .length,#woocommerce-fields.inline-edit-col .width{width:32.33%}#woocommerce-fields.inline-edit-col .height{margin-right:0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group label{clear:none;width:49%;margin:.2em 0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group.dimensions label{width:75%;max-width:75%}#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .regular_price,#woocommerce-fields-bulk.inline-edit-col .sale_price,#woocommerce-fields-bulk.inline-edit-col .stock,#woocommerce-fields-bulk.inline-edit-col .weight{box-sizing:border-box;width:100%;margin-left:4.4em}#woocommerce-fields-bulk.inline-edit-col .height,#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .width{box-sizing:border-box;width:25%}.column-coupon_code{line-height:2.25em}.column-coupon_code,ul.wc_coupon_list{margin:0;overflow:hidden;zoom:1;clear:both}ul.wc_coupon_list li{margin:0}ul.wc_coupon_list li.code{display:inline-block}ul.wc_coupon_list li.code:after{content:", "}ul.wc_coupon_list li.code:last-of-type:after{display:none}ul.wc_coupon_list li.code .tips{cursor:pointer}ul.wc_coupon_list_block{margin:0;padding-bottom:2px}ul.wc_coupon_list_block li{border-top:1px solid #fff;border-bottom:1px solid #ccc;line-height:2.5em;margin:0;padding:.5em 0}ul.wc_coupon_list_block li:first-child{border-top:0;padding-top:0}ul.wc_coupon_list_block li:last-child{border-bottom:0;padding-bottom:0}.button.wc-reload{text-indent:-9999px;position:relative;padding:0;height:28px;width:28px!important;display:inline-block}.button.wc-reload:after{font-family:Dashicons;font-weight:400;font-variant:normal;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:28px}#order_data h2,#order_data p.order_number{font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif;font-weight:400}.tablenav .actions{overflow:visible}.tablenav .select2-container{float:left;max-width:200px;font-size:14px;vertical-align:middle;margin:1px 6px 1px 1px}#woocommerce-order-data .handlediv,#woocommerce-order-data .hndle{display:none}#woocommerce-order-data .inside{display:block!important}#order_data{padding:23px 24px 12px}#order_data h2{margin:0;font-size:21px;line-height:1.2;text-shadow:1px 1px 1px #fff;padding:0}#order_data h3{font-size:14px}#order_data h3,#order_data h4{color:#333;margin:1.33em 0 0}#order_data p{color:#777}#order_data p.order_number{margin:0;line-height:1.6em;font-size:16px}#order_data .order_data_column_container{clear:both}#order_data .order_data_column{width:32%;padding:0 2% 0 0;float:left}#order_data .order_data_column:last-child{padding-right:0}#order_data .order_data_column p{padding:0!important}#order_data .order_data_column .address strong{display:block}#order_data .order_data_column .form-field{float:left;width:48%;padding:0;margin:9px 0 0}#order_data .order_data_column .form-field label{display:block;padding:0 0 3px}#order_data .order_data_column .form-field input,#order_data .order_data_column .form-field select,#order_data .order_data_column .form-field textarea{width:100%}#order_data .order_data_column .form-field .select2-container{width:100%!important}#order_data .order_data_column .form-field .date-picker{width:50%}#order_data .order_data_column .form-field .hour,#order_data .order_data_column .form-field .minute{width:3em}#order_data .order_data_column .form-field small{display:block;margin:5px 0 0;color:#999}#order_data .order_data_column .form-field.last{float:right}#order_data .order_data_column .form-field-wide{width:100%;clear:both}#order_data .order_data_column .form-field-wide .wc-customer-search,#order_data .order_data_column .form-field-wide .wc-enhanced-select,#order_data .order_data_column .form-field-wide input,#order_data .order_data_column .form-field-wide select,#order_data .order_data_column .form-field-wide textarea{width:100%}#order_data .order_data_column p.none_set{color:#999}#order_data .order_data_column ._billing_address_1_field,#order_data .order_data_column ._billing_city_field,#order_data .order_data_column ._billing_country_field,#order_data .order_data_column ._billing_email_field,#order_data .order_data_column ._billing_first_name_field,#order_data .order_data_column ._shipping_address_1_field,#order_data .order_data_column ._shipping_city_field,#order_data .order_data_column ._shipping_country_field,#order_data .order_data_column ._shipping_first_name_field{float:left}#order_data .order_data_column ._billing_address_2_field,#order_data .order_data_column ._billing_last_name_field,#order_data .order_data_column ._billing_phone_field,#order_data .order_data_column ._billing_postcode_field,#order_data .order_data_column ._billing_state_field,#order_data .order_data_column ._shipping_address_2_field,#order_data .order_data_column ._shipping_last_name_field,#order_data .order_data_column ._shipping_postcode_field,#order_data .order_data_column ._shipping_state_field,#order_data .order_data_column .wc-customer-user label a,#order_data .order_data_column .wc-order-status label a{float:right}#order_data .order_data_column ._billing_company_field,#order_data .order_data_column ._shipping_company_field,#order_data .order_data_column ._transaction_id_field{clear:both;width:100%}#order_data .order_data_column ._billing_email_field{clear:left}#order_data .order_data_column div.edit_address{display:none;zoom:1;padding-right:1px}#order_data .order_data_column .billing-same-as-shipping,#order_data .order_data_column .load_customer_billing,#order_data .order_data_column .load_customer_shipping,#order_data .order_data_column a.edit_address{width:14px;height:0;padding:14px 0 0;margin:0 0 0 6px;overflow:hidden;position:relative;color:#999;border:0;float:right}#order_data .order_data_column .billing-same-as-shipping:focus,#order_data .order_data_column .billing-same-as-shipping:hover,#order_data .order_data_column .load_customer_billing:focus,#order_data .order_data_column .load_customer_billing:hover,#order_data .order_data_column .load_customer_shipping:focus,#order_data .order_data_column .load_customer_shipping:hover,#order_data .order_data_column a.edit_address:focus,#order_data .order_data_column a.edit_address:hover{color:#000}#order_data .order_data_column .billing-same-as-shipping:after,#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after,#order_data .order_data_column a.edit_address: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}#order_data .order_data_column .billing-same-as-shipping:after{content:"\e008"}#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after{content:"\e03a"}#order_data .order_data_column a.edit_address:after{font-family:Dashicons;content:"\f464"}.order_actions{margin:0;overflow:hidden;zoom:1}.order_actions li{border-top:1px solid #fff;border-bottom:1px solid #ddd;padding:6px 0;margin:0;line-height:1.6em;float:left;width:50%;text-align:center}.order_actions li a{float:none;text-align:center;text-decoration:underline}.order_actions li.wide{width:auto;float:none;clear:both;padding:6px;text-align:left;overflow:hidden}.order_actions li #delete-action{line-height:25px;vertical-align:middle;text-align:left;float:left}.order_actions li .save_order{float:right}.order_actions li#actions{overflow:hidden}.order_actions li#actions .button{width:24px;box-sizing:border-box;float:right}.order_actions li#actions select{width:225px;box-sizing:border-box;float:left}#woocommerce-order-items .inside{margin:0;padding:0;background:#fefefe}#woocommerce-order-items .wc-order-data-row{border-bottom:1px solid #DFDFDF;padding:1.5em 2em;background:#f8f8f8;line-height:2em;text-align:right}#woocommerce-order-items .wc-order-data-row:after,#woocommerce-order-items .wc-order-data-row:before{content:" ";display:table}#woocommerce-order-items .wc-order-data-row:after{clear:both}#woocommerce-order-items .wc-order-data-row p{margin:0;line-height:2em}#woocommerce-order-items .wc-order-data-row .wc-used-coupons{text-align:left}#woocommerce-order-items .wc-order-data-row .wc-used-coupons .tips{display:inline-block}#woocommerce-order-items .wc-order-add-item{background:#fff;vertical-align:top;border-top:none}#woocommerce-order-items .wc-order-add-item .add_item_id,#woocommerce-order-items .wc-order-add-item .select2-container{vertical-align:top}#woocommerce-order-items .wc-order-add-item .add_item_id .search-field input,#woocommerce-order-items .wc-order-add-item .select2-container .search-field input{min-width:100px}#woocommerce-order-items .wc-order-add-item .select2-container{width:400px!important;text-align:left}#woocommerce-order-items .wc-order-add-item .calculate-action,#woocommerce-order-items .wc-order-add-item .cancel-action,#woocommerce-order-items .wc-order-add-item .save-action{float:left;margin-right:2px}#woocommerce-order-items .wc-used-coupons{float:left;width:50%}#woocommerce-order-items .wc-order-totals{float:right;width:50%;margin:0;padding:0;text-align:right}#woocommerce-order-items .wc-order-totals .amount{font-weight:700}#woocommerce-order-items .wc-order-totals .label{vertical-align:top}#woocommerce-order-items .wc-order-totals .total{font-size:1em!important;width:10em;margin:0 0 0 .5em;box-sizing:border-box}#woocommerce-order-items .wc-order-totals .total input[type=text]{width:96%;float:right}#woocommerce-order-items .wc-order-totals .refunded-total{color:#a00}#woocommerce-order-items .refund-actions{margin-top:5px;padding-top:12px;border-top:1px solid #DFDFDF}#woocommerce-order-items .refund-actions .button{float:right;margin-left:4px}#woocommerce-order-items .refund-actions .cancel-action,#woocommerce-order-items .wc-order-item-bulk-edit .cancel-action{float:left;margin-left:0}#woocommerce-order-items .add_meta{margin-left:0!important}#woocommerce-order-items h3 small{color:#999}#woocommerce-order-items .amount{white-space:nowrap}#woocommerce-order-items .add-items .description{margin-right:10px}#woocommerce-order-items .add-items .button{float:left;margin-right:.25em}#woocommerce-order-items .add-items .button-primary{float:none;margin-right:0}#woocommerce-order-items .inside{display:block!important}#woocommerce-order-items .handlediv,#woocommerce-order-items .hndle{display:none}#woocommerce-order-items .woocommerce_order_items_wrapper{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items{width:100%;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th{text-align:left;padding:1em;font-weight:400;color:#999;background:#f8f8f8;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th.sortable{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th .wc-arrow{float:right;position:relative;margin-right:-1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td{padding:1.5em 1em 1em;text-align:left;line-height:1.5em;vertical-align:top;border-bottom:1px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td select{width:50%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{font-size:14px;padding:4px;color:#555}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr td{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected{background:#F5EBF3}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected td{border-color:#E6CCE1;opacity:.8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:last-child td{border-bottom:1px solid #dfdfdf}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:first-child td{border-top:8px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody#order_line_items tr:first-child td{border-top:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb{text-align:left;width:38px;padding-bottom:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail{width:38px;height:38px;border:2px solid #e8e8e8;background:#f8f8f8;color:#ccc;position:relative;font-size:21px;display:block;text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;height:100%;text-align:center;content:"";width:38px;line-height:38px;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail img{width:100%;height:100%;margin:0;padding:0;position:relative}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-sku,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-variation{display:block;margin-top:.5em;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item{min-width:200px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .center,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .variation-id{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class{text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label{white-space:nowrap;color:#999;font-size:.833em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label input{display:inline}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class input{width:70px;vertical-align:middle;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class select{width:85px;height:26px;vertical-align:middle;font-size:1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input{display:inline-block;background:#fff;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);margin:1px 0;min-width:80px;overflow:hidden;line-height:1em;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input{width:100%;box-sizing:border-box}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input label{font-size:.75em;padding:4px 6px 0;color:#555;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input{width:100%;box-sizing:border-box;border:0;box-shadow:none;margin:0;padding:0 6px 4px;color:#555;background:0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input::-webkit-input-placeholder{color:#ddd}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child{border-bottom:1px dashed #ddd;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child label{color:#ccc}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .view{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .edit{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes label{display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount{display:block;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{margin-right:.25em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input{text-align:center;width:50px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items span.subtotal{opacity:.5}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.tax_class,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.tax_class{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .calculated{border-color:#ae8ca2;border-style:dotted}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{margin:.5em 0 0;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{color:#ccc;top:0;left:0;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-align:center;font-family:WooCommerce}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr th{border:0;padding:0 4px .5em 0;line-height:1.5em;width:20%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td{padding:0 4px .5em 0;border:0;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input{width:100%;margin:0;position:relative;border-bottom:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .refund_by,ul.order_notes li p.meta .exact-date{border-bottom:1px dotted #999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td textarea{width:100%;height:4em;margin:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input:focus+textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input:focus+textarea{border-top-color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p{margin:0 0 .5em;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p:last-child{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method_name{width:100%;margin:0 0 .5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;float:right;font-size:14px;visibility:hidden;margin:3px -18px 0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:hover:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:hover:before{color:#a00}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax:hover .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax:hover .delete-order-tax{visibility:visible}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded{display:block;color:#a00;white-space:nowrap;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;width:100%;height:100%;text-align:center;content:"";position:relative;top:auto;left:auto;margin:-1px 4px 0 0;vertical-align:middle;line-height:1em}#woocommerce-order-items .wc-order-edit-line-item{padding-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions{width:44px;text-align:right;padding-left:0;vertical-align:middle}#woocommerce-order-items .wc-order-edit-line-item-actions a{color:#ccc;display:inline-block;cursor:pointer;padding:0 0 .5em;margin:0 0 0 12px;vertical-align:middle;text-decoration:none;line-height:16px;width:16px;overflow:hidden}#woocommerce-order-items .wc-order-edit-line-item-actions a:before{margin:0;padding:0;font-size:16px;width:16px;height:16px}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before,#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{font-family:Dashicons;-webkit-font-smoothing:antialiased;text-indent:0;top:0;left:0;width:100%;height:100%;margin:0;text-align:center;position:relative;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1}#woocommerce-order-items .wc-order-edit-line-item-actions a:hover:before{color:#999}#woocommerce-order-items .wc-order-edit-line-item-actions a:first-child{margin-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:hover:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:hover:before{color:#a00}#woocommerce-order-items tbody tr .wc-order-edit-line-item-actions{visibility:hidden}#woocommerce-order-items tbody tr:hover .wc-order-edit-line-item-actions{visibility:visible}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions{width:1.5em;visibility:visible!important}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions a{padding:0}#woocommerce-order-downloads .buttons{float:left;padding:0;margin:0;vertical-align:top}#woocommerce-order-downloads .buttons .add_item_id,#woocommerce-order-downloads .buttons .select2-container{width:400px!important;margin-right:9px;vertical-align:top;float:left}#woocommerce-order-downloads .buttons button{margin:2px 0 0}#woocommerce-order-downloads h3 small{color:#999}#poststuff #woocommerce-order-actions .inside{margin:0;padding:0}#poststuff #woocommerce-order-actions .inside ul.order_actions li{padding:6px 10px;box-sizing:border-box}#poststuff #woocommerce-order-actions .inside ul.order_actions li:last-child{border-bottom:0}#poststuff #woocommerce-order-notes .inside{margin:0;padding:0}#poststuff #woocommerce-order-notes .inside ul.order_notes li{padding:0 10px}#woocommerce_customers p.search-box{margin:6px 0 4px;float:left}#woocommerce_customers .tablenav{float:right;clear:none}.widefat.customers td{vertical-align:middle;padding:4px 7px}.widefat .column-order_title{width:15%}.widefat .column-order_title time{display:block;color:#999;margin:3px 0}.widefat .column-orders,.widefat .column-paying,.widefat .column-spent{text-align:center;width:8%}.widefat .column-last_order{width:11%}.widefat .column-order_actions,.widefat .column-user_actions,.widefat .column-wc_actions{width:110px}.widefat .column-order_actions a.button,.widefat .column-user_actions a.button,.widefat .column-wc_actions a.button{float:left;margin:0 4px 2px 0;cursor:pointer;padding:3px 4px;height:auto}.widefat .column-order_actions a.button img,.widefat .column-user_actions a.button img,.widefat .column-wc_actions a.button img{display:block;width:12px;height:auto}.widefat small.meta{display:block;color:#999;font-size:inherit;margin:3px 0}.widefat .column-order_date,.widefat .column-order_total{width:9%}.widefat .column-order_status{width:45px;text-align:center}.widefat .column-order_status mark{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;background:0 0;font-size:1.4em;margin:0 auto}.widefat .column-order_status mark.cancelled:after,.widefat .column-order_status mark.completed:after,.widefat .column-order_status mark.failed:after,.widefat .column-order_status mark.on-hold:after,.widefat .column-order_status mark.pending:after,.widefat .column-order_status mark.processing:after,.widefat .column-order_status mark.refunded:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.column-customer_message .note-on:after,.column-order_notes .note-on:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;left:0;text-align:center;line-height:16px;font-family:WooCommerce}.widefat .column-order_status mark.pending:after{content:"\e012";color:#ffba00}.widefat .column-order_status mark.completed:after{content:"\e015";color:#2ea2cc}.widefat .column-order_status mark.on-hold:after{content:"\e033";color:#999}.widefat .column-order_status mark.failed:after{content:"\e016";color:#d0c21f}.widefat .column-order_status mark.cancelled:after{content:"\e013";color:#a00}.widefat .column-order_status mark.processing:after{content:"\e011";color:#73a724}.widefat .column-order_status mark.refunded:after{content:"\e014";color:#999}.widefat td.column-order_status{padding-top:9px}.column-customer_message .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-customer_message .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.column-order_notes .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-order_notes .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.order_actions .complete,.order_actions .processing,.order_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.order_actions .processing:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.order_actions .complete:after,.order_actions .view:after{font-family:Dashicons;text-indent:0;position:absolute;width:100%;height:100%;left:0;line-height:1.85;margin:0;text-align:center;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;font-weight:400}.order_actions .complete:after{content:""}.order_actions .view:after{content:""}.user_actions .edit,.user_actions .link,.user_actions .refresh,.user_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.user_actions .edit:after,.user_actions .link:after,.user_actions .refresh:after,.user_actions .view:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.user_actions .edit:after{font-family:Dashicons;content:"\f464"}.user_actions .link:after{content:"\e00d"}.user_actions .view:after{content:"\e010"}.user_actions .refresh:after{content:"\e031"}.attributes-table td,.attributes-table th{width:15%;vertical-align:top}.attributes-table .attribute-terms{width:32%}.attributes-table .attribute-actions{width:2em}.attributes-table .attribute-actions .configure-terms{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.attributes-table .attribute-actions .configure-terms:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}ul.order_notes{padding:2px 0 0}ul.order_notes li .note_content{padding:10px;background:#efefef;position:relative}ul.order_notes li .note_content p{margin:0;padding:0;word-wrap:break-word}ul.order_notes li p.meta{padding:10px;color:#999;margin:0;font-size:11px}ul.order_notes li a.delete_note{color:#a00}table.wp-list-table .row-actions,table.wp-list-table span.na{color:#999}ul.order_notes li .note_content:after{content:"";display:block;position:absolute;bottom:-10px;left:20px;width:0;height:0;border-width:10px 10px 0 0;border-style:solid;border-color:#efefef transparent}ul.order_notes li.customer-note .note_content{background:#A7CEDC}ul.order_notes li.customer-note .note_content:after{border-color:#A7CEDC transparent}ul.order_notes li.system-note .note_content{background:#d7cad2}ul.order_notes li.system-note .note_content:after{border-color:#d7cad2 transparent}.add_note{border-top:1px solid #ddd;padding:10px 10px 0}.add_note h4{margin-top:5px!important}.add_note #add_order_note{width:100%;height:50px}table.wp-list-table .column-thumb{width:52px;text-align:center;white-space:nowrap}table.wp-list-table .column-name{width:22%}table.wp-list-table .column-product_cat,table.wp-list-table .column-product_tag{width:11%!important}table.wp-list-table .column-featured,table.wp-list-table .column-product_type{width:48px;text-align:left!important}table.wp-list-table .column-customer_message,table.wp-list-table .column-order_notes{width:48px;text-align:center}table.wp-list-table .column-customer_message img,table.wp-list-table .column-order_notes img{margin:0 auto;padding-top:0!important}table.wp-list-table .manage-column.column-featured img,table.wp-list-table .manage-column.column-product_type img{padding-left:2px}table.wp-list-table .column-price .woocommerce-price-suffix{display:none}table.wp-list-table img{margin:1px 2px}table.wp-list-table td.column-thumb img{margin:0;width:auto;height:auto;max-width:40px;max-height:40px;vertical-align:middle}table.wp-list-table .column-is_in_stock{text-align:left!important}table.wp-list-table span.wc-featured,table.wp-list-table span.wc-image,table.wp-list-table span.wc-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table span.wc-featured:before,table.wp-list-table span.wc-image:before,table.wp-list-table span.wc-type:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:""}table.wp-list-table span.wc-featured{margin:0;cursor:pointer}table.wp-list-table span.wc-featured:before{content:"\f155"}table.wp-list-table span.wc-featured.not-featured:before{content:"\f154"}table.wp-list-table td.column-featured span.wc-featured{font-size:1.6em}table.wp-list-table span.wc-type{margin:0}table.wp-list-table span.wc-type:before{font-family:WooCommerce;content:"\e006"}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after,table.wp-list-table span.product-type:before{font-family:WooCommerce;text-align:center;line-height:1;top:0;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;left:0}table.wp-list-table span.product-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.6em}table.wp-list-table span.product-type:before{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}table.wp-list-table span.product-type.grouped:before{content:"\e002"}table.wp-list-table span.product-type.external:before{content:"\e034"}table.wp-list-table span.product-type.variable:before{content:"\e003"}table.wp-list-table span.product-type.downloadable:before{content:"\e001"}table.wp-list-table span.product-type.virtual:before{content:"\e000"}table.wp-list-table mark.instock{font-weight:700;color:#7ad03a;background:0 0;line-height:1}table.wp-list-table mark.outofstock{font-weight:700;color:#a44;background:0 0;line-height:1}table.wp-list-table .notes_head,table.wp-list-table .order-notes_head,table.wp-list-table .status_head{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%}table.wc_emails .wc-email-settings-table-name,table.wc_emails td.name,table.wc_gateways .wc-email-settings-table-name,table.wc_gateways td.name,table.wc_shipping .wc-email-settings-table-name,table.wc_shipping td.name{font-weight:700}table.wp-list-table .order-notes_head:after{content:"\e028"}table.wp-list-table .notes_head:after{content:"\e026"}table.wp-list-table .status_head:after{content:"\e011"}table.wp-list-table .column-order_items{width:12%}table.wp-list-table .column-order_items table.order_items{width:100%;margin:3px 0 0;padding:0;display:none}table.wp-list-table .column-order_items table.order_items td{border:0;margin:0;padding:0 0 3px}table.wp-list-table .column-order_items table.order_items td.qty{color:#999;padding-right:6px;text-align:left}mark.notice{background:#fff;color:#a00;margin:0 0 0 10px}a.export_rates,a.import_rates{float:right;margin-left:9px;margin-top:-2px;margin-bottom:0}#rates-search{float:right}#rates-search input.wc-tax-rates-search-field{padding:4px 8px;font-size:1.2em}#rates-pagination{float:right;margin-right:.5em}#rates-pagination .tablenav{margin:0}table.wc_input_table,table.wc_tax_rates{width:100%}table.wc_input_table span.tips,table.wc_tax_rates span.tips{color:#2ea2cc}table.wc_input_table th,table.wc_tax_rates th{white-space:nowrap;padding:10px}table.wc_input_table td,table.wc_tax_rates td{padding:0;border-right:1px solid #DFDFDF;border-bottom:1px solid #DFDFDF;border-top:0;background:#fff;cursor:default}table.wc_input_table td input[type=text],table.wc_input_table td input[type=number],table.wc_tax_rates td input[type=text],table.wc_tax_rates td input[type=number]{width:100%;padding:8px 10px;margin:0;border:0;outline:0;background:0 0}table.wc_input_table td input[type=text]:focus,table.wc_input_table td input[type=number]:focus,table.wc_tax_rates td input[type=text]:focus,table.wc_tax_rates td input[type=number]:focus{outline:0;box-shadow:none}table.wc_input_table td.apply_to_shipping,table.wc_input_table td.compound,table.wc_tax_rates td.apply_to_shipping,table.wc_tax_rates td.compound{padding:5px 7px;vertical-align:middle}table.wc_input_table td.apply_to_shipping input,table.wc_input_table td.compound input,table.wc_tax_rates td.apply_to_shipping input,table.wc_tax_rates td.compound input{width:auto;padding:0}table.wc_input_table td:last-child,table.wc_tax_rates td:last-child{border-right:0}table.wc_input_table tr.current td,table.wc_tax_rates tr.current td{background-color:#fefbcc}table.wc_input_table .cost,table.wc_input_table .cost input,table.wc_input_table .item_cost,table.wc_input_table .item_cost input,table.wc_tax_rates .cost,table.wc_tax_rates .cost input,table.wc_tax_rates .item_cost,table.wc_tax_rates .item_cost input{text-align:right}table.wc_input_table th.sort,table.wc_tax_rates th.sort{width:17px;padding:0 4px}table.wc_input_table td.sort,table.wc_tax_rates td.sort{padding:0 4px}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort{cursor:move;font-size:15px;background:#f9f9f9;text-align:center;vertical-align:middle}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before{color:#333}table.wc_input_table .button,table.wc_tax_rates .button{float:left;margin-right:5px}table.wc_input_table .export,table.wc_input_table .import,table.wc_tax_rates .export,table.wc_tax_rates .import{float:right;margin-right:0;margin-left:5px}table.wc_input_table span.tips,table.wc_tax_rates span.tips{padding:0 3px}table.wc_input_table .pagination,table.wc_tax_rates .pagination{float:right}table.wc_input_table .pagination .button,table.wc_tax_rates .pagination .button{margin-left:5px;margin-right:0}table.wc_input_table .pagination .current,table.wc_tax_rates .pagination .current{background:#bbb;text-shadow:none}table.wc_input_table tr:last-child td,table.wc_tax_rates tr:last-child td{border-bottom:0}table.wc_emails,table.wc_gateways,table.wc_shipping{position:relative}table.wc_emails td,table.wc_gateways td,table.wc_shipping td{vertical-align:middle;padding:7px;line-height:2em}table.wc_emails tr:nth-child(odd) td,table.wc_gateways tr:nth-child(odd) td,table.wc_shipping tr:nth-child(odd) td{background:#f9f9f9}table.wc_emails th,table.wc_gateways th,table.wc_shipping th{padding:9px 7px!important;vertical-align:middle}table.wc_emails .settings,table.wc_gateways .settings,table.wc_shipping .settings{text-align:right}table.wc_emails .default,table.wc_emails .radio,table.wc_emails .status,table.wc_gateways .default,table.wc_gateways .radio,table.wc_gateways .status,table.wc_shipping .default,table.wc_shipping .radio,table.wc_shipping .status{text-align:center}table.wc_emails .default .tips,table.wc_emails .radio .tips,table.wc_emails .status .tips,table.wc_gateways .default .tips,table.wc_gateways .radio .tips,table.wc_gateways .status .tips,table.wc_shipping .default .tips,table.wc_shipping .radio .tips,table.wc_shipping .status .tips{margin:0 auto}table.wc_emails .default input,table.wc_emails .radio input,table.wc_emails .status input,table.wc_gateways .default input,table.wc_gateways .radio input,table.wc_gateways .status input,table.wc_shipping .default input,table.wc_shipping .radio input,table.wc_shipping .status input{margin:0}table.wc_emails th.sort,table.wc_gateways th.sort,table.wc_shipping th.sort{width:28px;padding:0}table.wc_emails td.sort,table.wc_gateways td.sort,table.wc_shipping td.sort{padding:0 7px;cursor:move;font-size:15px;text-align:center;vertical-align:middle}table.wc_emails td.sort:before,table.wc_gateways td.sort:before,table.wc_shipping td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_emails .wc-email-settings-table-name span,table.wc_gateways .wc-email-settings-table-name span,table.wc_shipping .wc-email-settings-table-name span{font-weight:400;color:#999;margin:0 0 0 4px!important}table.wc_emails .wc-email-settings-table-status,table.wc_gateways .wc-email-settings-table-status,table.wc_shipping .wc-email-settings-table-status{text-align:center;width:1em}table.wc_emails .wc-email-settings-table-status .tips,table.wc_gateways .wc-email-settings-table-status .tips,table.wc_shipping .wc-email-settings-table-status .tips{margin:0 auto}table.wc_emails .wc-email-settings-table-actions a,table.wc_gateways .wc-email-settings-table-actions a,table.wc_shipping .wc-email-settings-table-actions a{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}table.wc_emails .wc-email-settings-table-actions a:after,table.wc_gateways .wc-email-settings-table-actions a:after,table.wc_shipping .wc-email-settings-table-actions a:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}table.wc-shipping-classes td,table.wc-shipping-classes th,table.wc-shipping-zone-methods td,table.wc-shipping-zone-methods th,table.wc-shipping-zones td,table.wc-shipping-zones th{vertical-align:top;line-height:24px;padding:1em;font-size:14px;background:#fff}table.wc-shipping-classes td li,table.wc-shipping-classes th li,table.wc-shipping-zone-methods td li,table.wc-shipping-zone-methods th li,table.wc-shipping-zones td li,table.wc-shipping-zones th li{line-height:24px;font-size:14px}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state,table.wc-shipping-classes td.wc-shipping-zones-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state,table.wc-shipping-zones td.wc-shipping-zones-blank-state{background:#F7F1F6!important;overflow:hidden;position:relative;padding:7.5em 7.5%;border-bottom:2px solid #EEE2EC}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zones td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state p{color:#a46497;font-size:1.5em;line-height:1.5em;margin:0 0 1em;position:relative;z-index:1;text-shadow:1px 1px 1px #fff}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state p.main{font-size:2em}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state li{margin-left:1em;list-style:circle inside}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-classes td.wc-shipping-zones-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state:before,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zones td.wc-shipping-zones-blank-state:before{content:"\e01b";font-family:WooCommerce;text-align:center;line-height:1;color:#EEE2EC;display:block;width:1em;font-size:40em;top:50%;right:-3.75%;margin-top:-.1875em;position:absolute}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-classes td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zones-blank-state .button-primary{background-color:#804877;border-color:#804877;-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);margin:0;opacity:1;text-shadow:0 -1px 1px #8a4f7f,1px 0 1px #8a4f7f,0 1px 1px #8a4f7f,-1px 0 1px #8a4f7f;font-size:1.5em;padding:.75em 1em;height:auto;position:relative;z-index:1}table.wc-shipping-classes .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-classes .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-classes tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-classes tr.odd td,table.wc-shipping-zone-methods .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tr.odd td,table.wc-shipping-zones .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zones .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zones tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zones tr.odd td{background:#f9f9f9}table.wc-shipping-classes p,table.wc-shipping-classes ul,table.wc-shipping-zone-methods p,table.wc-shipping-zone-methods ul,table.wc-shipping-zones p,table.wc-shipping-zones ul{margin:0}table.wc-shipping-classes td.wc-shipping-zone-method-sort,table.wc-shipping-classes td.wc-shipping-zone-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-sort,table.wc-shipping-zones td.wc-shipping-zone-method-sort,table.wc-shipping-zones td.wc-shipping-zone-sort{cursor:move;font-size:15px;text-align:center}table.wc-shipping-classes td.wc-shipping-zone-method-sort:before,table.wc-shipping-classes td.wc-shipping-zone-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:before,table.wc-shipping-zones td.wc-shipping-zone-sort:before{content:"\f333";font-family:Dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-classes td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-sort:hover:before{color:#333}table.wc-shipping-classes td.wc-shipping-zone-worldwide,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide,table.wc-shipping-zones td.wc-shipping-zone-worldwide{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-worldwide:before,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide:before,table.wc-shipping-zones td.wc-shipping-zone-worldwide:before{content:"\f319";font-family:dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes .wc-shipping-zone-methods,table.wc-shipping-classes .wc-shipping-zone-name,table.wc-shipping-zone-methods .wc-shipping-zone-methods,table.wc-shipping-zone-methods .wc-shipping-zone-name,table.wc-shipping-zones .wc-shipping-zone-methods,table.wc-shipping-zones .wc-shipping-zone-name{width:25%}table.wc-shipping-classes .wc-shipping-class-description input,table.wc-shipping-classes .wc-shipping-class-description select,table.wc-shipping-classes .wc-shipping-class-description textarea,table.wc-shipping-classes .wc-shipping-class-name input,table.wc-shipping-classes .wc-shipping-class-name select,table.wc-shipping-classes .wc-shipping-class-name textarea,table.wc-shipping-classes .wc-shipping-class-slug input,table.wc-shipping-classes .wc-shipping-class-slug select,table.wc-shipping-classes .wc-shipping-class-slug textarea,table.wc-shipping-classes .wc-shipping-zone-name input,table.wc-shipping-classes .wc-shipping-zone-name select,table.wc-shipping-classes .wc-shipping-zone-name textarea,table.wc-shipping-classes .wc-shipping-zone-region input,table.wc-shipping-classes .wc-shipping-zone-region select,table.wc-shipping-classes .wc-shipping-zone-region textarea,table.wc-shipping-zone-methods .wc-shipping-class-description input,table.wc-shipping-zone-methods .wc-shipping-class-description select,table.wc-shipping-zone-methods .wc-shipping-class-description textarea,table.wc-shipping-zone-methods .wc-shipping-class-name input,table.wc-shipping-zone-methods .wc-shipping-class-name select,table.wc-shipping-zone-methods .wc-shipping-class-name textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug input,table.wc-shipping-zone-methods .wc-shipping-class-slug select,table.wc-shipping-zone-methods .wc-shipping-class-slug textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name input,table.wc-shipping-zone-methods .wc-shipping-zone-name select,table.wc-shipping-zone-methods .wc-shipping-zone-name textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region input,table.wc-shipping-zone-methods .wc-shipping-zone-region select,table.wc-shipping-zone-methods .wc-shipping-zone-region textarea,table.wc-shipping-zones .wc-shipping-class-description input,table.wc-shipping-zones .wc-shipping-class-description select,table.wc-shipping-zones .wc-shipping-class-description textarea,table.wc-shipping-zones .wc-shipping-class-name input,table.wc-shipping-zones .wc-shipping-class-name select,table.wc-shipping-zones .wc-shipping-class-name textarea,table.wc-shipping-zones .wc-shipping-class-slug input,table.wc-shipping-zones .wc-shipping-class-slug select,table.wc-shipping-zones .wc-shipping-class-slug textarea,table.wc-shipping-zones .wc-shipping-zone-name input,table.wc-shipping-zones .wc-shipping-zone-name select,table.wc-shipping-zones .wc-shipping-zone-name textarea,table.wc-shipping-zones .wc-shipping-zone-region input,table.wc-shipping-zones .wc-shipping-zone-region select,table.wc-shipping-zones .wc-shipping-zone-region textarea{width:100%}table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-zone-delete{color:red}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle{float:right;margin:0;font-size:.9em;text-decoration:underline}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes{display:none}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea{margin-top:1em}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes .description{font-size:.9em;color:#999}table.wc-shipping-classes .wc-shipping-class-count,table.wc-shipping-zone-methods .wc-shipping-class-count,table.wc-shipping-zones .wc-shipping-class-count{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-methods,table.wc-shipping-zone-methods td.wc-shipping-zone-methods,table.wc-shipping-zones td.wc-shipping-zone-methods{color:#999}table.wc-shipping-classes td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .method_disabled{text-decoration:line-through}table.wc-shipping-classes td.wc-shipping-zone-methods ul,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul,table.wc-shipping-zones td.wc-shipping-zone-methods ul{color:#999;position:relative;padding-right:32px}table.wc-shipping-classes td.wc-shipping-zone-methods ul li,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li,table.wc-shipping-zones td.wc-shipping-zone-methods ul li{display:inline;margin:0}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:before{content:", "}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-classes td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:nth-child(2):before{content:""}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child{display:block}table.wc-shipping-classes td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zones td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row{position:absolute;right:0;top:0}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method{display:block;width:24px;padding:24px 0 0;height:0;overflow:hidden;cursor:pointer}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method:before{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;font-family:Dashicons;content:"\f502";color:#999;vertical-align:middle;line-height:24px;font-size:16px;margin:0}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled:before{line-height:inherit}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled{margin-top:1px;display:inline-block}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled{cursor:not-allowed}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled:before{color:#ccc}table.wc-shipping-classes .wc-shipping-zone-method-title,table.wc-shipping-zone-methods .wc-shipping-zone-method-title,table.wc-shipping-zones .wc-shipping-zone-method-title{width:33%}table.wc-shipping-classes .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zone-methods .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zones .wc-shipping-zone-method-title .wc-shipping-zone-method-delete{color:red}table.wc-shipping-classes .wc-shipping-zone-method-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled{text-align:center}table.wc-shipping-classes tfoot input,table.wc-shipping-classes tfoot select,table.wc-shipping-zone-methods tfoot input,table.wc-shipping-zone-methods tfoot select,table.wc-shipping-zones tfoot input,table.wc-shipping-zones tfoot select{vertical-align:middle!important}table.wc-shipping-classes tfoot .button-secondary,table.wc-shipping-zone-methods tfoot .button-secondary,table.wc-shipping-zones tfoot .button-secondary{float:right}table.wc-shipping-classes .editing .wc-shipping-zone-edit,table.wc-shipping-classes .editing .wc-shipping-zone-view,table.wc-shipping-zone-methods .editing .wc-shipping-zone-edit,table.wc-shipping-zone-methods .editing .wc-shipping-zone-view,table.wc-shipping-zones .editing .wc-shipping-zone-edit,table.wc-shipping-zones .editing .wc-shipping-zone-view{display:none}.wc-modal-shipping-method-settings{background:#f8f8f8;padding:1em!important}.wc-modal-shipping-method-settings form .form-table{width:100%;background:#fff;margin:0 0 1.5em}.wc-modal-shipping-method-settings form .form-table tr th{width:30%;position:relative}.wc-modal-shipping-method-settings form .form-table tr th .woocommerce-help-tip{float:right;margin:-8px -.5em 0 0;vertical-align:middle;right:0;top:50%;position:absolute}.wc-modal-shipping-method-settings form .form-table tr td input,.wc-modal-shipping-method-settings form .form-table tr td select,.wc-modal-shipping-method-settings form .form-table tr td textarea{width:50%;min-width:250px}.wc-modal-shipping-method-settings form .form-table tr td input[type=checkbox]{width:auto;min-width:16px}.wc-modal-shipping-method-settings form .form-table tr td,.wc-modal-shipping-method-settings form .form-table tr th{vertical-align:middle;margin:0;line-height:24px;padding:1em;border-bottom:1px solid #f8f8f8}.wc-modal-shipping-method-settings form .form-table:last-of-type{margin-bottom:0}.wc-backbone-modal .wc-shipping-zone-method-selector p{margin-top:0}.wc-backbone-modal .wc-shipping-zone-method-selector .wc-shipping-zone-method-description{margin:.75em 1px 0;line-height:1.5em;color:#999;font-style:italic}.wc-backbone-modal .wc-shipping-zone-method-selector select{width:100%;cursor:pointer}img.help_tip{margin:0 0 0 9px;vertical-align:middle}.postbox img.help_tip{margin-top:0}.postbox .woocommerce-help-tip{margin:0 0 0 9px}.status-disabled,.status-enabled,.status-manual{font-size:1.4em;display:block;text-indent:-9999px;position:relative;height:1em;width:1em}.status-disabled:before,.status-enabled:before,.status-manual:before{font-family:WooCommerce;line-height:1;margin:0;position:absolute;width:100%;height:100%;text-indent:0;top:0;font-variant:normal;-webkit-font-smoothing:antialiased;font-weight:400;text-align:center;left:0;speak:none;text-transform:none}.status-manual:before{content:"";color:#999}.status-enabled:before{content:"";color:#a46497}.status-disabled:before{content:"";color:#ccc}.woocommerce h2.woo-nav-tab-wrapper{margin-bottom:1em}.woocommerce nav.woo-nav-tab-wrapper{margin:1.5em 0 1em;border-bottom:1px solid #ccc}.woocommerce .subsubsub{margin:-8px 0 0}.woocommerce .wc-admin-breadcrumb{margin-left:.5em}.woocommerce .wc-admin-breadcrumb a{color:#a46497}.woocommerce #template div{margin:0}.woocommerce #template div p .button{float:right;margin-left:10px;margin-top:-4px}.woocommerce #template div .editor textarea{margin-bottom:8px}.woocommerce textarea[disabled=disabled]{background:#DFDFDF!important}.woocommerce table.form-table{margin:0;position:relative}.woocommerce table.form-table .forminp-radio ul{margin:0}.woocommerce table.form-table .forminp-radio ul li{line-height:1.4em}.woocommerce table.form-table textarea.input-text{height:100%;min-width:150px;display:block}.woocommerce table.form-table input.regular-input{width:25em}.woocommerce table.form-table textarea.wide-input{width:100%}.woocommerce table.form-table .woocommerce-help-tip,.woocommerce table.form-table img.help_tip{padding:0;margin:-4px 0 0 5px;vertical-align:middle;cursor:help;line-height:1}.woocommerce table.form-table span.help_tip{cursor:help;color:#2ea2cc}.woocommerce table.form-table th{position:relative;padding-right:24px}.woocommerce table.form-table .select2-container{display:block;max-width:350px;vertical-align:top;margin-bottom:3px}.woocommerce table.form-table table.widefat th{padding-right:inherit}.woocommerce table.form-table th .woocommerce-help-tip,.woocommerce table.form-table th img.help_tip{margin:0 -24px 0 0;float:right}.woocommerce table.form-table .wp-list-table .woocommerce-help-tip{float:none}.woocommerce table.form-table fieldset{margin-top:4px}.woocommerce table.form-table fieldset .woocommerce-help-tip,.woocommerce table.form-table fieldset img.help_tip{margin:-3px 0 0 5px}.woocommerce table.form-table fieldset p.description{margin-bottom:8px}.woocommerce table.form-table fieldset:first-child{margin-top:0}.woocommerce table.form-table .iris-picker{z-index:100;display:none;position:absolute;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,.2)}.woocommerce table.form-table .iris-picker .ui-slider{border:0!important;margin:0!important;width:auto!important;height:auto!important;background:none!important}.woocommerce table.form-table .iris-picker .ui-slider .ui-slider-handle{margin-bottom:0!important}.woocommerce table.form-table .colorpickpreview{padding:3px 3px 3px 20px;border:1px solid #ddd;border-right:0}.woocommerce table.form-table .colorpick{border-left:0}.woocommerce table.form-table .image_width_settings{vertical-align:middle}.woocommerce table.form-table .image_width_settings label{margin-left:10px}.woocommerce table.form-table .wc_emails_wrapper{padding:0 15px 10px 0}.woocommerce #tabs-wrap table a.remove{margin-left:4px}.woocommerce #tabs-wrap table p{margin:0 0 4px!important;overflow:hidden;zoom:1}.woocommerce #tabs-wrap table p a.add{float:left}#wp-excerpt-editor-container{background:#fff}#product_variation-parent #parent_id{width:100%}#postimagediv img{border:1px solid #d5d5d5;max-width:100%}#woocommerce-product-images .inside{margin:0;padding:0}#woocommerce-product-images .inside .add_product_images{padding:0 12px 12px}#woocommerce-product-images .inside #product_images_container{padding:0 0 0 9px}#woocommerce-product-images .inside #product_images_container ul{margin:0;padding:0}#woocommerce-product-images .inside #product_images_container ul:after,#woocommerce-product-images .inside #product_images_container ul:before{content:" ";display:table}#woocommerce-product-images .inside #product_images_container ul:after{clear:both}#woocommerce-product-images .inside #product_images_container ul li.add,#woocommerce-product-images .inside #product_images_container ul li.image,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{width:80px;float:left;cursor:move;border:1px solid #d5d5d5;margin:9px 9px 0 0;background:#f7f7f7;border-radius:2px;position:relative;box-sizing:border-box}#woocommerce-product-images .inside #product_images_container ul li.add img,#woocommerce-product-images .inside #product_images_container ul li.image img,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder img{width:100%;height:auto;display:block}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{border:3px dashed #ddd;position:relative}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-size:2.618em;line-height:72px;color:#ddd}#woocommerce-product-images .inside #product_images_container ul ul.actions{position:absolute;top:-8px;right:-8px;padding:2px;display:none}#woocommerce-product-images .inside #product_images_container ul ul.actions li{float:right;margin:0 0 0 2px}#woocommerce-product-images .inside #product_images_container ul ul.actions li a{width:1em;margin:0;height:0;display:block;overflow:hidden}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.tips{cursor:pointer}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.4em}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:hover:before{color:#a00}#woocommerce-product-images .inside #product_images_container ul li:hover ul.actions{display:block}#woocommerce-product-data .hndle{padding:10px}#woocommerce-product-data .hndle span{display:block;vertical-align:middle;line-height:24px}#woocommerce-product-data .hndle span span{display:inline;line-height:inherit;vertical-align:baseline}#woocommerce-product-data .hndle label{padding-right:1em;font-size:12px;vertical-align:baseline}#woocommerce-product-data .hndle label:first-child{margin-right:1em;border-right:1px solid #dfdfdf}#woocommerce-product-data .hndle input,#woocommerce-product-data .hndle select{margin:-3px 0 0 .5em;vertical-align:middle}#woocommerce-product-data>.handlediv{margin-top:4px}#woocommerce-product-data .wrap{margin:0}#woocommerce-coupon-description{padding:3px 8px;font-size:1.7em;line-height:1.42em;height:auto;width:100%;outline:0;margin:10px 0;display:block}#woocommerce-coupon-description::-webkit-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description::-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-ms-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap{background:#fff}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{float:left;width:80%}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-product-data .woocommerce_options_panel .wc-radios{display:block;float:left;margin:0}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-product-data .woocommerce_options_panel .wc-radios li{display:block;padding:0 0 10px}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li input,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-product-data .woocommerce_options_panel .wc-radios li input{width:auto}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap,.woocommerce .panel-wrap{overflow:hidden}#woocommerce-coupon-data ul.wc-tabs,#woocommerce-product-data ul.wc-tabs,.woocommerce ul.wc-tabs{margin:0;width:20%;float:left;line-height:1em;padding:0 0 10px;position:relative;background-color:#fafafa;border-right:1px solid #eee;box-sizing:border-box}#woocommerce-coupon-data ul.wc-tabs:after,#woocommerce-product-data ul.wc-tabs:after,.woocommerce ul.wc-tabs:after{content:"";display:block;width:100%;height:9999em;position:absolute;bottom:-9999em;left:0;background-color:#fafafa;border-right:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li,#woocommerce-product-data ul.wc-tabs li,.woocommerce ul.wc-tabs li{margin:0;padding:0;display:block;position:relative}#woocommerce-coupon-data ul.wc-tabs li a,#woocommerce-product-data ul.wc-tabs li a,.woocommerce ul.wc-tabs li a{margin:0;padding:10px;display:block;box-shadow:none;text-decoration:none;line-height:20px!important;border-bottom:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li a:before,#woocommerce-product-data ul.wc-tabs li a:before,.woocommerce ul.wc-tabs li a:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}#woocommerce-coupon-data ul.wc-tabs li.general_options a:before,#woocommerce-product-data ul.wc-tabs li.general_options a:before,.woocommerce ul.wc-tabs li.general_options a:before{content:"\f107"}#woocommerce-coupon-data ul.wc-tabs li.inventory_options a:before,#woocommerce-product-data ul.wc-tabs li.inventory_options a:before,.woocommerce ul.wc-tabs li.inventory_options a:before{content:"\f481"}#woocommerce-coupon-data ul.wc-tabs li.shipping_options a:before,#woocommerce-product-data ul.wc-tabs li.shipping_options a:before,.woocommerce ul.wc-tabs li.shipping_options a:before{font-family:WooCommerce;content:"\e01a"}#woocommerce-coupon-data ul.wc-tabs li.linked_product_options a:before,#woocommerce-product-data ul.wc-tabs li.linked_product_options a:before,.woocommerce ul.wc-tabs li.linked_product_options a:before{content:"\f103"}#woocommerce-coupon-data ul.wc-tabs li.attribute_options a:before,#woocommerce-product-data ul.wc-tabs li.attribute_options a:before,.woocommerce ul.wc-tabs li.attribute_options a:before{content:"\f175"}#woocommerce-coupon-data ul.wc-tabs li.advanced_options a:before,#woocommerce-product-data ul.wc-tabs li.advanced_options a:before,.woocommerce ul.wc-tabs li.advanced_options a:before{font-family:Dashicons;content:"\f111"}#woocommerce-coupon-data ul.wc-tabs li.variations_options a:before,#woocommerce-product-data ul.wc-tabs li.variations_options a:before,.woocommerce ul.wc-tabs li.variations_options a:before{content:"\f509"}#woocommerce-coupon-data ul.wc-tabs li.usage_restriction_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_restriction_options a:before,.woocommerce ul.wc-tabs li.usage_restriction_options a:before{font-family:WooCommerce;content:"\e602"}#woocommerce-coupon-data ul.wc-tabs li.usage_limit_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_limit_options a:before,.woocommerce ul.wc-tabs li.usage_limit_options a:before{font-family:WooCommerce;content:"\e601"}#woocommerce-coupon-data ul.wc-tabs li.general_coupon_data a:before,#woocommerce-product-data ul.wc-tabs li.general_coupon_data a:before,.woocommerce ul.wc-tabs li.general_coupon_data a:before{font-family:WooCommerce;content:"\e600"}#woocommerce-coupon-data ul.wc-tabs li.active a,#woocommerce-product-data ul.wc-tabs li.active a,.woocommerce ul.wc-tabs li.active a{color:#555;position:relative;background-color:#eee}.woocommerce_page_wc-settings .shippingrows th.check-column{padding-top:20px}.woocommerce_page_wc-settings .shippingrows tfoot th{padding-left:10px}.woocommerce_page_wc-settings .shippingrows .add.button:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}.woocommerce_page_wc-settings h3.wc-settings-sub-title{font-size:1.2em}#woocommerce-coupon-data .inside,#woocommerce-order-data .inside,#woocommerce-order-downloads .inside,#woocommerce-product-data .inside,#woocommerce-product-type-options .inside{margin:0;padding:0}.panel,.woocommerce_options_panel{padding:9px;color:#555}.panel .form-field .woocommerce-help-tip,.woocommerce_options_panel .form-field .woocommerce-help-tip{font-size:1.4em}.panel,.woocommerce_page_settings .woocommerce_options_panel{padding:0}#woocommerce-product-specs .inside,#woocommerce-product-type-options .panel{margin:0;padding:9px}#woocommerce-product-type-options .panel p,.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p{margin:0 0 9px;font-size:12px;padding:5px 9px;line-height:24px}#woocommerce-product-type-options .panel p:after,.woocommerce_options_panel fieldset.form-field:after,.woocommerce_options_panel p:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce_options_panel .checkbox,.woocommerce_variable_attributes .checkbox{width:auto;margin:3px 0;vertical-align:middle}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{width:100%;padding:0!important}.woocommerce_options_panel .downloadable_files table th,.woocommerce_variations .downloadable_files table th{padding:7px 0 7px 7px!important}.woocommerce_options_panel .downloadable_files table th.sort,.woocommerce_variations .downloadable_files table th.sort{width:17px;padding:7px!important}.woocommerce_options_panel .downloadable_files table th .woocommerce-help-tip,.woocommerce_variations .downloadable_files table th .woocommerce-help-tip{font-size:1.1em;margin-left:0}.woocommerce_options_panel .downloadable_files table td,.woocommerce_variations .downloadable_files table td{vertical-align:middle!important;padding:4px 0 4px 7px!important;position:relative}.woocommerce_options_panel .downloadable_files table td:last-child,.woocommerce_variations .downloadable_files table td:last-child{padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td input.input_text,.woocommerce_variations .downloadable_files table td input.input_text{width:100%;float:none;min-width:0;margin:1px 0}.woocommerce_options_panel .downloadable_files table td .upload_file_button,.woocommerce_variations .downloadable_files table td .upload_file_button{width:auto;float:right;cursor:pointer}.woocommerce_options_panel .downloadable_files table td .delete,.woocommerce_variations .downloadable_files table td .delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.2em}.woocommerce_options_panel .downloadable_files table td .delete:before,.woocommerce_variations .downloadable_files table td .delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}.woocommerce_options_panel .downloadable_files table td .delete:hover:before,.woocommerce_variations .downloadable_files table td .delete:hover:before{color:#a00}.woocommerce_options_panel .downloadable_files table td.sort,.woocommerce_variations .downloadable_files table td.sort{width:17px;cursor:move;font-size:15px;text-align:center;background:#f9f9f9;padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td.sort:before,.woocommerce_variations .downloadable_files table td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_options_panel .downloadable_files table td.sort:hover:before,.woocommerce_variations .downloadable_files table td.sort:hover:before{color:#333}.woocommerce_variation h3 .sort{width:17px;height:26px;cursor:move;float:right;font-size:15px;font-weight:400;margin-right:.5em;visibility:hidden;text-align:center;vertical-align:middle}.woocommerce_variation h3 .sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:28px;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_variation h3 .sort:hover:before{color:#777}.woocommerce_variation h3:hover .sort,.woocommerce_variation.ui-sortable-helper .sort{visibility:visible}.woocommerce_options_panel{min-height:175px;box-sizing:border-box}.woocommerce_options_panel .downloadable_files{padding:0 9px 0 162px;position:relative;margin:9px 0}.woocommerce_options_panel .downloadable_files label{position:absolute;left:0;margin:0 0 0 12px;line-height:24px}.woocommerce_options_panel p{margin:9px 0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px 5px 162px!important}.woocommerce_options_panel .sale_price_dates_fields .short:first-of-type{margin-bottom:1em}.woocommerce_options_panel .sale_price_dates_fields .short:nth-of-type(2){clear:left}.woocommerce_options_panel label,.woocommerce_options_panel legend{float:left;width:150px;padding:0;margin:0 0 0 -150px}.woocommerce_options_panel label .req,.woocommerce_options_panel legend .req{font-weight:700;font-style:normal;color:#a00}.woocommerce_options_panel .description{padding:0;margin:0 0 0 7px;clear:none;display:inline}.woocommerce_options_panel .description-block{margin-left:0;display:block}.woocommerce_options_panel input,.woocommerce_options_panel select,.woocommerce_options_panel textarea{margin:0}.woocommerce_options_panel textarea{height:3.5em;line-height:1.5em;vertical-align:top}.woocommerce_options_panel input[type=text],.woocommerce_options_panel input[type=number],.woocommerce_options_panel input[type=email],.woocommerce_options_panel input[type=password]{width:50%;float:left}.woocommerce_options_panel input.button{width:auto;margin-left:8px}.woocommerce_options_panel select{float:left}.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:50%}.woocommerce_options_panel .sized{width:auto!important;margin-right:6px}.woocommerce_options_panel .options_group{border-top:1px solid #fff;border-bottom:1px solid #eee}.woocommerce_options_panel .options_group:first-child{border-top:0}.woocommerce_options_panel .options_group:last-child{border-bottom:0}.woocommerce_options_panel .options_group fieldset{margin:9px 0;font-size:12px;padding:5px 9px;line-height:24px}.woocommerce_options_panel .options_group fieldset label{width:auto;float:none}.woocommerce_options_panel .options_group fieldset ul{float:left;width:50%;margin:0;padding:0}.woocommerce_options_panel .options_group fieldset ul li{margin:0;width:auto}.woocommerce_options_panel .options_group fieldset ul li input{width:auto;float:none;margin-right:4px}.woocommerce_options_panel .options_group fieldset ul.wc-radios label{margin-left:0}.woocommerce_options_panel .dimensions_field .wrap{display:block;width:50%}.woocommerce_options_panel .dimensions_field .wrap input{width:30.75%;margin-right:3.8%}.woocommerce_options_panel .dimensions_field .wrap .last{margin-right:0}.woocommerce_options_panel.padded{padding:1em}#woocommerce-product-data input.dp-applied,.woocommerce_options_panel .select2-container{float:left}#grouped_product_options,#simple_product_options,#virtual_product_options{padding:12px;font-style:italic;color:#666}.wc-metaboxes-wrapper .toolbar{margin:0!important;border-top:1px solid #fff;border-bottom:1px solid #eee;padding:9px 12px!important}.wc-metaboxes-wrapper .toolbar:first-child{border-top:0}.wc-metaboxes-wrapper .toolbar:last-child{border-bottom:0}.wc-metaboxes-wrapper .toolbar .add_variation{float:right;margin-left:5px}.wc-metaboxes-wrapper .toolbar .cancel-variation-changes,.wc-metaboxes-wrapper .toolbar .save-variation-changes{float:left;margin-right:5px}.wc-metaboxes-wrapper p.toolbar{overflow:hidden;zoom:1}.wc-metaboxes-wrapper .expand-close{margin-right:2px;color:#777;font-size:12px;font-style:italic}.wc-metaboxes-wrapper .expand-close a{background:0 0;padding:0;font-size:12px;text-decoration:none}.wc-metaboxes-wrapper#product_attributes .expand-close{float:right;line-height:28px}.wc-metaboxes-wrapper .fr,.wc-metaboxes-wrapper button.add_variable_attribute{float:right;margin:0 0 0 6px}.wc-metaboxes-wrapper .wc-metaboxes{border-bottom:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox-sortable-placeholder{border-color:#bbb;background-color:#f5f5f5;margin-bottom:9px;border-width:1px;border-style:dashed}.wc-metaboxes-wrapper .wc-metabox{background:#fff;border-bottom:1px solid #eee;margin:0!important}.wc-metaboxes-wrapper .wc-metabox select{font-weight:400}.wc-metaboxes-wrapper .wc-metabox:last-of-type{border-bottom:0}.wc-metaboxes-wrapper .wc-metabox .handlediv{width:27px}.wc-metaboxes-wrapper .wc-metabox .handlediv:before{content:"\f142"!important;cursor:pointer;display:inline-block;font:400 20px/1 Dashicons;line-height:.5!important;padding:8px 10px;position:relative;right:12px;top:0}.wc-metaboxes-wrapper .wc-metabox.closed{border-radius:3px}.wc-metaboxes-wrapper .wc-metabox.closed .handlediv:before{content:"\f140"!important}.wc-metaboxes-wrapper .wc-metabox.closed h3{border:0}.wc-metaboxes-wrapper .wc-metabox h3{margin:0!important;padding:.75em .75em .75em 1em!important;font-size:1em!important;overflow:hidden;zoom:1;cursor:move}.wc-metaboxes-wrapper .wc-metabox h3 a.delete,.wc-metaboxes-wrapper .wc-metabox h3 button{float:right}.wc-metaboxes-wrapper .wc-metabox h3 a.delete{color:red;font-weight:400;line-height:26px;text-decoration:none;position:relative;visibility:hidden}.wc-metaboxes-wrapper .wc-metabox h3 strong{line-height:26px;font-weight:700}.wc-metaboxes-wrapper .wc-metabox h3 select{font-family:sans-serif;max-width:20%;margin:.25em .25em .25em 0}.wc-metaboxes-wrapper .wc-metabox h3 .handlediv{background-position:6px 5px!important;visibility:hidden;height:26px}.wc-metaboxes-wrapper .wc-metabox h3.fixed{cursor:pointer!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3{cursor:pointer;padding:.5em .75em .5em 1em!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .handlediv,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .sort,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 a.delete{margin-top:.25em}.wc-metaboxes-wrapper .wc-metabox h3:hover .handlediv,.wc-metaboxes-wrapper .wc-metabox h3:hover a.delete,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper .handlediv,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper a.delete{visibility:visible}.wc-metaboxes-wrapper .wc-metabox table{width:100%;position:relative;background-color:#fdfdfd;padding:1em;border-top:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox table td{text-align:left;padding:0 6px 1em 0;vertical-align:top;border:0}.wc-metaboxes-wrapper .wc-metabox table td label{text-align:left;display:block;line-height:21px}.wc-metaboxes-wrapper .wc-metabox table td input{float:left;min-width:200px}.wc-metaboxes-wrapper .wc-metabox table td input,.wc-metaboxes-wrapper .wc-metabox table td textarea{width:100%;margin:0;display:block;font-size:14px;padding:4px;color:#555}.wc-metaboxes-wrapper .wc-metabox table td .select2-container,.wc-metaboxes-wrapper .wc-metabox table td select{width:100%!important}.wc-metaboxes-wrapper .wc-metabox table td input.short{width:200px}.wc-metaboxes-wrapper .wc-metabox table td input.checkbox{width:16px;min-width:inherit;vertical-align:text-bottom;display:inline-block;float:none}.wc-metaboxes-wrapper .wc-metabox table td.attribute_name{width:200px}.wc-metaboxes-wrapper .wc-metabox table .minus,.wc-metaboxes-wrapper .wc-metabox table .plus{margin-top:6px}.wc-metaboxes-wrapper .wc-metabox table .fl{float:left}.wc-metaboxes-wrapper .wc-metabox table .fr{float:right}.variations-pagenav{float:right;line-height:24px}.variations-pagenav .displaying-num{color:#777;font-size:12px;font-style:italic}.variations-pagenav a{padding:0 10px 3px;background:rgba(0,0,0,.05);font-size:16px;font-weight:400;text-decoration:none}.variations-pagenav a.disabled,.variations-pagenav a.disabled:active,.variations-pagenav a.disabled:focus,.variations-pagenav a.disabled:hover{color:#A0A5AA;background:rgba(0,0,0,.05)}.variations-defaults{float:left}.variations-defaults select{margin:.25em .25em .25em 0}.woocommerce_variable_attributes{background-color:#fdfdfd;border-top:1px solid #eee}.woocommerce_variable_attributes .data{padding:1em 2em}.woocommerce_variable_attributes .data:after,.woocommerce_variable_attributes .data:before{content:" ";display:table}.woocommerce_variable_attributes .data:after{clear:both}.woocommerce_variable_attributes .upload_image_button{display:block;width:48px;height:48px;float:left;margin-right:20px;position:relative;cursor:pointer}.woocommerce_variable_attributes .upload_image_button img{width:100%;height:auto;display:none}.woocommerce_variable_attributes .upload_image_button:before{content:"\f128";font-family:Dashicons;position:absolute;top:0;left:0;right:0;bottom:0;text-align:center;line-height:48px;font-size:48px;font-weight:400;-webkit-font-smoothing:antialiased}.woocommerce_variable_attributes .upload_image_button.remove img{display:block}.woocommerce_variable_attributes .upload_image_button.remove:before{content:"\f335";display:none}.woocommerce_variable_attributes .upload_image_button.remove:hover:before{display:block}.woocommerce_variable_attributes .options{border:1px solid #eee;border-width:1px 0;padding:.25em 0}.woocommerce_variable_attributes .options label{display:inline-block;padding:4px 1em 2px 0}.woocommerce_variable_attributes .options input[type=checkbox]{margin-top:5px;margin-right:3px}.form-row label{display:block}.form-row input[type=number],.form-row input[type=text],.form-row select{width:100%}.form-row.dimensions_field input{width:25%;float:left;margin-right:1%}.form-row.dimensions_field input:last-of-type{margin-right:0}.form-row-first,.form-row-last{width:48%;float:right}.form-row-first{clear:both;float:left}.form-row-full{clear:both}.tips{cursor:help;text-decoration:none}img.tips{padding:5px 0 0}#tiptip_holder{display:none;position:absolute;top:0;left:0;z-index:9999999}#tiptip_holder.tip_top{padding-bottom:5px}#tiptip_holder.tip_top #tiptip_arrow_inner{margin-top:-7px;margin-left:-6px;border-top-color:#333}#tiptip_holder.tip_bottom{padding-top:5px}#tiptip_holder.tip_bottom #tiptip_arrow_inner{margin-top:-5px;margin-left:-6px;border-bottom-color:#333}#tiptip_holder.tip_right{padding-left:5px}#tiptip_holder.tip_right #tiptip_arrow_inner{margin-top:-6px;margin-left:-5px;border-right-color:#333}#tiptip_holder.tip_left{padding-right:5px}#tiptip_holder.tip_left #tiptip_arrow_inner{margin-top:-6px;margin-left:-7px;border-left-color:#333}#tiptip_content,.chart-tooltip,.wc_error_tip{color:#fff;font-size:.8em;max-width:150px;background:#333;text-align:center;border-radius:3px;padding:.618em 1em;box-shadow:0 1px 3px rgba(0,0,0,.2)}#tiptip_content code,.chart-tooltip code,.wc_error_tip code{padding:1px;background:#888}#tiptip_arrow,#tiptip_arrow_inner{position:absolute;border-color:transparent;border-style:solid;border-width:6px;height:0;width:0}.wc_error_tip{max-width:20em;line-height:1.8em;position:absolute;white-space:normal;background:#d82223;margin:1.5em 1px 0 -1em;z-index:9999999}.wc_error_tip:after{content:"";display:block;border:8px solid #d82223;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-3px;left:50%;margin:-1em 0 0 -3px}img.ui-datepicker-trigger{vertical-align:middle;margin-top:-1px;cursor:pointer}.wc-metabox-content img.ui-datepicker-trigger,.woocommerce_options_panel img.ui-datepicker-trigger{float:left;margin-right:8px;margin-top:4px;margin-left:4px}#ui-datepicker-div{display:none}.woocommerce-reports-wide.woocommerce-reports-wrap,.woocommerce-reports-wrap.woocommerce-reports-wrap{margin-left:300px;padding-top:18px}.woocommerce-reports-wide.halved,.woocommerce-reports-wrap.halved{margin:0;overflow:hidden;zoom:1}.woocommerce-reports-wide .widefat td,.woocommerce-reports-wrap .widefat td{vertical-align:top;padding:7px}.woocommerce-reports-wide .widefat td .description,.woocommerce-reports-wrap .widefat td .description{margin:4px 0 0}.woocommerce-reports-wide .postbox:after,.woocommerce-reports-wrap .postbox:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox h3,.woocommerce-reports-wrap .postbox h3{cursor:default!important}.woocommerce-reports-wide .postbox .inside,.woocommerce-reports-wrap .postbox .inside{padding:10px;margin:0!important}.woocommerce-reports-wide .postbox div.stats_range,.woocommerce-reports-wide .postbox h3.stats_range,.woocommerce-reports-wrap .postbox div.stats_range,.woocommerce-reports-wrap .postbox h3.stats_range{border-bottom-color:#dfdfdf;margin:0;padding:0!important}.woocommerce-reports-wide .postbox div.stats_range .export_csv,.woocommerce-reports-wide .postbox h3.stats_range .export_csv,.woocommerce-reports-wrap .postbox div.stats_range .export_csv,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv{float:right;line-height:26px;border-left:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range .export_csv:before,.woocommerce-reports-wide .postbox h3.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox div.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;content:"";text-decoration:none;margin-right:4px}.woocommerce-reports-wide .postbox div.stats_range ul,.woocommerce-reports-wide .postbox h3.stats_range ul,.woocommerce-reports-wrap .postbox div.stats_range ul,.woocommerce-reports-wrap .postbox h3.stats_range ul{list-style:none;margin:0;padding:0;zoom:1;background:#f5f5f5;border-bottom:1px solid #ccc}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox div.stats_range ul:before,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:before,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:before,.woocommerce-reports-wrap .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:before{content:" ";display:table}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:after{clear:both}.woocommerce-reports-wide .postbox div.stats_range ul li,.woocommerce-reports-wide .postbox h3.stats_range ul li,.woocommerce-reports-wrap .postbox div.stats_range ul li,.woocommerce-reports-wrap .postbox h3.stats_range ul li{float:left;margin:0;padding:0;line-height:26px;font-weight:700;font-size:14px}.woocommerce-reports-wide .postbox div.stats_range ul li a,.woocommerce-reports-wide .postbox h3.stats_range ul li a,.woocommerce-reports-wrap .postbox div.stats_range ul li a,.woocommerce-reports-wrap .postbox h3.stats_range ul li a{border-right:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range ul li.active,.woocommerce-reports-wide .postbox h3.stats_range ul li.active,.woocommerce-reports-wrap .postbox div.stats_range ul li.active,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active{background:#fff;-webkit-box-shadow:0 4px 0 0 #fff;box-shadow:0 4px 0 0 #fff}.woocommerce-reports-wide .postbox div.stats_range ul li.active a,.woocommerce-reports-wide .postbox h3.stats_range ul li.active a,.woocommerce-reports-wrap .postbox div.stats_range ul li.active a,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active a{color:#777}.woocommerce-reports-wide .postbox div.stats_range ul li.custom,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom{padding:9px 10px;vertical-align:middle}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form{display:inline;margin:0}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form input.range_datepicker{padding:0;margin:0 10px 0 0;background:0 0;border:0;color:#777;text-align:center;-webkit-box-shadow:none;box-shadow:none}.woocommerce-reports-wide .postbox .chart-with-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar{padding:12px 12px 12px 249px;margin:0!important}.woocommerce-reports-wide .postbox .chart-with-sidebar .chart-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar .chart-sidebar{width:225px;margin-left:-237px;float:left}.woocommerce-reports-wide .postbox .chart-widgets,.woocommerce-reports-wrap .postbox .chart-widgets{margin:0;padding:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget{margin:0 0 1em;background:#fafafa;border:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4{background:#fff;border:1px solid #dfdfdf;border-left-width:0;border-right-width:0;padding:10px;margin:0;color:#2ea2cc;border-top-width:0;background-image:-webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9));background-image:-webkit-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-moz-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-o-linear-gradient(bottom,#ececec,#f9f9f9);background-image:linear-gradient(to top,#ececec,#f9f9f9)}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr.active td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr.active td{background:#f5f5f5}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4.section_title:hover,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4.section_title:hover{color:#a00}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title{cursor:pointer}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span{display:block}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin-left:.618em;content:"";text-decoration:none;float:right;font-size:.9em;line-height:1.618}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open{color:#333}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open span:after{display:none}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section{border-bottom:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section .select2-container,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section .select2-container{width:100%!important}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section:last-of-type,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section:last-of-type{border-radius:0 0 3px 3px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td{padding:7px 10px;vertical-align:top;border-top:1px solid #e5e5e5;line-height:1.4em}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.sparkline,form.report_filters div,form.report_filters input,form.report_filters label,form.report_filters p{vertical-align:middle}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr:first-child td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr:first-child td{border-top:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name{max-width:175px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name a,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name a{word-wrap:break-word}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table .wc_sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table .wc_sparkline{width:32px;height:1em;display:block;float:right}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p{margin:0;padding:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p .submit{margin-top:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget #product_ids,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget #product_ids{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_none,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_none{float:right;color:#999;margin-left:4px;margin-top:10px}.woocommerce-reports-wide .postbox .chart-legend,.woocommerce-reports-wrap .postbox .chart-legend{list-style:none;margin:0 0 1em;padding:0;border:1px solid #dfdfdf;border-right-width:0;border-bottom-width:0;background:#fff}.woocommerce-reports-wide .postbox .chart-legend li,.woocommerce-reports-wrap .postbox .chart-legend li{border-right:5px solid #aaa;color:#aaa;padding:1em;display:block;margin:0;-webkit-transition:all ease .5s;box-shadow:inset 0 -1px 0 0 #dfdfdf}.woocommerce-reports-wide .postbox .chart-legend li strong,.woocommerce-reports-wrap .postbox .chart-legend li strong{font-size:1.618em;line-height:1.2em;color:#464646;font-weight:400;display:block;font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif}.woocommerce-reports-wide .postbox .chart-legend li strong del,.woocommerce-reports-wrap .postbox .chart-legend li strong del{color:#e74c3c;font-weight:400}.woocommerce-reports-wide .postbox .chart-legend li:hover,.woocommerce-reports-wrap .postbox .chart-legend li:hover{box-shadow:inset 0 -1px 0 0 #dfdfdf,inset 300px 0 0 rgba(156,93,144,.1);border-right:5px solid #9c5d90!important;padding-left:1.5em;color:#9c5d90}.woocommerce-reports-wide .postbox .pie-chart-legend,.woocommerce-reports-wrap .postbox .pie-chart-legend{margin:12px 0 0;overflow:hidden}.woocommerce-reports-wide .postbox .pie-chart-legend li,.woocommerce-reports-wrap .postbox .pie-chart-legend li{float:left;margin:0;padding:6px 0 0;border-top:4px solid #999;text-align:center;box-sizing:border-box;width:50%}.woocommerce-reports-wide .postbox .stat,.woocommerce-reports-wrap .postbox .stat{font-size:1.5em!important;font-weight:700;text-align:center}.woocommerce-reports-wide .postbox .chart-placeholder,.woocommerce-reports-wrap .postbox .chart-placeholder{width:100%;height:650px;overflow:hidden;position:relative}.woocommerce-reports-wide .postbox .chart-prompt,.woocommerce-reports-wrap .postbox .chart-prompt{line-height:650px;margin:0;color:#999;font-size:1.2em;font-style:italic;text-align:center}.woocommerce-reports-wide .postbox .chart-container,.woocommerce-reports-wrap .postbox .chart-container{background:#fff;padding:12px;position:relative;border:1px solid #dfdfdf;border-radius:3px}.woocommerce-reports-wide .postbox .main .chart-legend,.woocommerce-reports-wrap .postbox .main .chart-legend{margin-top:12px}.woocommerce-reports-wide .postbox .main .chart-legend li,.woocommerce-reports-wrap .postbox .main .chart-legend li{border-right:0;margin:0 8px 0 0;float:left;border-top:4px solid #aaa}.woocommerce-reports-wide .woocommerce-reports-main,.woocommerce-reports-wrap .woocommerce-reports-main{float:left;min-width:100%}.woocommerce-reports-wide .woocommerce-reports-main table td,.woocommerce-reports-wrap .woocommerce-reports-main table td{padding:9px}.woocommerce-reports-wide .woocommerce-reports-sidebar,.woocommerce-reports-wrap .woocommerce-reports-sidebar{display:inline;width:281px;margin-left:-300px;clear:both;float:left}.woocommerce-reports-wide .woocommerce-reports-left,.woocommerce-reports-wrap .woocommerce-reports-left{width:49.5%;float:left}.woocommerce-reports-wide .woocommerce-reports-right,.woocommerce-reports-wrap .woocommerce-reports-right{width:49.5%;float:right}.woocommerce-reports-wide .column-wc_actions a.edit,.woocommerce-reports-wide .column-wc_actions a.view,.woocommerce-reports-wrap .column-wc_actions a.edit,.woocommerce-reports-wrap .column-wc_actions a.view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;line-height:1.85}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after{content:"\f464"}.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{content:"\f177"}.woocommerce-wide-reports-wrap{padding-bottom:11px}.woocommerce-wide-reports-wrap .widefat .export-data{float:right}.woocommerce-wide-reports-wrap .widefat td,.woocommerce-wide-reports-wrap .widefat th{vertical-align:middle;padding:7px}.chart-tooltip{position:absolute;display:none;line-height:1}table.bar_chart{width:100%}table.bar_chart thead th{text-align:left;color:#ccc;padding:6px 0}table.bar_chart tbody th{padding:6px 0;width:25%;text-align:left!important;font-weight:400!important;border-bottom:1px solid #fee}table.bar_chart tbody td{text-align:right;line-height:24px;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td span{color:#8a4b75;display:block}table.bar_chart tbody td span.alt{color:#47a03e;margin-top:6px}table.bar_chart tbody td.bars{position:relative;text-align:left;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td.bars a,table.bar_chart tbody td.bars span{text-decoration:none;clear:both;background:#8a4b75;float:left;display:block;line-height:24px;height:24px;-moz-border-radius:3px;-webkit-border-radius:3px;-o-border-radius:3px;-khtml-border-radius:3px;border-radius:3px}.post-type-product .woocommerce-BlankState-message:before,.post-type-shop_coupon .woocommerce-BlankState-message:before,.post-type-shop_order .woocommerce-BlankState-message:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}table.bar_chart tbody td.bars span.alt{clear:both;background:#47a03e}table.bar_chart tbody td.bars span.alt span{margin:0;color:#c5dec2!important;text-shadow:0 1px 0 #47a03e;background:0 0}.post-type-shop_order .woocommerce-BlankState-message:before{content:""}.post-type-shop_coupon .woocommerce-BlankState-message:before{content:""}.post-type-product .woocommerce-BlankState-message:before{content:""}.woocommerce-BlankState{text-align:center;padding:5em 0 0}.woocommerce-BlankState .woocommerce-BlankState-message{color:#aaa;margin:0 auto 1.5em;line-height:1.5em;font-size:1.2em;max-width:500px}.woocommerce-BlankState .woocommerce-BlankState-message:before{color:#ddd;text-shadow:0 -1px 1px rgba(0,0,0,.2),0 1px 0 rgba(255,255,255,.8);font-size:8em;display:block;position:relative!important;top:auto;left:auto;line-height:1em;margin:0 0 .1875em}.woocommerce-BlankState .woocommerce-BlankState-cta{font-size:1.2em;padding:.75em 1.5em;height:auto}@media only screen and (max-width:1280px){#order_data .order_data_column{width:48%}#order_data .order_data_column:first-child{width:100%}.woocommerce_options_panel .description{display:block;clear:both;margin-left:0}.woocommerce_options_panel .dimensions_field .wrap,.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:80%}.woocommerce_options_panel .downloadable_files,.woocommerce_variations .downloadable_files{padding:0;clear:both}.woocommerce_options_panel .downloadable_files label,.woocommerce_variations .downloadable_files label{position:static}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{margin:0 12px 24px;width:94%}.woocommerce_options_panel .downloadable_files table .sort,.woocommerce_variations .downloadable_files table .sort{visibility:hidden}.woocommerce_options_panel .woocommerce_variable_attributes .downloadable_files table,.woocommerce_variations .woocommerce_variable_attributes .downloadable_files table{margin:0 0 1em;width:100%}}@media only screen and (max-width:900px){#woocommerce-coupon-data ul.coupon_data_tabs,#woocommerce-product-data .wc-tabs-back,#woocommerce-product-data ul.product_data_tabs{width:10%}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{width:90%}#woocommerce-coupon-data ul.coupon_data_tabs li a,#woocommerce-product-data ul.product_data_tabs li a{position:relative;text-indent:-999px;padding:10px}#woocommerce-coupon-data ul.coupon_data_tabs li a:before,#woocommerce-product-data ul.product_data_tabs li a:before{position:absolute;top:0;right:0;bottom:0;left:0;text-indent:0;text-align:center;line-height:40px;width:100%;height:40px}}@media only screen and (max-width:782px){#wp-excerpt-media-buttons a{font-size:16px;line-height:37px;height:39px;padding:0 20px 0 15px}#wp-excerpt-editor-tools{padding-top:20px;padding-right:15px;overflow:hidden;margin-bottom:-1px}.post-type-product .wp-list-table .is-expanded td:not(.hidden),.post-type-shop_order .wp-list-table .is-expanded td:not(.hidden){overflow:visible}#woocommerce-product-data .checkbox{width:25px}.variations-pagenav{float:none;text-align:center;font-size:18px}.variations-pagenav .displaying-num{font-size:16px}.variations-pagenav a{padding:8px 20px 11px;font-size:18px}.variations-pagenav select{padding:0 20px}.variations-defaults{float:none;text-align:center;margin-top:10px}.post-type-product .wp-list-table .column-thumb{display:none;text-align:left;padding-bottom:0}.post-type-product .wp-list-table .column-thumb:before{display:none!important}.post-type-product .wp-list-table .column-thumb img{max-width:32px}.post-type-product .wp-list-table .toggle-row{top:-28px}.post-type-shop_order .wp-list-table .column-order_status{display:none;text-align:left;padding-bottom:0}.post-type-shop_order .wp-list-table .column-order_status mark{margin:0}.post-type-shop_order .wp-list-table .column-order_status:before{display:none!important}.post-type-shop_order .wp-list-table .column-customer_message,.post-type-shop_order .wp-list-table .column-order_notes{text-align:inherit}.post-type-shop_order .wp-list-table .column-order_notes .note-on{font-size:1.3em;margin:0}.post-type-shop_order .wp-list-table .toggle-row{top:-15px}}@media only screen and (max-width:500px){.woocommerce_options_panel label,.woocommerce_options_panel legend{float:none;width:auto;display:block;margin:0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px!important}}.wc-backbone-modal *{box-sizing:border-box}.wc-backbone-modal .wc-backbone-modal-content{position:fixed;background:#fff;z-index:100000;left:50%;top:50%;transform:translate(-50%,-50%);width:500px}.wc-backbone-modal .wc-backbone-modal-content article{overflow:auto}.wc-backbone-modal.wc-backbone-modal-shipping-method-settings .wc-backbone-modal-content{width:75%;min-width:500px}.wc-backbone-modal-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;min-height:360px;background:#000;opacity:.7;z-index:99900}.wc-backbone-modal-main{padding-bottom:55px}.wc-backbone-modal-main article,.wc-backbone-modal-main header{display:block;position:relative}.wc-backbone-modal-main .wc-backbone-modal-header{height:auto;background:#fcfcfc;padding:1em 1.5em;border-bottom:1px solid #ddd}.wc-backbone-modal-main .wc-backbone-modal-header h1{margin:0;font-size:18px;font-weight:700;line-height:1.5em}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link{cursor:pointer;color:#777;height:54px;width:54px;padding:0;position:absolute;top:0;right:0;text-align:center;border:0;border-left:1px solid #ddd;background-color:transparent;-webkit-transition:color .1s ease-in-out,background .1s ease-in-out;transition:color .1s ease-in-out,background .1s ease-in-out}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:before{font:400 22px/50px dashicons!important;color:#666;display:block;content:'\f335';font-weight:300}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus,.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:hover{background:#ddd;border-color:#ccc;color:#000}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus{outline:0}.wc-backbone-modal-main article{padding:1.5em}.wc-backbone-modal-main article p{margin:1.5em 0}.wc-backbone-modal-main article p:last-child,.wc-backbone-modal-main footer .inner .button{margin-bottom:0}.wc-backbone-modal-main article p:first-child{margin-top:0}.wc-backbone-modal-main article .pagination{padding:10px 0 0;text-align:center}.wc-backbone-modal-main footer{position:absolute;left:0;right:0;bottom:0;z-index:100;padding:1em 1.5em;background:#fcfcfc;border-top:1px solid #dfdfdf;box-shadow:0 -4px 4px -4px rgba(0,0,0,.1)}.wc-backbone-modal-main footer .inner{float:right;line-height:23px}.select2-drop{z-index:999999!important}.select2-container-multi .select2-choices .select2-search-field input{font-family:inherit;font-size:inherit;font-weight:inherit;padding:3px 5px}.select2-container{line-height:1.85em;font-size:14px} \ No newline at end of file diff --git a/assets/css/admin.scss b/assets/css/admin.scss index 52ba29e12a9..1cd2cec5cd4 100644 --- a/assets/css/admin.scss +++ b/assets/css/admin.scss @@ -2039,6 +2039,7 @@ table.wc_input_table { th { white-space: nowrap; + padding: 10px; } td { @@ -2052,7 +2053,7 @@ table.wc_input_table { input[type="text"], input[type="number"] { width: 100%; - padding: 5px 10px; + padding: 8px 10px; margin: 0; border: 0; outline: 0; From 31fdfcdec4bc25d33686f17b89e15f67e4fcc0a6 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 27 Jul 2016 11:47:30 +0100 Subject: [PATCH 160/298] Remove prefix from tags and cats Closes #11297 --- includes/class-wc-post-types.php | 50 ++++++++++++++++---------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/includes/class-wc-post-types.php b/includes/class-wc-post-types.php index d2c540c2b7a..639061266c9 100644 --- a/includes/class-wc-post-types.php +++ b/includes/class-wc-post-types.php @@ -60,20 +60,20 @@ class WC_Post_types { apply_filters( 'woocommerce_taxonomy_args_product_cat', array( 'hierarchical' => true, 'update_count_callback' => '_wc_term_recount', - 'label' => __( 'Product Categories', 'woocommerce' ), + 'label' => __( 'Categories', 'woocommerce' ), 'labels' => array( - 'name' => __( 'Product Categories', 'woocommerce' ), - 'singular_name' => __( 'Product Category', 'woocommerce' ), + 'name' => __( 'Categories', 'woocommerce' ), + 'singular_name' => __( 'Category', 'woocommerce' ), 'menu_name' => _x( 'Categories', 'Admin menu name', 'woocommerce' ), - 'search_items' => __( 'Search Product Categories', 'woocommerce' ), - 'all_items' => __( 'All Product Categories', 'woocommerce' ), - 'parent_item' => __( 'Parent Product Category', 'woocommerce' ), - 'parent_item_colon' => __( 'Parent Product Category:', 'woocommerce' ), - 'edit_item' => __( 'Edit Product Category', 'woocommerce' ), - 'update_item' => __( 'Update Product Category', 'woocommerce' ), - 'add_new_item' => __( 'Add New Product Category', 'woocommerce' ), - 'new_item_name' => __( 'New Product Category Name', 'woocommerce' ), - 'not_found' => __( 'No Product Category found', 'woocommerce' ), + 'search_items' => __( 'Search Categories', 'woocommerce' ), + 'all_items' => __( 'All Categories', 'woocommerce' ), + 'parent_item' => __( 'Parent Category', 'woocommerce' ), + 'parent_item_colon' => __( 'Parent Category:', 'woocommerce' ), + 'edit_item' => __( 'Edit Category', 'woocommerce' ), + 'update_item' => __( 'Update Category', 'woocommerce' ), + 'add_new_item' => __( 'Add New Category', 'woocommerce' ), + 'new_item_name' => __( 'New Category Name', 'woocommerce' ), + 'not_found' => __( 'No categories found', 'woocommerce' ), ), 'show_ui' => true, 'query_var' => true, @@ -98,20 +98,20 @@ class WC_Post_types { 'update_count_callback' => '_wc_term_recount', 'label' => __( 'Product Tags', 'woocommerce' ), 'labels' => array( - 'name' => __( 'Product Tags', 'woocommerce' ), - 'singular_name' => __( 'Product Tag', 'woocommerce' ), + 'name' => __( 'Tags', 'woocommerce' ), + 'singular_name' => __( 'Tag', 'woocommerce' ), 'menu_name' => _x( 'Tags', 'Admin menu name', 'woocommerce' ), - 'search_items' => __( 'Search Product Tags', 'woocommerce' ), - 'all_items' => __( 'All Product Tags', 'woocommerce' ), - 'edit_item' => __( 'Edit Product Tag', 'woocommerce' ), - 'update_item' => __( 'Update Product Tag', 'woocommerce' ), - 'add_new_item' => __( 'Add New Product Tag', 'woocommerce' ), - 'new_item_name' => __( 'New Product Tag Name', 'woocommerce' ), - 'popular_items' => __( 'Popular Product Tags', 'woocommerce' ), - 'separate_items_with_commas' => __( 'Separate Product Tags with commas', 'woocommerce' ), - 'add_or_remove_items' => __( 'Add or remove Product Tags', 'woocommerce' ), - 'choose_from_most_used' => __( 'Choose from the most used Product tags', 'woocommerce' ), - 'not_found' => __( 'No Product Tags found', 'woocommerce' ), + 'search_items' => __( 'Search Tags', 'woocommerce' ), + 'all_items' => __( 'All Tags', 'woocommerce' ), + 'edit_item' => __( 'Edit Tag', 'woocommerce' ), + 'update_item' => __( 'Update Tag', 'woocommerce' ), + 'add_new_item' => __( 'Add New Tag', 'woocommerce' ), + 'new_item_name' => __( 'New Tag Name', 'woocommerce' ), + 'popular_items' => __( 'Popular Tags', 'woocommerce' ), + 'separate_items_with_commas' => __( 'Separate Tags with commas', 'woocommerce' ), + 'add_or_remove_items' => __( 'Add or remove Tags', 'woocommerce' ), + 'choose_from_most_used' => __( 'Choose from the most used tags', 'woocommerce' ), + 'not_found' => __( 'No tags found', 'woocommerce' ), ), 'show_ui' => true, 'query_var' => true, From 66c61eebc83348af4c42856539cd918a8e181fa9 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 27 Jul 2016 11:58:43 +0100 Subject: [PATCH 161/298] Define full path for includes Closes #11087 --- includes/admin/class-wc-admin-addons.php | 2 +- includes/admin/class-wc-admin-dashboard.php | 4 +- includes/admin/class-wc-admin-importers.php | 2 +- includes/admin/class-wc-admin-post-types.php | 2 +- includes/admin/class-wc-admin-reports.php | 4 +- includes/admin/class-wc-admin-settings.php | 4 +- includes/admin/class-wc-admin-status.php | 8 +- includes/admin/class-wc-admin-webhooks.php | 2 +- includes/admin/class-wc-admin.php | 26 ++--- .../reports/class-wc-report-low-in-stock.php | 2 +- .../reports/class-wc-report-most-stocked.php | 2 +- .../reports/class-wc-report-out-of-stock.php | 2 +- .../settings/class-wc-settings-shipping.php | 8 +- includes/admin/wc-admin-functions.php | 6 +- includes/class-wc-api.php | 62 ++++++------ includes/class-wc-background-updater.php | 6 +- includes/class-wc-emails.php | 4 +- includes/class-wc-geo-ip.php | 2 +- includes/class-wc-geolocation.php | 2 +- includes/class-wc-install.php | 8 +- includes/class-wc-legacy-api.php | 72 +++++++------- includes/class-wc-session-handler.php | 2 +- .../paypal/class-wc-gateway-paypal.php | 8 +- .../class-wc-gateway-paypal-ipn-handler.php | 2 +- .../class-wc-gateway-paypal-pdt-handler.php | 2 +- .../class-wc-gateway-simplify-commerce.php | 2 +- includes/wc-widget-functions.php | 26 ++--- uninstall.php | 2 +- woocommerce.php | 97 ++++++++++--------- 29 files changed, 186 insertions(+), 185 deletions(-) diff --git a/includes/admin/class-wc-admin-addons.php b/includes/admin/class-wc-admin-addons.php index fe714f9c629..caf9689e074 100644 --- a/includes/admin/class-wc-admin-addons.php +++ b/includes/admin/class-wc-admin-addons.php @@ -133,6 +133,6 @@ class WC_Admin_Addons { $theme = wp_get_theme(); $section_keys = array_keys( $sections ); $current_section = isset( $_GET['section'] ) ? sanitize_text_field( $_GET['section'] ) : current( $section_keys ); - include_once( 'views/html-admin-page-addons.php' ); + include_once( dirname( __FILE__ ) . '/views/html-admin-page-addons.php' ); } } diff --git a/includes/admin/class-wc-admin-dashboard.php b/includes/admin/class-wc-admin-dashboard.php index 09b26130f4f..78f7ee3b231 100644 --- a/includes/admin/class-wc-admin-dashboard.php +++ b/includes/admin/class-wc-admin-dashboard.php @@ -46,8 +46,8 @@ class WC_Admin_Dashboard { public function status_widget() { global $wpdb; - include_once( 'reports/class-wc-admin-report.php' ); - include_once( 'reports/class-wc-report-sales-by-date.php' ); + include_once( dirname( __FILE__ ) . '/reports/class-wc-admin-report.php' ); + include_once( dirname( __FILE__ ) . '/reports/class-wc-report-sales-by-date.php' ); $reports = new WC_Admin_Report(); $sales_by_date = new WC_Report_Sales_By_Date(); diff --git a/includes/admin/class-wc-admin-importers.php b/includes/admin/class-wc-admin-importers.php index 6920abb0d99..d76645e8ab0 100644 --- a/includes/admin/class-wc-admin-importers.php +++ b/includes/admin/class-wc-admin-importers.php @@ -50,7 +50,7 @@ class WC_Admin_Importers { } // includes - require 'importers/class-wc-tax-rate-importer.php'; + require( dirname( __FILE__ ) . '/importers/class-wc-tax-rate-importer.php' ); // Dispatch $importer = new WC_Tax_Rate_Importer(); diff --git a/includes/admin/class-wc-admin-post-types.php b/includes/admin/class-wc-admin-post-types.php index d9bc880d267..baefb4ccea1 100644 --- a/includes/admin/class-wc-admin-post-types.php +++ b/includes/admin/class-wc-admin-post-types.php @@ -93,7 +93,7 @@ class WC_Admin_Post_Types { } // Meta-Box Class - include_once( 'class-wc-admin-meta-boxes.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-admin-meta-boxes.php' ); // Download permissions add_action( 'woocommerce_process_product_file_download_paths', array( $this, 'process_product_file_download_paths' ), 10, 3 ); diff --git a/includes/admin/class-wc-admin-reports.php b/includes/admin/class-wc-admin-reports.php index e43bba6571d..2d6709ed455 100644 --- a/includes/admin/class-wc-admin-reports.php +++ b/includes/admin/class-wc-admin-reports.php @@ -30,8 +30,8 @@ class WC_Admin_Reports { $current_tab = ! empty( $_GET['tab'] ) ? sanitize_title( $_GET['tab'] ) : $first_tab[0]; $current_report = isset( $_GET['report'] ) ? sanitize_title( $_GET['report'] ) : current( array_keys( $reports[ $current_tab ]['reports'] ) ); - include_once( 'reports/class-wc-admin-report.php' ); - include_once( 'views/html-admin-page-reports.php' ); + include_once( dirname( __FILE__ ) . '/reports/class-wc-admin-report.php' ); + include_once( dirname( __FILE__ ) . '/views/html-admin-page-reports.php' ); } /** diff --git a/includes/admin/class-wc-admin-settings.php b/includes/admin/class-wc-admin-settings.php index 2e4d242f26f..e53ed09ea3e 100644 --- a/includes/admin/class-wc-admin-settings.php +++ b/includes/admin/class-wc-admin-settings.php @@ -47,7 +47,7 @@ class WC_Admin_Settings { if ( empty( self::$settings ) ) { $settings = array(); - include_once( 'settings/class-wc-settings-page.php' ); + include_once( dirname( __FILE__ ) . '/settings/class-wc-settings-page.php' ); $settings[] = include( 'settings/class-wc-settings-general.php' ); $settings[] = include( 'settings/class-wc-settings-products.php' ); @@ -166,7 +166,7 @@ class WC_Admin_Settings { // Get tabs for the settings page $tabs = apply_filters( 'woocommerce_settings_tabs_array', array() ); - include 'views/html-admin-settings.php'; + include( dirname( __FILE__ ) . '/views/html-admin-settings.php' ); } /** diff --git a/includes/admin/class-wc-admin-status.php b/includes/admin/class-wc-admin-status.php index c65b590347f..db3050be3c3 100644 --- a/includes/admin/class-wc-admin-status.php +++ b/includes/admin/class-wc-admin-status.php @@ -21,14 +21,14 @@ class WC_Admin_Status { * Handles output of the reports page in admin. */ public static function output() { - include_once( 'views/html-admin-page-status.php' ); + include_once( dirname( __FILE__ ) . '/views/html-admin-page-status.php' ); } /** * Handles output of report. */ public static function status_report() { - include_once( 'views/html-admin-page-status-report.php' ); + include_once( dirname( __FILE__ ) . '/views/html-admin-page-status-report.php' ); } /** @@ -138,7 +138,7 @@ class WC_Admin_Status { echo '

    ' . __( 'Your changes have been saved.', 'woocommerce' ) . '

    '; } - include_once( 'views/html-admin-page-status-tools.php' ); + include_once( dirname( __FILE__ ) . '/views/html-admin-page-status-tools.php' ); } /** @@ -205,7 +205,7 @@ class WC_Admin_Status { $viewed_log = current( $logs ); } - include_once( 'views/html-admin-page-status-logs.php' ); + include_once( dirname( __FILE__ ) . '/views/html-admin-page-status-logs.php' ); } /** diff --git a/includes/admin/class-wc-admin-webhooks.php b/includes/admin/class-wc-admin-webhooks.php index 227d57544a5..0f2c6bb7d5a 100644 --- a/includes/admin/class-wc-admin-webhooks.php +++ b/includes/admin/class-wc-admin-webhooks.php @@ -442,7 +442,7 @@ class WC_Admin_Webhooks { add_filter( 'comments_clauses', array( 'WC_Comments', 'exclude_webhook_comments' ), 10, 1 ); if ( $logs ) { - include_once( 'settings/views/html-webhook-logs.php' ); + include_once( dirname( __FILE__ ) . '/settings/views/html-webhook-logs.php' ); } else { echo '

    ' . __( 'This Webhook has no log yet.', 'woocommerce' ) . '

    '; } diff --git a/includes/admin/class-wc-admin.php b/includes/admin/class-wc-admin.php index d62f2998b7a..b76ba91da5b 100644 --- a/includes/admin/class-wc-admin.php +++ b/includes/admin/class-wc-admin.php @@ -43,34 +43,34 @@ class WC_Admin { * Include any classes we need within admin. */ public function includes() { - include_once( 'wc-admin-functions.php' ); - include_once( 'wc-meta-box-functions.php' ); - include_once( 'class-wc-admin-post-types.php' ); - include_once( 'class-wc-admin-taxonomies.php' ); - include_once( 'class-wc-admin-menus.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' ); - include_once( 'class-wc-admin-pointers.php' ); + include_once( dirname( __FILE__ ) . '/wc-admin-functions.php' ); + include_once( dirname( __FILE__ ) . '/wc-meta-box-functions.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-admin-post-types.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-admin-taxonomies.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-admin-menus.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-admin-notices.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-admin-assets.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-admin-api-keys.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-admin-webhooks.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-admin-pointers.php' ); // Help Tabs if ( apply_filters( 'woocommerce_enable_admin_help_tab', true ) ) { - include_once( 'class-wc-admin-help.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-admin-help.php' ); } // Setup/welcome if ( ! empty( $_GET['page'] ) ) { switch ( $_GET['page'] ) { case 'wc-setup' : - include_once( 'class-wc-admin-setup-wizard.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-admin-setup-wizard.php' ); break; } } // Importers if ( defined( 'WP_LOAD_IMPORTERS' ) ) { - include_once( 'class-wc-admin-importers.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-admin-importers.php' ); } } diff --git a/includes/admin/reports/class-wc-report-low-in-stock.php b/includes/admin/reports/class-wc-report-low-in-stock.php index a964950a2d5..48e047e5d9e 100644 --- a/includes/admin/reports/class-wc-report-low-in-stock.php +++ b/includes/admin/reports/class-wc-report-low-in-stock.php @@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) { } if ( ! class_exists( 'WC_Report_Stock' ) ) { - require_once( 'class-wc-report-stock.php' ); + require_once( dirname( __FILE__ ) . '/class-wc-report-stock.php' ); } /** diff --git a/includes/admin/reports/class-wc-report-most-stocked.php b/includes/admin/reports/class-wc-report-most-stocked.php index afcc6287b35..5ca160e2d5b 100644 --- a/includes/admin/reports/class-wc-report-most-stocked.php +++ b/includes/admin/reports/class-wc-report-most-stocked.php @@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) { } if ( ! class_exists( 'WC_Report_Stock' ) ) { - require_once( 'class-wc-report-stock.php' ); + require_once( dirname( __FILE__ ) . '/class-wc-report-stock.php' ); } /** diff --git a/includes/admin/reports/class-wc-report-out-of-stock.php b/includes/admin/reports/class-wc-report-out-of-stock.php index 547c0dcb71d..0205e954f37 100644 --- a/includes/admin/reports/class-wc-report-out-of-stock.php +++ b/includes/admin/reports/class-wc-report-out-of-stock.php @@ -5,7 +5,7 @@ if ( ! defined( 'ABSPATH' ) ) { } if ( ! class_exists( 'WC_Report_Stock' ) ) { - require_once( 'class-wc-report-stock.php' ); + require_once( dirname( __FILE__ ) . '/class-wc-report-stock.php' ); } /** diff --git a/includes/admin/settings/class-wc-settings-shipping.php b/includes/admin/settings/class-wc-settings-shipping.php index d2c642cdc11..c6a35502417 100644 --- a/includes/admin/settings/class-wc-settings-shipping.php +++ b/includes/admin/settings/class-wc-settings-shipping.php @@ -217,7 +217,7 @@ class WC_Settings_Shipping extends WC_Settings_Page { ) ); wp_enqueue_script( 'wc-shipping-zone-methods' ); - include_once( 'views/html-admin-page-shipping-zone-methods.php' ); + include_once( dirname( __FILE__ ) . '/views/html-admin-page-shipping-zone-methods.php' ); } /** @@ -246,7 +246,7 @@ class WC_Settings_Shipping extends WC_Settings_Page { ) ); wp_enqueue_script( 'wc-shipping-zones' ); - include_once( 'views/html-admin-page-shipping-zones.php' ); + include_once( dirname( __FILE__ ) . '/views/html-admin-page-shipping-zones.php' ); } /** @@ -277,7 +277,7 @@ class WC_Settings_Shipping extends WC_Settings_Page { $shipping_method->display_errors(); } - include_once( 'views/html-admin-page-shipping-zones-instance.php' ); + include_once( dirname( __FILE__ ) . '/views/html-admin-page-shipping-zones-instance.php' ); } /** @@ -308,7 +308,7 @@ class WC_Settings_Shipping extends WC_Settings_Page { 'wc-shipping-class-count' => __( 'Product Count', 'woocommerce' ), ) ); - include_once( 'views/html-admin-page-shipping-classes.php' ); + include_once( dirname( __FILE__ ) . '/views/html-admin-page-shipping-classes.php' ); } } diff --git a/includes/admin/wc-admin-functions.php b/includes/admin/wc-admin-functions.php index 9ec801cd7bc..3f0fdbad604 100644 --- a/includes/admin/wc-admin-functions.php +++ b/includes/admin/wc-admin-functions.php @@ -135,7 +135,7 @@ function wc_create_page( $slug, $option = '', $page_title = '', $page_content = function woocommerce_admin_fields( $options ) { if ( ! class_exists( 'WC_Admin_Settings' ) ) { - include 'class-wc-admin-settings.php'; + include( dirname( __FILE__ ) . '/class-wc-admin-settings.php' ); } WC_Admin_Settings::output_fields( $options ); @@ -150,7 +150,7 @@ function woocommerce_admin_fields( $options ) { function woocommerce_update_options( $options, $data = null ) { if ( ! class_exists( 'WC_Admin_Settings' ) ) { - include 'class-wc-admin-settings.php'; + include( dirname( __FILE__ ) . '/class-wc-admin-settings.php' ); } WC_Admin_Settings::save_fields( $options, $data ); @@ -166,7 +166,7 @@ function woocommerce_update_options( $options, $data = null ) { function woocommerce_settings_get_option( $option_name, $default = '' ) { if ( ! class_exists( 'WC_Admin_Settings' ) ) { - include 'class-wc-admin-settings.php'; + include( dirname( __FILE__ ) . '/class-wc-admin-settings.php' ); } return WC_Admin_Settings::get_option( $option_name, $default ); diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 41587e21343..68d7fa42104 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -15,7 +15,7 @@ if ( ! defined( 'ABSPATH' ) ) { } if ( ! class_exists( 'WC_Legacy_API' ) ) { - include_once( 'class-wc-legacy-api.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-legacy-api.php' ); } class WC_API extends WC_Legacy_API { @@ -129,46 +129,46 @@ class WC_API extends WC_Legacy_API { */ private function rest_api_includes() { // Exception handler. - include_once( 'api/class-wc-rest-exception.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-exception.php' ); // Authentication. - include_once( 'api/class-wc-rest-authentication.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-authentication.php' ); // WP-API classes and functions. - include_once( 'vendor/wp-rest-functions.php' ); + include_once( dirname( __FILE__ ) . '/vendor/wp-rest-functions.php' ); if ( ! class_exists( 'WP_REST_Controller' ) ) { - include_once( 'vendor/class-wp-rest-controller.php' ); + include_once( dirname( __FILE__ ) . '/vendor/class-wp-rest-controller.php' ); } // Abstract controllers. - include_once( 'abstracts/abstract-wc-rest-controller.php' ); - include_once( 'abstracts/abstract-wc-rest-posts-controller.php' ); - include_once( 'abstracts/abstract-wc-rest-terms-controller.php' ); - include_once( 'abstracts/abstract-wc-settings-api.php' ); + include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-controller.php' ); + include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-posts-controller.php' ); + include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-terms-controller.php' ); + include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-settings-api.php' ); // REST API controllers. - include_once( 'api/class-wc-rest-coupons-controller.php' ); - include_once( 'api/class-wc-rest-customer-downloads-controller.php' ); - include_once( 'api/class-wc-rest-customers-controller.php' ); - include_once( 'api/class-wc-rest-order-notes-controller.php' ); - include_once( 'api/class-wc-rest-order-refunds-controller.php' ); - include_once( 'api/class-wc-rest-orders-controller.php' ); - include_once( 'api/class-wc-rest-product-attribute-terms-controller.php' ); - include_once( 'api/class-wc-rest-product-attributes-controller.php' ); - include_once( 'api/class-wc-rest-product-categories-controller.php' ); - include_once( 'api/class-wc-rest-product-reviews-controller.php' ); - include_once( 'api/class-wc-rest-product-shipping-classes-controller.php' ); - include_once( 'api/class-wc-rest-product-tags-controller.php' ); - include_once( 'api/class-wc-rest-products-controller.php' ); - include_once( 'api/class-wc-rest-report-sales-controller.php' ); - include_once( 'api/class-wc-rest-report-top-sellers-controller.php' ); - include_once( 'api/class-wc-rest-reports-controller.php' ); - include_once( 'api/class-wc-rest-settings-controller.php' ); - include_once( 'api/class-wc-rest-settings-options-controller.php' ); - include_once( 'api/class-wc-rest-tax-classes-controller.php' ); - include_once( 'api/class-wc-rest-taxes-controller.php' ); - include_once( 'api/class-wc-rest-webhook-deliveries.php' ); - include_once( 'api/class-wc-rest-webhooks-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-coupons-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-customer-downloads-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-customers-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-order-notes-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-order-refunds-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-orders-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-attribute-terms-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-attributes-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-categories-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-reviews-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-shipping-classes-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-product-tags-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-products-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-report-sales-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-report-top-sellers-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-reports-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-settings-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-settings-options-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-tax-classes-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-taxes-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-webhook-deliveries.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-webhooks-controller.php' ); } /** diff --git a/includes/class-wc-background-updater.php b/includes/class-wc-background-updater.php index e168be72cad..df0b2cda78b 100644 --- a/includes/class-wc-background-updater.php +++ b/includes/class-wc-background-updater.php @@ -16,8 +16,8 @@ if ( ! defined( 'ABSPATH' ) ) { exit; } -include_once( 'libraries/wp-async-request.php' ); -include_once( 'libraries/wp-background-process.php' ); +include_once( dirname( __FILE__ ) . '/libraries/wp-async-request.php' ); +include_once( dirname( __FILE__ ) . '/libraries/wp-background-process.php' ); /** * WC_Background_Updater Class. @@ -99,7 +99,7 @@ class WC_Background_Updater extends WP_Background_Process { $logger = new WC_Logger(); - include_once( 'wc-update-functions.php' ); + include_once( dirname( __FILE__ ) . '/wc-update-functions.php' ); if ( is_callable( $callback ) ) { $logger->add( 'wc_db_updates', sprintf( 'Running %s callback', $callback ) ); diff --git a/includes/class-wc-emails.php b/includes/class-wc-emails.php index 49c78becfa3..fe7354b761f 100644 --- a/includes/class-wc-emails.php +++ b/includes/class-wc-emails.php @@ -129,7 +129,7 @@ class WC_Emails { */ public function init() { // Include email classes - include_once( 'emails/class-wc-email.php' ); + include_once( dirname( __FILE__ ) . '/emails/class-wc-email.php' ); $this->emails['WC_Email_New_Order'] = include( 'emails/class-wc-email-new-order.php' ); $this->emails['WC_Email_Cancelled_Order'] = include( 'emails/class-wc-email-cancelled-order.php' ); @@ -147,7 +147,7 @@ class WC_Emails { // include css inliner if ( ! class_exists( 'Emogrifier' ) && class_exists( 'DOMDocument' ) ) { - include_once( 'libraries/class-emogrifier.php' ); + include_once( dirname( __FILE__ ) . '/libraries/class-emogrifier.php' ); } } diff --git a/includes/class-wc-geo-ip.php b/includes/class-wc-geo-ip.php index 9f6d29d3d66..1dcfed3c555 100644 --- a/includes/class-wc-geo-ip.php +++ b/includes/class-wc-geo-ip.php @@ -1169,7 +1169,7 @@ class WC_Geo_IP { */ public static function log( $message ) { if ( ! class_exists( 'WC_Logger' ) ) { - include_once( 'class-wc-logger.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-logger.php' ); } if ( empty( self::$log ) ) { diff --git a/includes/class-wc-geolocation.php b/includes/class-wc-geolocation.php index e130316d11e..f22d6f7b9be 100644 --- a/includes/class-wc-geolocation.php +++ b/includes/class-wc-geolocation.php @@ -218,7 +218,7 @@ class WC_Geolocation { */ private static function geolocate_via_db( $ip_address ) { if ( ! class_exists( 'WC_Geo_IP' ) ) { - include_once( 'class-wc-geo-ip.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-geo-ip.php' ); } $gi = new WC_Geo_IP(); diff --git a/includes/class-wc-install.php b/includes/class-wc-install.php index 7d3cfb79e70..57bfc7942fe 100644 --- a/includes/class-wc-install.php +++ b/includes/class-wc-install.php @@ -96,7 +96,7 @@ class WC_Install { * Init background updates */ public static function init_background_updater() { - include_once( 'class-wc-background-updater.php' ); + include_once( dirname( __FILE__ ) . '/class-wc-background-updater.php' ); self::$background_updater = new WC_Background_Updater(); } @@ -139,7 +139,7 @@ class WC_Install { } // Ensure needed classes are loaded - include_once( 'admin/class-wc-admin-notices.php' ); + include_once( dirname( __FILE__ ) . '/admin/class-wc-admin-notices.php' ); self::create_options(); self::create_tables(); @@ -287,7 +287,7 @@ class WC_Install { * Create pages that the plugin relies on, storing page id's in variables. */ public static function create_pages() { - include_once( 'admin/wc-admin-functions.php' ); + include_once( dirname( __FILE__ ) . '/admin/wc-admin-functions.php' ); $pages = apply_filters( 'woocommerce_create_pages', array( 'shop' => array( @@ -326,7 +326,7 @@ class WC_Install { */ private static function create_options() { // Include settings so that we can run through defaults - include_once( 'admin/class-wc-admin-settings.php' ); + include_once( dirname( __FILE__ ) . '/admin/class-wc-admin-settings.php' ); $settings = WC_Admin_Settings::get_settings_pages(); diff --git a/includes/class-wc-legacy-api.php b/includes/class-wc-legacy-api.php index c105e92b7fa..99cfb48834f 100644 --- a/includes/class-wc-legacy-api.php +++ b/includes/class-wc-legacy-api.php @@ -124,23 +124,23 @@ class WC_Legacy_API { public function includes() { // API server / response handlers. - include_once( 'api/legacy/v3/class-wc-api-exception.php' ); - include_once( 'api/legacy/v3/class-wc-api-server.php' ); - include_once( 'api/legacy/v3/interface-wc-api-handler.php' ); - include_once( 'api/legacy/v3/class-wc-api-json-handler.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-exception.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-server.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v3/interface-wc-api-handler.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-json-handler.php' ); // Authentication. - include_once( 'api/legacy/v3/class-wc-api-authentication.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-authentication.php' ); $this->authentication = new WC_API_Authentication(); - include_once( 'api/legacy/v3/class-wc-api-resource.php' ); - include_once( 'api/legacy/v3/class-wc-api-coupons.php' ); - include_once( 'api/legacy/v3/class-wc-api-customers.php' ); - include_once( 'api/legacy/v3/class-wc-api-orders.php' ); - include_once( 'api/legacy/v3/class-wc-api-products.php' ); - include_once( 'api/legacy/v3/class-wc-api-reports.php' ); - include_once( 'api/legacy/v3/class-wc-api-taxes.php' ); - include_once( 'api/legacy/v3/class-wc-api-webhooks.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-resource.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-coupons.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-customers.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-orders.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-products.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-reports.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-taxes.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v3/class-wc-api-webhooks.php' ); // Allow plugins to load other response handlers or resource classes. do_action( 'woocommerce_api_loaded' ); @@ -182,20 +182,20 @@ class WC_Legacy_API { private function handle_v1_rest_api_request() { // Include legacy required files for v1 REST API request. - include_once( 'api/legacy/v1/class-wc-api-server.php' ); - include_once( 'api/legacy/v1/interface-wc-api-handler.php' ); - include_once( 'api/legacy/v1/class-wc-api-json-handler.php' ); - include_once( 'api/legacy/v1/class-wc-api-xml-handler.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-server.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v1/interface-wc-api-handler.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-json-handler.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-xml-handler.php' ); - include_once( 'api/legacy/v1/class-wc-api-authentication.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-authentication.php' ); $this->authentication = new WC_API_Authentication(); - include_once( 'api/legacy/v1/class-wc-api-resource.php' ); - include_once( 'api/legacy/v1/class-wc-api-coupons.php' ); - include_once( 'api/legacy/v1/class-wc-api-customers.php' ); - include_once( 'api/legacy/v1/class-wc-api-orders.php' ); - include_once( 'api/legacy/v1/class-wc-api-products.php' ); - include_once( 'api/legacy/v1/class-wc-api-reports.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-resource.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-coupons.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-customers.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-orders.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-products.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v1/class-wc-api-reports.php' ); // Allow plugins to load other response handlers or resource classes. do_action( 'woocommerce_api_loaded' ); @@ -228,21 +228,21 @@ class WC_Legacy_API { * @deprecated 2.6.0 */ private function handle_v2_rest_api_request() { - include_once( 'api/legacy/v2/class-wc-api-exception.php' ); - include_once( 'api/legacy/v2/class-wc-api-server.php' ); - include_once( 'api/legacy/v2/interface-wc-api-handler.php' ); - include_once( 'api/legacy/v2/class-wc-api-json-handler.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-exception.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-server.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v2/interface-wc-api-handler.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-json-handler.php' ); - include_once( 'api/legacy/v2/class-wc-api-authentication.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-authentication.php' ); $this->authentication = new WC_API_Authentication(); - include_once( 'api/legacy/v2/class-wc-api-resource.php' ); - include_once( 'api/legacy/v2/class-wc-api-coupons.php' ); - include_once( 'api/legacy/v2/class-wc-api-customers.php' ); - include_once( 'api/legacy/v2/class-wc-api-orders.php' ); - include_once( 'api/legacy/v2/class-wc-api-products.php' ); - include_once( 'api/legacy/v2/class-wc-api-reports.php' ); - include_once( 'api/legacy/v2/class-wc-api-webhooks.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-resource.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-coupons.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-customers.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-orders.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-products.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-reports.php' ); + include_once( dirname( __FILE__ ) . '/api/legacy/v2/class-wc-api-webhooks.php' ); // allow plugins to load other response handlers or resource classes. do_action( 'woocommerce_api_loaded' ); diff --git a/includes/class-wc-session-handler.php b/includes/class-wc-session-handler.php index 915cdaf4cfa..0546ac3dbc1 100644 --- a/includes/class-wc-session-handler.php +++ b/includes/class-wc-session-handler.php @@ -4,7 +4,7 @@ if ( ! defined( 'ABSPATH' ) ) { } if ( ! class_exists( 'WC_Session' ) ) { - include_once( 'abstracts/abstract-wc-session.php' ); + include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-session.php' ); } /** diff --git a/includes/gateways/paypal/class-wc-gateway-paypal.php b/includes/gateways/paypal/class-wc-gateway-paypal.php index 680bc84aa95..0dd15e46296 100644 --- a/includes/gateways/paypal/class-wc-gateway-paypal.php +++ b/includes/gateways/paypal/class-wc-gateway-paypal.php @@ -60,11 +60,11 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { if ( ! $this->is_valid_for_use() ) { $this->enabled = 'no'; } else { - include_once( 'includes/class-wc-gateway-paypal-ipn-handler.php' ); + include_once( dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-ipn-handler.php' ); new WC_Gateway_Paypal_IPN_Handler( $this->testmode, $this->receiver_email ); if ( $this->identity_token ) { - include_once( 'includes/class-wc-gateway-paypal-pdt-handler.php' ); + include_once( dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-pdt-handler.php' ); new WC_Gateway_Paypal_PDT_Handler( $this->testmode, $this->identity_token ); } } @@ -236,7 +236,7 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { * @return array */ public function process_payment( $order_id ) { - include_once( 'includes/class-wc-gateway-paypal-request.php' ); + include_once( dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-request.php' ); $order = wc_get_order( $order_id ); $paypal_request = new WC_Gateway_Paypal_Request( $this ); @@ -271,7 +271,7 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { return new WP_Error( 'error', __( 'Refund Failed: No transaction ID', 'woocommerce' ) ); } - include_once( 'includes/class-wc-gateway-paypal-refund.php' ); + include_once( dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-refund.php' ); WC_Gateway_Paypal_Refund::$api_username = $this->get_option( 'api_username' ); WC_Gateway_Paypal_Refund::$api_password = $this->get_option( 'api_password' ); diff --git a/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php b/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php index 4b42c58c94e..f33901d40a8 100644 --- a/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php +++ b/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php @@ -4,7 +4,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; } -include_once( 'class-wc-gateway-paypal-response.php' ); +include_once( dirname( __FILE__ ) . '/class-wc-gateway-paypal-response.php' ); /** * Handles responses from PayPal IPN. diff --git a/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php b/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php index 1ec87825611..69d1dd2dc6b 100644 --- a/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php +++ b/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php @@ -4,7 +4,7 @@ if ( ! defined( 'ABSPATH' ) ) { exit; } -include_once( 'class-wc-gateway-paypal-response.php' ); +include_once( dirname( __FILE__ ) . '/class-wc-gateway-paypal-response.php' ); /** * Handle PDT Responses from PayPal. diff --git a/includes/gateways/simplify-commerce/class-wc-gateway-simplify-commerce.php b/includes/gateways/simplify-commerce/class-wc-gateway-simplify-commerce.php index dde11a0dffd..6fb3a0b818d 100644 --- a/includes/gateways/simplify-commerce/class-wc-gateway-simplify-commerce.php +++ b/includes/gateways/simplify-commerce/class-wc-gateway-simplify-commerce.php @@ -74,7 +74,7 @@ class WC_Gateway_Simplify_Commerce extends WC_Payment_Gateway_CC { */ protected function init_simplify_sdk() { // Include lib - require_once( 'includes/Simplify.php' ); + require_once( dirname( __FILE__ ) . '/includes/Simplify.php' ); Simplify::$publicKey = $this->public_key; Simplify::$privateKey = $this->private_key; diff --git a/includes/wc-widget-functions.php b/includes/wc-widget-functions.php index 2b1ab07d4b8..0fb6459c34f 100644 --- a/includes/wc-widget-functions.php +++ b/includes/wc-widget-functions.php @@ -15,19 +15,19 @@ if ( ! defined( 'ABSPATH' ) ) { } // Include widget classes. -include_once( 'abstracts/abstract-wc-widget.php' ); -include_once( 'widgets/class-wc-widget-cart.php' ); -include_once( 'widgets/class-wc-widget-layered-nav-filters.php' ); -include_once( 'widgets/class-wc-widget-layered-nav.php' ); -include_once( 'widgets/class-wc-widget-price-filter.php' ); -include_once( 'widgets/class-wc-widget-product-categories.php' ); -include_once( 'widgets/class-wc-widget-product-search.php' ); -include_once( 'widgets/class-wc-widget-product-tag-cloud.php' ); -include_once( 'widgets/class-wc-widget-products.php' ); -include_once( 'widgets/class-wc-widget-rating-filter.php' ); -include_once( 'widgets/class-wc-widget-recent-reviews.php' ); -include_once( 'widgets/class-wc-widget-recently-viewed.php' ); -include_once( 'widgets/class-wc-widget-top-rated-products.php' ); +include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-widget.php' ); +include_once( dirname( __FILE__ ) . '/widgets/class-wc-widget-cart.php' ); +include_once( dirname( __FILE__ ) . '/widgets/class-wc-widget-layered-nav-filters.php' ); +include_once( dirname( __FILE__ ) . '/widgets/class-wc-widget-layered-nav.php' ); +include_once( dirname( __FILE__ ) . '/widgets/class-wc-widget-price-filter.php' ); +include_once( dirname( __FILE__ ) . '/widgets/class-wc-widget-product-categories.php' ); +include_once( dirname( __FILE__ ) . '/widgets/class-wc-widget-product-search.php' ); +include_once( dirname( __FILE__ ) . '/widgets/class-wc-widget-product-tag-cloud.php' ); +include_once( dirname( __FILE__ ) . '/widgets/class-wc-widget-products.php' ); +include_once( dirname( __FILE__ ) . '/widgets/class-wc-widget-rating-filter.php' ); +include_once( dirname( __FILE__ ) . '/widgets/class-wc-widget-recent-reviews.php' ); +include_once( dirname( __FILE__ ) . '/widgets/class-wc-widget-recently-viewed.php' ); +include_once( dirname( __FILE__ ) . '/widgets/class-wc-widget-top-rated-products.php' ); /** * Register Widgets. diff --git a/uninstall.php b/uninstall.php index 7f2beb741a3..f6ffed61dff 100644 --- a/uninstall.php +++ b/uninstall.php @@ -26,7 +26,7 @@ $status_options = get_option( 'woocommerce_status_options', array() ); if ( ! empty( $status_options['uninstall_data'] ) ) { // Roles + caps. - include_once( 'includes/class-wc-install.php' ); + include_once( dirname( __FILE__ ) . '/includes/class-wc-install.php' ); WC_Install::remove_roles(); // Pages. diff --git a/woocommerce.php b/woocommerce.php index ba40cc0cd77..e34c518c717 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -178,6 +178,7 @@ final class WooCommerce { $upload_dir = wp_upload_dir(); $this->define( 'WC_PLUGIN_FILE', __FILE__ ); + $this->define( 'WC_ABSPATH', dirname( __FILE__ ) . '/' ); $this->define( 'WC_PLUGIN_BASENAME', plugin_basename( __FILE__ ) ); $this->define( 'WC_VERSION', $this->version ); $this->define( 'WOOCOMMERCE_VERSION', $this->version ); @@ -224,20 +225,20 @@ final class WooCommerce { * Include required core files used in admin and on the frontend. */ public function includes() { - include_once( 'includes/class-wc-autoloader.php' ); - include_once( 'includes/wc-core-functions.php' ); - include_once( 'includes/class-wc-register-wp-admin-settings.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-geolocation.php' ); - include_once( 'includes/class-wc-download-handler.php' ); - include_once( 'includes/class-wc-comments.php' ); - include_once( 'includes/class-wc-post-data.php' ); - include_once( 'includes/class-wc-ajax.php' ); + include_once( WC_ABSPATH . 'includes/class-wc-autoloader.php' ); + include_once( WC_ABSPATH . 'includes/wc-core-functions.php' ); + include_once( WC_ABSPATH . 'includes/class-wc-register-wp-admin-settings.php' ); + include_once( WC_ABSPATH . 'includes/wc-widget-functions.php' ); + include_once( WC_ABSPATH . 'includes/wc-webhook-functions.php' ); + include_once( WC_ABSPATH . 'includes/class-wc-install.php' ); + include_once( WC_ABSPATH . 'includes/class-wc-geolocation.php' ); + include_once( WC_ABSPATH . 'includes/class-wc-download-handler.php' ); + include_once( WC_ABSPATH . 'includes/class-wc-comments.php' ); + include_once( WC_ABSPATH . 'includes/class-wc-post-data.php' ); + include_once( WC_ABSPATH . 'includes/class-wc-ajax.php' ); if ( $this->is_request( 'admin' ) ) { - include_once( 'includes/admin/class-wc-admin.php' ); + include_once( WC_ABSPATH . 'includes/admin/class-wc-admin.php' ); } if ( $this->is_request( 'frontend' ) ) { @@ -245,36 +246,36 @@ final class WooCommerce { } if ( $this->is_request( 'frontend' ) || $this->is_request( 'cron' ) ) { - include_once( 'includes/class-wc-session-handler.php' ); + include_once( WC_ABSPATH . 'includes/class-wc-session-handler.php' ); } if ( $this->is_request( 'cron' ) && 'yes' === get_option( 'woocommerce_allow_tracking', 'no' ) ) { - include_once( 'includes/class-wc-tracker.php' ); + include_once( WC_ABSPATH . 'includes/class-wc-tracker.php' ); } - include_once( 'includes/class-wc-query.php' ); // The main query class - include_once( '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-data.php' ); // WC_Data for CRUD - include_once( 'includes/abstracts/abstract-wc-payment-token.php' ); // Payment Tokens - include_once( 'includes/abstracts/abstract-wc-product.php' ); // Products - include_once( 'includes/abstracts/abstract-wc-order.php' ); // Orders - include_once( 'includes/abstracts/abstract-wc-settings-api.php' ); // Settings API (for gateways, shipping, and integrations) - include_once( 'includes/abstracts/abstract-wc-shipping-method.php' ); // A Shipping method - include_once( 'includes/abstracts/abstract-wc-payment-gateway.php' ); // A Payment gateway - include_once( 'includes/abstracts/abstract-wc-integration.php' ); // An integration with a service - include_once( 'includes/class-wc-product-factory.php' ); // Product factory - include_once( 'includes/class-wc-payment-tokens.php' ); // Payment tokens controller - include_once( 'includes/gateways/class-wc-payment-gateway-cc.php' ); // CC Payment Gateway - include_once( 'includes/gateways/class-wc-payment-gateway-echeck.php' ); // eCheck Payment Gateway - include_once( 'includes/class-wc-countries.php' ); // Defines countries and states - include_once( 'includes/class-wc-integrations.php' ); // Loads integrations - include_once( 'includes/class-wc-cache-helper.php' ); // Cache Helper - include_once( 'includes/class-wc-https.php' ); // https Helper + include_once( WC_ABSPATH . 'includes/class-wc-query.php' ); // The main query class + include_once( WC_ABSPATH . 'includes/class-wc-api.php' ); // API Class + include_once( WC_ABSPATH . 'includes/class-wc-auth.php' ); // Auth Class + include_once( WC_ABSPATH . 'includes/class-wc-post-types.php' ); // Registers post types + include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-data.php' ); // WC_Data for CRUD + include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-payment-token.php' ); // Payment Tokens + include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-product.php' ); // Products + include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-order.php' ); // Orders + include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-settings-api.php' ); // Settings API (for gateways, shipping, and integrations) + include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-shipping-method.php' ); // A Shipping method + include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-payment-gateway.php' ); // A Payment gateway + include_once( WC_ABSPATH . 'includes/abstracts/abstract-wc-integration.php' ); // An integration with a service + include_once( WC_ABSPATH . 'includes/class-wc-product-factory.php' ); // Product factory + include_once( WC_ABSPATH . 'includes/class-wc-payment-tokens.php' ); // Payment tokens controller + include_once( WC_ABSPATH . 'includes/gateways/class-wc-payment-gateway-cc.php' ); // CC Payment Gateway + include_once( WC_ABSPATH . 'includes/gateways/class-wc-payment-gateway-echeck.php' ); // eCheck Payment Gateway + include_once( WC_ABSPATH . 'includes/class-wc-countries.php' ); // Defines countries and states + include_once( WC_ABSPATH . 'includes/class-wc-integrations.php' ); // Loads integrations + include_once( WC_ABSPATH . 'includes/class-wc-cache-helper.php' ); // Cache Helper + include_once( WC_ABSPATH . 'includes/class-wc-https.php' ); // https Helper if ( defined( 'WP_CLI' ) && WP_CLI ) { - include_once( 'includes/class-wc-cli.php' ); + include_once( WC_ABSPATH . 'includes/class-wc-cli.php' ); } $this->query = new WC_Query(); @@ -285,25 +286,25 @@ final class WooCommerce { * Include required frontend files. */ public function frontend_includes() { - include_once( 'includes/wc-cart-functions.php' ); - include_once( 'includes/wc-notice-functions.php' ); - include_once( 'includes/wc-template-hooks.php' ); - include_once( 'includes/class-wc-template-loader.php' ); // Template Loader - include_once( 'includes/class-wc-frontend-scripts.php' ); // Frontend Scripts - include_once( 'includes/class-wc-form-handler.php' ); // Form Handlers - include_once( 'includes/class-wc-cart.php' ); // The main cart class - include_once( 'includes/class-wc-tax.php' ); // Tax class - include_once( 'includes/class-wc-shipping-zones.php' ); // Shipping Zones class - include_once( 'includes/class-wc-customer.php' ); // Customer class - include_once( 'includes/class-wc-shortcodes.php' ); // Shortcodes class - include_once( 'includes/class-wc-embed.php' ); // Embeds + include_once( WC_ABSPATH . 'includes/wc-cart-functions.php' ); + include_once( WC_ABSPATH . 'includes/wc-notice-functions.php' ); + include_once( WC_ABSPATH . 'includes/wc-template-hooks.php' ); + include_once( WC_ABSPATH . 'includes/class-wc-template-loader.php' ); // Template Loader + include_once( WC_ABSPATH . 'includes/class-wc-frontend-scripts.php' ); // Frontend Scripts + include_once( WC_ABSPATH . 'includes/class-wc-form-handler.php' ); // Form Handlers + include_once( WC_ABSPATH . 'includes/class-wc-cart.php' ); // The main cart class + include_once( WC_ABSPATH . 'includes/class-wc-tax.php' ); // Tax class + include_once( WC_ABSPATH . 'includes/class-wc-shipping-zones.php' ); // Shipping Zones class + include_once( WC_ABSPATH . 'includes/class-wc-customer.php' ); // Customer class + include_once( WC_ABSPATH . 'includes/class-wc-shortcodes.php' ); // Shortcodes class + include_once( WC_ABSPATH . 'includes/class-wc-embed.php' ); // Embeds } /** * Function used to Init WooCommerce Template Functions - This makes them pluggable by plugins and themes. */ public function include_template_functions() { - include_once( 'includes/wc-template-functions.php' ); + include_once( WC_ABSPATH . 'includes/wc-template-functions.php' ); } /** From d2adabaf8976303f7b08947042933dbf544d4f11 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 27 Jul 2016 12:47:41 +0100 Subject: [PATCH 162/298] Redirect to login after password reset. Closes #11376 --- includes/class-wc-form-handler.php | 2 +- includes/shortcodes/class-wc-shortcode-my-account.php | 11 +++++------ readme.txt | 1 + 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/includes/class-wc-form-handler.php b/includes/class-wc-form-handler.php index df46f551b62..7d8cc89bd74 100644 --- a/includes/class-wc-form-handler.php +++ b/includes/class-wc-form-handler.php @@ -987,7 +987,7 @@ class WC_Form_Handler { do_action( 'woocommerce_customer_reset_password', $user ); - wp_redirect( add_query_arg( 'reset', 'true', remove_query_arg( array( 'key', 'login', 'reset-link-sent' ) ) ) ); + wp_redirect( add_query_arg( 'password-reset', 'true', wc_get_page_permalink( 'myaccount' ) ) ); exit; } } diff --git a/includes/shortcodes/class-wc-shortcode-my-account.php b/includes/shortcodes/class-wc-shortcode-my-account.php index 38c0beefbf7..39033c0c597 100644 --- a/includes/shortcodes/class-wc-shortcode-my-account.php +++ b/includes/shortcodes/class-wc-shortcode-my-account.php @@ -41,6 +41,11 @@ class WC_Shortcode_My_Account { wc_add_notice( $message ); } + // After password reset, add confirmation message. + if ( ! empty( $_GET['password-reset'] ) ) { + wc_add_notice( __( 'Your password has been reset successfully.', 'woocommerce' ) ); + } + if ( isset( $wp->query_vars['lost-password'] ) ) { self::lost_password(); } else { @@ -188,12 +193,6 @@ class WC_Shortcode_My_Account { if ( ! empty( $_GET['reset-link-sent'] ) ) { return wc_get_template( 'myaccount/lost-password-confirmation.php' ); - /** - * After reset, show confirmation message. - */ - } elseif ( ! empty( $_GET['reset'] ) ) { - wc_add_notice( __( 'Your password has been reset.', 'woocommerce' ) . ' ' . __( 'Log in', 'woocommerce' ) . '' ); - /** * Process reset key / login from email confirmation link */ diff --git a/readme.txt b/readme.txt index f444d00d4db..992ba0f52b2 100644 --- a/readme.txt +++ b/readme.txt @@ -162,6 +162,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc * Respect stock status and prevent the "out of stock threshold" setting affecting existing in-stock products. * Added Nigerian Provinces to i18n/state. * Improved handling of shop page rewrite rules to allow subpages. +* Redirect to login after password reset. [See changelog for all versions](https://raw.githubusercontent.com/woothemes/woocommerce/master/CHANGELOG.txt). From a816e8a92d4f74dff2634f0202c5ee36c26ff507 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 27 Jul 2016 13:48:10 +0100 Subject: [PATCH 163/298] APIClass and hook basics --- .../paypal/class-wc-gateway-paypal.php | 35 +++- .../class-wc-gateway-paypal-api-handler.php | 157 ++++++++++++++++++ .../class-wc-gateway-paypal-refund.php | 81 --------- 3 files changed, 186 insertions(+), 87 deletions(-) create mode 100644 includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php delete mode 100644 includes/gateways/paypal/includes/class-wc-gateway-paypal-refund.php diff --git a/includes/gateways/paypal/class-wc-gateway-paypal.php b/includes/gateways/paypal/class-wc-gateway-paypal.php index 0dd15e46296..c45254e2589 100644 --- a/includes/gateways/paypal/class-wc-gateway-paypal.php +++ b/includes/gateways/paypal/class-wc-gateway-paypal.php @@ -56,6 +56,8 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { self::$log_enabled = $this->debug; add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) ); + add_action( 'woocommerce_order_status_on-hold_to_processing', array( $this, 'capture_payment' ) ); + add_action( 'woocommerce_order_status_on-hold_to_completed', array( $this, 'capture_payment' ) ); if ( ! $this->is_valid_for_use() ) { $this->enabled = 'no'; @@ -256,6 +258,17 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { return $order && $order->get_transaction_id(); } + /** + * Init the API class and set the username/password etc. + */ + protected function init_api() { + include_once( dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-api-handler.php' ); + + WC_Gateway_Paypal_API_Handler::$api_username = $this->get_option( 'api_username' ); + WC_Gateway_Paypal_API_Handler::$api_password = $this->get_option( 'api_password' ); + WC_Gateway_Paypal_API_Handler::$api_signature = $this->get_option( 'api_signature' ); + } + /** * Process a refund if supported. * @param int $order_id @@ -271,13 +284,9 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { return new WP_Error( 'error', __( 'Refund Failed: No transaction ID', 'woocommerce' ) ); } - include_once( dirname( __FILE__ ) . '/includes/class-wc-gateway-paypal-refund.php' ); + $this->init_api(); - WC_Gateway_Paypal_Refund::$api_username = $this->get_option( 'api_username' ); - WC_Gateway_Paypal_Refund::$api_password = $this->get_option( 'api_password' ); - WC_Gateway_Paypal_Refund::$api_signature = $this->get_option( 'api_signature' ); - - $result = WC_Gateway_Paypal_Refund::refund_order( $order, $amount, $reason, $this->testmode ); + $result = WC_Gateway_Paypal_API_Handler::refund_order( $order, $amount, $reason, $this->testmode ); if ( is_wp_error( $result ) ) { $this->log( 'Refund Failed: ' . $result->get_error_message() ); @@ -296,4 +305,18 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { return isset( $result['L_LONGMESSAGE0'] ) ? new WP_Error( 'error', $result['L_LONGMESSAGE0'] ) : false; } + + /** + * Capture payment when the order is changed from on-hold to complete or processing + * + * @param int $order_id + */ + public function capture_payment( $order_id ) { + $order = wc_get_order( $order_id ); + + if ( 'paypal' === $order->payment_method ) { + $this->init_api(); + WC_Gateway_Paypal_API_Handler::do_capture( $order, $amount ); + } + } } diff --git a/includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php b/includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php new file mode 100644 index 00000000000..29ab4f0451e --- /dev/null +++ b/includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php @@ -0,0 +1,157 @@ + '84.0', + 'SIGNATURE' => self::$api_signature, + 'USER' => self::$api_username, + 'PWD' => self::$api_password, + 'METHOD' => 'DoCapture', + 'AUTHORIZATIONID' => $order->get_transaction_id(), + 'AMT' => number_format( $amount, 2, '.', '' ), + 'CURRENCYCODE' => $order->get_order_currency(), + 'COMPLETETYPE' => 'Complete', + ); + return apply_filters( 'woocommerce_paypal_capture_request', $request, $order, $amount ); + } + + /** + * Capture an authorization. + * @param WC_Order $order + * @param float $amount + * @return object Either an object of name value pairs for a success, or a WP_ERROR object. + */ + public static function do_capture( $order, $amount ) { + $response = wp_safe_remote_post( + $sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp', + array( + 'method' => 'POST', + 'body' => self::get_capture_request( $order, $amount ), + 'timeout' => 70, + 'user-agent' => 'WooCommerce', + 'httpversion' => '1.1' + ) + ); + + WC_Gateway_Paypal::log( 'DoCapture Response: ' . print_r( $response, true ) ); + + if ( empty( $response['body'] ) ) { + return new WP_Error( 'paypal-api', 'Empty Response' ); + } elseif ( is_wp_error( $response ) ) { + return $response; + } + + parse_str( $response['body'], $response_array ); + + return (object) $response_array; + } + + + /** + * Refund an order via PayPal. + * @param WC_Order $order + * @param float $amount + * @param string $reason + * @param bool $sandbox + * @return array|wp_error The parsed response from paypal, or a WP_Error object + */ + public static function refund_order( $order, $amount = null, $reason = '', $sandbox = false ) { + $response = wp_safe_remote_post( + $sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp', + array( + 'method' => 'POST', + 'body' => self::get_request( $order, $amount, $reason ), + 'timeout' => 70, + 'user-agent' => 'WooCommerce', + 'httpversion' => '1.1' + ) + ); + + WC_Gateway_Paypal::log( 'Refund Response: ' . print_r( $response, true ) ); + + if ( is_wp_error( $response ) ) { + return $response; + } + + if ( empty( $response['body'] ) ) { + return new WP_Error( 'paypal-refunds', 'Empty Response' ); + } + + parse_str( $response['body'], $response_array ); + + return $response_array; + } +} + +/** + * Here for backwards compatibility. + * @since 2.7.0 + */ +class WC_Gateway_Paypal_Refund extends WC_Gateway_Paypal_API_Handler { + /** + * Get refund request args. + * @param WC_Order $order + * @param float $amount + * @param string $reason + * @return array + */ + public static function get_request( $order, $amount = null, $reason = '' ) { + $request = array( + 'VERSION' => '84.0', + 'SIGNATURE' => self::$api_signature, + 'USER' => self::$api_username, + 'PWD' => self::$api_password, + 'METHOD' => 'RefundTransaction', + 'TRANSACTIONID' => $order->get_transaction_id(), + 'NOTE' => html_entity_decode( wc_trim_string( $reason, 255 ), ENT_NOQUOTES, 'UTF-8' ), + 'REFUNDTYPE' => 'Full' + ); + if ( ! is_null( $amount ) ) { + $request['AMT'] = number_format( $amount, 2, '.', '' ); + $request['CURRENCYCODE'] = $order->get_order_currency(); + $request['REFUNDTYPE'] = 'Partial'; + } + return apply_filters( 'woocommerce_paypal_refund_request', $request, $order, $amount, $reason ); + } + + /** + * Handle response from PayPal API. + */ + public static function handle_response( $response, $order ) { + + switch ( strtolower( $response['ACK'] ) ) { + case 'success': + case 'successwithwarning': + $order->add_order_note( sprintf( __( 'Refunded %s - Refund ID: %s', 'woocommerce' ), $response['GROSSREFUNDAMT'], $response['REFUNDTRANSACTIONID'] ) ); + return true; + break; + } + } +} diff --git a/includes/gateways/paypal/includes/class-wc-gateway-paypal-refund.php b/includes/gateways/paypal/includes/class-wc-gateway-paypal-refund.php deleted file mode 100644 index 0e80ab97ca6..00000000000 --- a/includes/gateways/paypal/includes/class-wc-gateway-paypal-refund.php +++ /dev/null @@ -1,81 +0,0 @@ - '84.0', - 'SIGNATURE' => self::$api_signature, - 'USER' => self::$api_username, - 'PWD' => self::$api_password, - 'METHOD' => 'RefundTransaction', - 'TRANSACTIONID' => $order->get_transaction_id(), - 'NOTE' => html_entity_decode( wc_trim_string( $reason, 255 ), ENT_NOQUOTES, 'UTF-8' ), - 'REFUNDTYPE' => 'Full' - ); - if ( ! is_null( $amount ) ) { - $request['AMT'] = number_format( $amount, 2, '.', '' ); - $request['CURRENCYCODE'] = $order->get_order_currency(); - $request['REFUNDTYPE'] = 'Partial'; - } - return apply_filters( 'woocommerce_paypal_refund_request', $request, $order, $amount, $reason ); - } - - /** - * Refund an order via PayPal. - * @param WC_Order $order - * @param float $amount - * @param string $reason - * @param bool $sandbox - * @return array|wp_error The parsed response from paypal, or a WP_Error object - */ - public static function refund_order( $order, $amount = null, $reason = '', $sandbox = false ) { - $response = wp_safe_remote_post( - $sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp', - array( - 'method' => 'POST', - 'body' => self::get_request( $order, $amount, $reason ), - 'timeout' => 70, - 'user-agent' => 'WooCommerce', - 'httpversion' => '1.1' - ) - ); - - WC_Gateway_Paypal::log( 'Refund Response: ' . print_r( $response, true ) ); - - if ( is_wp_error( $response ) ) { - return $response; - } - - if ( empty( $response['body'] ) ) { - return new WP_Error( 'paypal-refunds', 'Empty Response' ); - } - - parse_str( $response['body'], $response_array ); - - return $response_array; - } -} From a5d036d91cf7db81febecce79c82a55071e20532 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 27 Jul 2016 14:10:31 +0100 Subject: [PATCH 164/298] New function to generate query strings --- includes/wc-template-functions.php | 27 ++++++++++++++++++++++++++- templates/loop/orderby.php | 16 +--------------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 51e288a3b0a..7094c7abd95 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -337,6 +337,31 @@ function wc_product_post_class( $classes, $class = '', $post_id = '' ) { return $classes; } +/** + * Outputs hidden form inputs for each query string variable. + * @param array $values name value pairs + * @param array $exclude keys to exclude + * @since 2.7.0 + */ +function wc_query_string_form_fields( $values = null, $exclude = array(), $currentkey = '' ) { + if ( is_null( $values ) ) { + $values = $_GET; + } + foreach ( $values as $key => $value ) { + if ( in_array( $key, $exclude ) ) { + continue; + } + if ( $currentkey ) { + $key = $currentkey . '[' . $key . ']'; + } + if ( is_array( $value ) ) { + wc_query_string_form_fields( $value, $exclude, $key ); + } else { + echo ''; + } + } +} + /** Template pages ********************************************************/ if ( ! function_exists( 'woocommerce_content' ) ) { @@ -606,7 +631,7 @@ if ( ! function_exists( 'woocommerce_product_archive_description' ) ) { if ( is_search() ) { return; } - + if ( is_post_type_archive( 'product' ) && 0 === absint( get_query_var( 'paged' ) ) ) { $shop_page = get_post( wc_get_page_id( 'shop' ) ); if ( $shop_page ) { diff --git a/templates/loop/orderby.php b/templates/loop/orderby.php index f958159e5d1..f262297d35d 100644 --- a/templates/loop/orderby.php +++ b/templates/loop/orderby.php @@ -27,19 +27,5 @@ if ( ! defined( 'ABSPATH' ) ) { - $val ) { - if ( 'orderby' === $key || 'submit' === $key ) { - continue; - } - if ( is_array( $val ) ) { - foreach( $val as $innerVal ) { - echo ''; - } - } else { - echo ''; - } - } - ?> + From d45be39758c8e860f549d6d436938d087a4e71ab Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 27 Jul 2016 16:55:42 +0100 Subject: [PATCH 165/298] Capture and refund support --- .../paypal/class-wc-gateway-paypal.php | 34 +++- .../class-wc-gateway-paypal-api-handler.php | 166 +++++++++--------- .../class-wc-gateway-paypal-ipn-handler.php | 12 +- .../class-wc-gateway-paypal-pdt-handler.php | 53 +++--- 4 files changed, 155 insertions(+), 110 deletions(-) diff --git a/includes/gateways/paypal/class-wc-gateway-paypal.php b/includes/gateways/paypal/class-wc-gateway-paypal.php index c45254e2589..414f7b67582 100644 --- a/includes/gateways/paypal/class-wc-gateway-paypal.php +++ b/includes/gateways/paypal/class-wc-gateway-paypal.php @@ -267,6 +267,7 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { WC_Gateway_Paypal_API_Handler::$api_username = $this->get_option( 'api_username' ); WC_Gateway_Paypal_API_Handler::$api_password = $this->get_option( 'api_password' ); WC_Gateway_Paypal_API_Handler::$api_signature = $this->get_option( 'api_signature' ); + WC_Gateway_Paypal_API_Handler::$sandbox = $this->testmode; } /** @@ -286,7 +287,7 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { $this->init_api(); - $result = WC_Gateway_Paypal_API_Handler::refund_order( $order, $amount, $reason, $this->testmode ); + $result = WC_Gateway_Paypal_API_Handler::refund_transaction( $order, $amount, $reason ); if ( is_wp_error( $result ) ) { $this->log( 'Refund Failed: ' . $result->get_error_message() ); @@ -295,15 +296,15 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { $this->log( 'Refund Result: ' . print_r( $result, true ) ); - switch ( strtolower( $result['ACK'] ) ) { + switch ( strtolower( $result->ACK ) ) { case 'success': case 'successwithwarning': - $order->add_order_note( sprintf( __( 'Refunded %s - Refund ID: %s', 'woocommerce' ), $result['GROSSREFUNDAMT'], $result['REFUNDTRANSACTIONID'] ) ); + $order->add_order_note( sprintf( __( 'Refunded %s - Refund ID: %s', 'woocommerce' ), $result->GROSSREFUNDAMT, $result->REFUNDTRANSACTIONID ) ); return true; break; } - return isset( $result['L_LONGMESSAGE0'] ) ? new WP_Error( 'error', $result['L_LONGMESSAGE0'] ) : false; + return isset( $result->L_LONGMESSAGE0 ) ? new WP_Error( 'error', $result->L_LONGMESSAGE0 ) : false; } /** @@ -314,9 +315,30 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { public function capture_payment( $order_id ) { $order = wc_get_order( $order_id ); - if ( 'paypal' === $order->payment_method ) { + if ( 'paypal' === $order->payment_method && 'pending' === get_post_meta( $order->id, '_paypal_status', true ) && $order->get_transaction_id() ) { $this->init_api(); - WC_Gateway_Paypal_API_Handler::do_capture( $order, $amount ); + $result = WC_Gateway_Paypal_API_Handler::do_capture( $order ); + + if ( is_wp_error( $result ) ) { + $this->log( 'Capture Failed: ' . $result->get_error_message() ); + $order->add_order_note( sprintf( __( 'Payment could not captured: %s', 'woocommerce' ), $result->get_error_message() ) ); + return; + } + + $this->log( 'Capture Result: ' . print_r( $result, true ) ); + + if ( ! empty( $result->PAYMENTSTATUS ) ) { + switch ( $result->PAYMENTSTATUS ) { + case 'Completed' : + $order->add_order_note( sprintf( __( 'Payment of %s was captured - Auth ID: %s, Transaction ID: %s', 'woocommerce' ), $result->AMT, $result->AUTHORIZATIONID, $result->TRANSACTIONID ) ); + update_post_meta( $order->id, '_paypal_status', $result->PAYMENTSTATUS ); + update_post_meta( $order->id, '_transaction_id', $result->TRANSACTIONID ); + break; + default : + $order->add_order_note( sprintf( __( 'Payment could not captured - Auth ID: %s, Status: %s', 'woocommerce' ), $result->AUTHORIZATIONID, $result->PAYMENTSTATUS ) ); + break; + } + } } } } diff --git a/includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php b/includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php index 29ab4f0451e..dc3edcc901a 100644 --- a/includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php +++ b/includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php @@ -19,6 +19,9 @@ class WC_Gateway_Paypal_API_Handler { /** @var string API Signature */ public static $api_signature; + /** @var string API Signature */ + public static $sandbox = false; + /** * Get capture request args. * See https://developer.paypal.com/docs/classic/api/merchant/DoCapture_API_Operation_NVP/. @@ -35,86 +38,13 @@ class WC_Gateway_Paypal_API_Handler { 'PWD' => self::$api_password, 'METHOD' => 'DoCapture', 'AUTHORIZATIONID' => $order->get_transaction_id(), - 'AMT' => number_format( $amount, 2, '.', '' ), + 'AMT' => number_format( is_null( $amount ) ? $order->get_total() : $amount, 2, '.', '' ), 'CURRENCYCODE' => $order->get_order_currency(), 'COMPLETETYPE' => 'Complete', ); return apply_filters( 'woocommerce_paypal_capture_request', $request, $order, $amount ); } - /** - * Capture an authorization. - * @param WC_Order $order - * @param float $amount - * @return object Either an object of name value pairs for a success, or a WP_ERROR object. - */ - public static function do_capture( $order, $amount ) { - $response = wp_safe_remote_post( - $sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp', - array( - 'method' => 'POST', - 'body' => self::get_capture_request( $order, $amount ), - 'timeout' => 70, - 'user-agent' => 'WooCommerce', - 'httpversion' => '1.1' - ) - ); - - WC_Gateway_Paypal::log( 'DoCapture Response: ' . print_r( $response, true ) ); - - if ( empty( $response['body'] ) ) { - return new WP_Error( 'paypal-api', 'Empty Response' ); - } elseif ( is_wp_error( $response ) ) { - return $response; - } - - parse_str( $response['body'], $response_array ); - - return (object) $response_array; - } - - - /** - * Refund an order via PayPal. - * @param WC_Order $order - * @param float $amount - * @param string $reason - * @param bool $sandbox - * @return array|wp_error The parsed response from paypal, or a WP_Error object - */ - public static function refund_order( $order, $amount = null, $reason = '', $sandbox = false ) { - $response = wp_safe_remote_post( - $sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp', - array( - 'method' => 'POST', - 'body' => self::get_request( $order, $amount, $reason ), - 'timeout' => 70, - 'user-agent' => 'WooCommerce', - 'httpversion' => '1.1' - ) - ); - - WC_Gateway_Paypal::log( 'Refund Response: ' . print_r( $response, true ) ); - - if ( is_wp_error( $response ) ) { - return $response; - } - - if ( empty( $response['body'] ) ) { - return new WP_Error( 'paypal-refunds', 'Empty Response' ); - } - - parse_str( $response['body'], $response_array ); - - return $response_array; - } -} - -/** - * Here for backwards compatibility. - * @since 2.7.0 - */ -class WC_Gateway_Paypal_Refund extends WC_Gateway_Paypal_API_Handler { /** * Get refund request args. * @param WC_Order $order @@ -122,7 +52,7 @@ class WC_Gateway_Paypal_Refund extends WC_Gateway_Paypal_API_Handler { * @param string $reason * @return array */ - public static function get_request( $order, $amount = null, $reason = '' ) { + public static function get_refund_request( $order, $amount = null, $reason = '' ) { $request = array( 'VERSION' => '84.0', 'SIGNATURE' => self::$api_signature, @@ -142,16 +72,86 @@ class WC_Gateway_Paypal_Refund extends WC_Gateway_Paypal_API_Handler { } /** - * Handle response from PayPal API. + * Capture an authorization. + * @param WC_Order $order + * @param float $amount + * @return object Either an object of name value pairs for a success, or a WP_ERROR object. */ - public static function handle_response( $response, $order ) { + public static function do_capture( $order, $amount = null ) { + $raw_response = wp_safe_remote_post( + self::$sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp', + array( + 'method' => 'POST', + 'body' => self::get_capture_request( $order, $amount ), + 'timeout' => 70, + 'user-agent' => 'WooCommerce', + 'httpversion' => '1.1' + ) + ); - switch ( strtolower( $response['ACK'] ) ) { - case 'success': - case 'successwithwarning': - $order->add_order_note( sprintf( __( 'Refunded %s - Refund ID: %s', 'woocommerce' ), $response['GROSSREFUNDAMT'], $response['REFUNDTRANSACTIONID'] ) ); - return true; - break; + WC_Gateway_Paypal::log( 'DoCapture Response: ' . print_r( $raw_response, true ) ); + + if ( empty( $raw_response['body'] ) ) { + return new WP_Error( 'paypal-api', 'Empty Response' ); + } elseif ( is_wp_error( $raw_response ) ) { + return $raw_response; + } + + parse_str( $raw_response['body'], $response ); + + return (object) $response; + } + + /** + * Refund an order via PayPal. + * @param WC_Order $order + * @param float $amount + * @param string $reason + * @return object Either an object of name value pairs for a success, or a WP_ERROR object. + */ + public static function refund_transaction( $order, $amount = null, $reason = '' ) { + $raw_response = wp_safe_remote_post( + self::$sandbox ? 'https://api-3t.sandbox.paypal.com/nvp' : 'https://api-3t.paypal.com/nvp', + array( + 'method' => 'POST', + 'body' => self::get_refund_request( $order, $amount, $reason ), + 'timeout' => 70, + 'user-agent' => 'WooCommerce', + 'httpversion' => '1.1' + ) + ); + + WC_Gateway_Paypal::log( 'Refund Response: ' . print_r( $raw_response, true ) ); + + if ( empty( $raw_response['body'] ) ) { + return new WP_Error( 'paypal-api', 'Empty Response' ); + } elseif ( is_wp_error( $raw_response ) ) { + return $raw_response; + } + + parse_str( $raw_response['body'], $response ); + + return (object) $response; + } +} + +/** + * Here for backwards compatibility. + * @since 2.7.0 + */ +class WC_Gateway_Paypal_Refund extends WC_Gateway_Paypal_API_Handler { + public static function get_request( $order, $amount = null, $reason = '' ) { + return self::get_refund_request( $order, $amount, $reason ); + } + public static function refund_order( $order, $amount = null, $reason = '', $sandbox = false ) { + if ( $sandbox ) { + self::$sandbox = $sandbox; + } + $result = self::refund_transaction( $order, $amount, $reason ); + if ( is_wp_error( $result ) ) { + return $result; + } else { + return (array) $result; } } } diff --git a/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php b/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php index f33901d40a8..202a931519f 100644 --- a/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php +++ b/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php @@ -192,7 +192,11 @@ class WC_Gateway_Paypal_IPN_Handler extends WC_Gateway_Paypal_Response { } } else { - $this->payment_on_hold( $order, sprintf( __( 'Payment pending: %s', 'woocommerce' ), $posted['pending_reason'] ) ); + if ( 'authorization' === $posted['pending_reason'] ) { + $this->payment_on_hold( $order, __( 'Payment authorized. Change payment status to processing or complete to capture funds.', 'woocommerce' ) ); + } else { + $this->payment_on_hold( $order, sprintf( __( 'Payment pending (%s).', 'woocommerce' ), $posted['pending_reason'] ) ); + } } } @@ -304,6 +308,12 @@ class WC_Gateway_Paypal_IPN_Handler extends WC_Gateway_Paypal_Response { if ( ! empty( $posted['payment_type'] ) ) { update_post_meta( $order->id, 'Payment type', wc_clean( $posted['payment_type'] ) ); } + if ( ! empty( $posted['txn_id'] ) ) { + update_post_meta( $order->id, '_transaction_id', wc_clean( $posted['txn_id'] ) ); + } + if ( ! empty( $posted['payment_status'] ) ) { + update_post_meta( $order->id, '_paypal_status', wc_clean( $posted['payment_status'] ) ); + } } /** diff --git a/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php b/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php index 69d1dd2dc6b..2ef5b944ac4 100644 --- a/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php +++ b/includes/gateways/paypal/includes/class-wc-gateway-paypal-pdt-handler.php @@ -88,28 +88,41 @@ class WC_Gateway_Paypal_PDT_Handler extends WC_Gateway_Paypal_Response { $transaction_result = $this->validate_transaction( $transaction ); - if ( $transaction_result && 'completed' === $status ) { - if ( $order->get_total() != $amount ) { - WC_Gateway_Paypal::log( 'Payment error: Amounts do not match (amt ' . $amount . ')' ); - $this->payment_on_hold( $order, sprintf( __( 'Validation error: PayPal amounts do not match (amt %s).', 'woocommerce' ), $amount ) ); - } else { - $this->payment_complete( $order, $transaction, __( 'PDT payment completed', 'woocommerce' ) ); + WC_Gateway_Paypal::log( 'PDT Transaction Result: ' . print_r( $transaction_result, true ) ); - // Log paypal transaction fee and other meta data. - if ( ! empty( $transaction_result['mc_fee'] ) ) { - update_post_meta( $order->id, 'PayPal Transaction Fee', $transaction_result['mc_fee'] ); + update_post_meta( $order->id, '_paypal_status', $status ); + update_post_meta( $order->id, '_transaction_id', $transaction ); + + if ( $transaction_result ) { + if ( 'completed' === $status ) { + if ( $order->get_total() != $amount ) { + WC_Gateway_Paypal::log( 'Payment error: Amounts do not match (amt ' . $amount . ')' ); + $this->payment_on_hold( $order, sprintf( __( 'Validation error: PayPal amounts do not match (amt %s).', 'woocommerce' ), $amount ) ); + } else { + $this->payment_complete( $order, $transaction, __( 'PDT payment completed', 'woocommerce' ) ); + + // Log paypal transaction fee and other meta data. + if ( ! empty( $transaction_result['mc_fee'] ) ) { + update_post_meta( $order->id, 'PayPal Transaction Fee', $transaction_result['mc_fee'] ); + } + if ( ! empty( $transaction_result['payer_email'] ) ) { + update_post_meta( $order->id, 'Payer PayPal address', $transaction_result['payer_email'] ); + } + if ( ! empty( $transaction_result['first_name'] ) ) { + update_post_meta( $order->id, 'Payer first name', $transaction_result['first_name'] ); + } + if ( ! empty( $transaction_result['last_name'] ) ) { + update_post_meta( $order->id, 'Payer last name', $transaction_result['last_name'] ); + } + if ( ! empty( $transaction_result['payment_type'] ) ) { + update_post_meta( $order->id, 'Payment type', $transaction_result['payment_type'] ); + } } - if ( ! empty( $transaction_result['payer_email'] ) ) { - update_post_meta( $order->id, 'Payer PayPal address', $transaction_result['payer_email'] ); - } - if ( ! empty( $transaction_result['first_name'] ) ) { - update_post_meta( $order->id, 'Payer first name', $transaction_result['first_name'] ); - } - if ( ! empty( $transaction_result['last_name'] ) ) { - update_post_meta( $order->id, 'Payer last name', $transaction_result['last_name'] ); - } - if ( ! empty( $transaction_result['payment_type'] ) ) { - update_post_meta( $order->id, 'Payment type', $transaction_result['payment_type'] ); + } else { + if ( 'authorization' === $transaction_result['pending_reason'] ) { + $this->payment_on_hold( $order, __( 'Payment authorized. Change payment status to processing or complete to capture funds.', 'woocommerce' ) ); + } else { + $this->payment_on_hold( $order, sprintf( __( 'Payment pending (%s).', 'woocommerce' ), $transaction_result['pending_reason'] ) ); } } } From 15c63893261682066b371ad4b3463c44e0f1fbf9 Mon Sep 17 00:00:00 2001 From: Lee Willis Date: Wed, 27 Jul 2016 18:14:50 +0100 Subject: [PATCH 166/298] Delete method options when deleting method --- includes/class-wc-ajax.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/class-wc-ajax.php b/includes/class-wc-ajax.php index 2b3ddabb9ed..6fa67474aeb 100644 --- a/includes/class-wc-ajax.php +++ b/includes/class-wc-ajax.php @@ -3243,7 +3243,10 @@ class WC_AJAX { $method_id = $wpdb->get_var( $wpdb->prepare( "SELECT method_id FROM {$wpdb->prefix}woocommerce_shipping_zone_methods WHERE instance_id = %d", $instance_id ) ); if ( isset( $data['deleted'] ) ) { + $shipping_method = WC_Shipping_Zones::get_shipping_method( $instance_id ); + $option_key = $shipping_method->get_instance_option_key(); if ( $wpdb->delete( "{$wpdb->prefix}woocommerce_shipping_zone_methods", array( 'instance_id' => $instance_id ) ) ) { + delete_option( $option_key ); do_action( 'woocommerce_shipping_zone_method_deleted', $instance_id, $method_id, $zone_id ); } continue; From e255602d919155f487a45e5e7a9e34c4d0cdf4d4 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Thu, 21 Jul 2016 09:26:02 -0700 Subject: [PATCH 167/298] System status controller --- ...class-wc-rest-system-status-controller.php | 750 ++++++++++++++++++ includes/class-wc-api.php | 2 + includes/wc-rest-functions.php | 7 +- 3 files changed, 756 insertions(+), 3 deletions(-) create mode 100644 includes/api/class-wc-rest-system-status-controller.php diff --git a/includes/api/class-wc-rest-system-status-controller.php b/includes/api/class-wc-rest-system-status-controller.php new file mode 100644 index 00000000000..5b4b41f5e32 --- /dev/null +++ b/includes/api/class-wc-rest-system-status-controller.php @@ -0,0 +1,750 @@ +namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_collection_params(), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to view system status + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_rest_check_manager_permissions( 'system-status', 'read' ) ) { + // return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Get a system status info, by section. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function get_items( $request ) { + $schema = $this->get_item_schema(); + $mappings = $this->get_item_mappings(); + $response = array(); + + foreach ( $mappings as $section => $values ) { + settype( $values, $schema['properties'][ $section ]['type'] ); + foreach( $values as $key => $value ) { + if ( isset( $schema['properties'][ $section ]['properties'][ $key ]['type'] ) ) { + settype( $values[ $key ], $schema['properties'][ $section ]['properties'][ $key ]['type'] ); + } + } + $response[ $section ] = $values; + } + + return rest_ensure_response( $response ); + } + + /** + * Get the system status schema, conforming to JSON Schema. + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'system-status', + 'type' => 'object', + 'properties' => array( + 'environment' => array( + 'description' => __( 'Environment', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'home_url' => array( + 'description' => __( 'Home URL' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'site_url' => array( + 'description' => __( 'Site URL' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'wc_version' => array( + 'description' => __( 'WooCommerce Version' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'log_directory' => array( + 'description' => __( 'Log Directory' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'log_directory_writable' => array( + 'description' => __( 'Is Log Directory Writable?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'wp_version' => array( + 'description' => __( 'WordPress Version' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'wp_multisite' => array( + 'description' => __( 'Is WordPress Multisite?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'wp_memory_limit' => array( + 'description' => __( 'WordPress Memory Limit' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'wp_debug_mode' => array( + 'description' => __( 'Is WordPress Debug Mode Active?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'wp_cron' => array( + 'description' => __( 'Are WordPress Cron Jobs Enabled?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'language' => array( + 'description' => __( 'WordPress Language' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'server_info' => array( + 'description' => __( 'Server Info' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'php_version' => array( + 'description' => __( 'PHP Version' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'php_post_max_size' => array( + 'description' => __( 'PHP Post Max Size' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'php_max_execution_time' => array( + 'description' => __( 'PHP Max Execution Time' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'php_max_input_vars' => array( + 'description' => __( 'PHP Max Input Vars' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'curl_version' => array( + 'description' => __( 'cURL Version' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'suhosin_installed' => array( + 'description' => __( 'Is SUHOSIN Installed?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'max_upload_size' => array( + 'description' => __( 'Max Upload Size' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'mysql_version' => array( + 'description' => __( 'MySQL Version' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'default_timezone' => array( + 'description' => __( 'Default Timezone' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'fsockopen_or_curl_enabled' => array( + 'description' => __( 'Is fsockopen/cURL Enabled?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'soapclient_enabled' => array( + 'description' => __( 'Is SoapClient Class Enabled?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'domdocument_enabled' => array( + 'description' => __( 'Is DomDocument Class Enabled?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'gzip_enabled' => array( + 'description' => __( 'Is GZip Enabled?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'mbstring_enabled' => array( + 'description' => __( 'Is mbstring Enabled?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'remote_post_successful' => array( + 'description' => __( 'Remote POST Successful?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'remote_post_response' => array( + 'description' => __( 'Remote POST Response' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'remote_get_successful' => array( + 'description' => __( 'Remote GET Successful?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'remote_get_response' => array( + 'description' => __( 'Remote GET Response' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + ), + ), + 'database' => array( + 'description' => __( 'Database', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'wc_database_version' => array( + 'description' => __( 'WC Database Version' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'database_prefix' => array( + 'description' => __( 'Database Prefix' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'maxmind_geoip_database' => array( + 'description' => __( 'MaxMind GeoIP Database' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'database_tables' => array( + 'description' => __( 'Database Tables' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + ), + ) + ), + 'active_plugins' => array( + 'description' => __( 'Active Plugins', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + ), + 'theme' => array( + 'description' => __( 'Theme', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'name' => array( + 'description' => __( 'Theme Name' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'version' => array( + 'description' => __( 'Theme Version' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'author_url' => array( + 'description' => __( 'Theme Author URL' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + 'is_child_theme' => array( + 'description' => __( 'Is this theme a child theme?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'has_woocommerce_support' => array( + 'description' => __( 'Does the theme declare WooCommerce support?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'overrides' => array( + 'description' => __( 'Template Overrides', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + ), + 'parent_name' => array( + 'description' => __( 'Parent Theme Name' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'parent_version' => array( + 'description' => __( 'Parent Theme Version' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'parent_author_url' => array( + 'description' => __( 'Parent Theme Author URL' ), + 'type' => 'string', + 'format' => 'uri', + 'context' => array( 'view', 'edit' ), + ), + ) + ), + 'settings' => array( + 'description' => __( 'Settings', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + 'properties' => array( + 'api_enabled' => array( + 'description' => __( 'REST API Enabled?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'force_ssl' => array( + 'description' => __( 'SSL Forced?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'currency' => array( + 'description' => __( 'Currency' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'currency_symbol' => array( + 'description' => __( 'Currency Symbol' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'currency_position' => array( + 'description' => __( 'Currency Position' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'thousand_separator' => array( + 'description' => __( 'Thousand Separator' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'decimal_separator' => array( + 'description' => __( 'Decimal Separator' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), + 'number_of_decimals' => array( + 'description' => __( 'Number of Decimals' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + ), + 'geolocation_enabled' => array( + 'description' => __( 'Geolocation Enabled?' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'taxonomies' => array( + 'description' => __( 'Taxonomy Terms for Product/Order Statuses' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + ), + ) + ), + 'wc_pages' => array( + 'description' => __( 'WooCommerce Pages', 'woocommerce' ), + 'type' => 'array', + 'context' => array( 'view', 'edit' ), + ), + ) + ); + + return $this->add_additional_fields_schema( $schema ); + } + + /** + * Return an array of sections and the data associated with each + * + * @return array + */ + public function get_item_mappings() { + global $wpdb; + + // Matches schema + return array( + 'environment' => $this->get_environment_info(), + 'database' => $this->get_database_info(), + 'active_plugins' => $this->get_active_plugins(), + 'theme' => $this->get_theme_info(), + 'settings' => $this->get_settings(), + 'wc_pages' => $this->get_wc_pages(), + ); + } + + /** + * Get array of environment information. Includes thing like software + * versions, and various server settings. + * + * @return array + */ + public function get_environment_info() { + global $wpdb; + + // Figure out cURL version, if installed. + $curl_version = ''; + if ( function_exists( 'curl_version' ) ) { + $curl_version = curl_version(); + $curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version']; + } + + // WP memory limit + $wp_memory_limit = wc_let_to_num( WP_MEMORY_LIMIT ); + if ( function_exists( 'memory_get_usage' ) ) { + $wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) ); + } + + // Test POST requests + $post_response = wp_safe_remote_post( 'https://www.paypal.com/cgi-bin/webscr', array( + 'timeout' => 60, + 'user-agent' => 'WooCommerce/' . WC()->version, + 'httpversion' => '1.1', + 'body' => array( + 'cmd' => '_notify-validate' + ) + ) ); + $post_response_successful = false; + if ( ! is_wp_error( $post_response ) && $post_response['response']['code'] >= 200 && $post_response['response']['code'] < 300 ) { + $post_response_successful = true; + } + + // Test GET requests + $get_response = wp_safe_remote_get( 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=' . ( is_multisite() ? '1' : '0' ) ); + $get_response_successful = false; + if ( ! is_wp_error( $post_response ) && $post_response['response']['code'] >= 200 && $post_response['response']['code'] < 300 ) { + $get_response_successful = true; + } + + // Return all environment info. Described by JSON Schema. + return array( + 'home_url' => get_option( 'home' ), + 'site_url' => get_option( 'siteurl' ), + 'wc_version' => WC()->version, + 'log_directory' => WC_LOG_DIR, + 'log_directory_writable' => ( @fopen( WC_LOG_DIR . 'test-log.log', 'a' ) ? true : false ), + 'wp_version' => get_bloginfo('version'), + 'wp_multisite' => is_multisite(), + 'wp_memory_limit' => $wp_memory_limit, + 'wp_debug_mode' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ), + 'wp_cron' => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ), + 'language' => get_locale(), + 'server_info' => $_SERVER['SERVER_SOFTWARE'], + 'php_version' => phpversion(), + 'php_post_max_size' => wc_let_to_num( ini_get( 'post_max_size' ) ), + 'php_max_execution_time' => ini_get( 'max_execution_time' ), + 'php_max_input_vars' => ini_get( 'max_input_vars' ), + 'curl_version' => $curl_version, + 'suhosin_installed' => extension_loaded( 'suhosin' ), + 'max_upload_size' => wp_max_upload_size(), + 'mysql_version' => ( ! empty( $wpdb->is_mysql ) ? $wpdb->db_version() : '' ), + 'default_timezone' => date_default_timezone_get(), + 'fsockopen_or_curl_enabled' => ( function_exists( 'fsockopen' ) || function_exists( 'curl_init' ) ), + 'soapclient_enabled' => class_exists( 'SoapClient' ), + 'domdocument_enabled' => class_exists( 'DOMDocument' ), + 'gzip_enabled' => is_callable( 'gzopen' ), + 'mbstring_enabled' => extension_loaded( 'mbstring' ), + 'remote_post_successful' => $post_response_successful, + 'remote_post_response' => ( is_wp_error( $post_response ) ? $post_response->get_error_message() : $post_response['response']['code'] ), + 'remote_get_successful' => $get_response_successful, + 'remote_get_response' => ( is_wp_error( $get_response ) ? $get_response->get_error_message() : $get_response['response']['code'] ), + ); + } + + /** + * Get array of database information. Version, prefix, and table existence. + * + * @return array + */ + public function get_database_info() { + global $wpdb; + + // WC Core tables to check existence of + $tables = array( + 'woocommerce_sessions', + 'woocommerce_api_keys', + 'woocommerce_attribute_taxonomies', + 'woocommerce_downloadable_product_permissions', + 'woocommerce_order_items', + 'woocommerce_order_itemmeta', + 'woocommerce_tax_rates', + 'woocommerce_tax_rate_locations', + 'woocommerce_shipping_zones', + 'woocommerce_shipping_zone_locations', + 'woocommerce_shipping_zone_methods', + 'woocommerce_payment_tokens', + 'woocommerce_payment_tokenmeta', + ); + + if ( get_option( 'db_version' ) < 34370 ) { + $tables[] = 'woocommerce_termmeta'; + } + $table_exists = array(); + foreach ( $tables as $table ) { + $table_exists[ $table ] = ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s;", $wpdb->prefix . $table ) ) === $wpdb->prefix . $table ); + } + + // Return all database info. Described by JSON Schema. + return array( + 'wc_database_version' => get_option( 'woocommerce_db_version' ), + 'database_prefix' => $wpdb->prefix, + 'maxmind_geoip_database' => WC_Geolocation::get_local_database_path(), + 'database_tables' => $table_exists, + ); + } + + /** + * Get a list of plugins active on the site. + * + * @return array + */ + public function get_active_plugins() { + require_once( ABSPATH . 'wp-admin/includes/plugin.php' ); + + // Get both site plugins and network plugins + $active_plugins = (array) get_option( 'active_plugins', array() ); + if ( is_multisite() ) { + $network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) ); + $active_plugins = array_merge( $active_plugins, $network_activated_plugins ); + } + + $active_plugins_data = array(); + foreach ( $active_plugins as $plugin ) { + $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); + // convert plugin data to json response format. + $active_plugins_data[] = array( + 'name' => $data['Name'], + 'version' => $data['Version'], + 'url' => $data['PluginURI'], + 'author_name' => $data['AuthorName'], + 'author_url' => esc_url_raw( $data['AuthorURI'] ), + ); + } + + return $active_plugins_data; + } + + /** + * Get info on the current active theme, info on parent theme (if presnet) + * and a list of template overrides. + * + * @return array + */ + public function get_theme_info() { + $active_theme = wp_get_theme(); + + // Get parent theme info if this theme is a child theme, otherwise + // pass empty info in the response. + if( is_child_theme() ) { + $parent_theme = wp_get_theme( $active_theme->Template ); + $parent_theme_info = array( + 'parent_name' => $parent_theme->Name, + 'parentversion' => $parent_theme->Version, + 'parent_author_url' => $parent_theme->{'Author URI'}, + ); + } else { + $parent_theme_info = array( 'parent_theme_name' => '', 'parent_theme_version' => '', 'parent_theme_author_url' => '' ); + } + + /** + * Scan the theme directory for all WC templates to see if our theme + * overrides any of them. + */ + $override_files = array(); + $scan_files = WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' ); + foreach ( $scan_files as $file ) { + if ( file_exists( get_stylesheet_directory() . '/' . $file ) ) { + $theme_file = get_stylesheet_directory() . '/' . $file; + } elseif ( file_exists( get_stylesheet_directory() . '/woocommerce/' . $file ) ) { + $theme_file = get_stylesheet_directory() . '/woocommerce/' . $file; + } elseif ( file_exists( get_template_directory() . '/' . $file ) ) { + $theme_file = get_template_directory() . '/' . $file; + } elseif ( file_exists( get_template_directory() . '/woocommerce/' . $file ) ) { + $theme_file = get_template_directory() . '/woocommerce/' . $file; + } else { + $theme_file = false; + } + + if ( ! empty( $theme_file ) ) { + $override_files[] = str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ); + } + } + + $active_theme_info = array( + 'name' => $active_theme->Name, + 'version' => $active_theme->Version, + 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), + 'is_child_theme' => is_child_theme(), + 'has_woocommerce_support' => ( current_theme_supports( 'woocommerce' ) || in_array( $active_theme->template, wc_get_core_supported_themes() ) ), + 'overrides' => $override_files, + ); + + return array_merge( $active_theme_info, $parent_theme_info ); + } + + /** + * Get some setting values for the site that are useful for debugging + * purposes. For full settings access, use the settings api. + * + * @return array + */ + public function get_settings() { + // Get a list of terms used for product/order taxonomies + $term_response = array(); + $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); + foreach ( $terms as $term ) { + $term_response[ $term->slug ] = strtolower( $term->name ); + } + + // Return array of useful settings for debugging. + return array( + 'api_enabled' => 'yes' === get_option( 'woocommerce_api_enabled' ), + 'force_ssl' => 'yes' === get_option( 'woocommerce_force_ssl_checkout' ), + 'currency' => get_woocommerce_currency(), + 'currency_symbol' => get_woocommerce_currency_symbol(), + 'currency_position' => get_option( 'woocommerce_currency_pos' ), + 'thousand_separator' => wc_get_price_thousand_separator(), + 'decimal_separator' => wc_get_price_decimal_separator(), + 'number_of_decimals' => wc_get_price_decimals(), + 'geolocation_enabled' => in_array( get_option( 'woocommerce_default_customer_address' ), array( 'geolocation_ajax', 'geolocation' ) ), + 'taxonomies' => $term_response, + ); + } + + /** + * Returns a mini-report on WC pages and if they are configured correctly: + * Present, visible, and including the correct shortcode. + * + * @return array + */ + public function get_wc_pages() { + // WC pages to check against + $check_pages = array( + _x( 'Shop Base', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_shop_page_id', + 'shortcode' => '', + ), + _x( 'Cart', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_cart_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', + ), + _x( 'Checkout', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_checkout_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', + ), + _x( 'My Account', 'Page setting', 'woocommerce' ) => array( + 'option' => 'woocommerce_myaccount_page_id', + 'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', + ), + ); + + $pages_output = array(); + foreach ( $check_pages as $page_name => $values ) { + $errors = array(); + $page_id = get_option( $values['option'] ); + $page_set = $page_exists = $page_visible = false; + $shortcode_present = $shortcode_required = false; + + // Page checks + if ( $page_id ) { + $page_set = true; + } + if ( get_post( $page_id ) ) { + $page_exists = true; + } + if ( 'publish' === get_post_status( $page_id ) ) { + $page_visible = true; + } + + // Shortcode checks + if ( $values['shortcode'] && get_post( $page_id ) ) { + $shortcode_required = true; + $page = get_post( $page_id ); + if ( strstr( $page->post_content, $values['shortcode'] ) ) { + $shortcode_present = true; + } + } + + // Wrap up our findings into an output array + $pages_output[] = array( + 'page_name' => $page_name, + 'page_id' => $page_id, + 'page_set' => $page_set, + 'page_exists' => $page_exists, + 'page_visible' => $page_visible, + 'shortcode_required' => $shortcode_required, + 'shortcode_present' => $shortcode_present, + ); + } + + return $pages_output; + } + + /** + * Get any query params needed. + * + * @return array + */ + public function get_collection_params() { + return array( + 'context' => $this->get_context_param( array( 'default' => 'view' ) ), + ); + } + +} diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 68d7fa42104..c3f0b8817ff 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -169,6 +169,7 @@ class WC_API extends WC_Legacy_API { include_once( dirname( __FILE__ ) . '/api/class-wc-rest-taxes-controller.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-webhook-deliveries.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-webhooks-controller.php' ); + include_once( dirname( __FILE__ ) . 'api/class-wc-rest-system-status-controller.php' ); } /** @@ -202,6 +203,7 @@ class WC_API extends WC_Legacy_API { 'WC_REST_Taxes_Controller', 'WC_REST_Webhook_Deliveries_Controller', 'WC_REST_Webhooks_Controller', + 'WC_REST_System_Status_Controller', ); foreach ( $controllers as $controller ) { diff --git a/includes/wc-rest-functions.php b/includes/wc-rest-functions.php index ddb3dfeb2f8..a62195fe9ef 100644 --- a/includes/wc-rest-functions.php +++ b/includes/wc-rest-functions.php @@ -306,9 +306,10 @@ function wc_rest_check_product_term_permissions( $taxonomy, $context = 'read', $ */ function wc_rest_check_manager_permissions( $object, $context = 'read' ) { $objects = array( - 'reports' => 'view_woocommerce_reports', - 'settings' => 'manage_woocommerce', - 'attributes' => 'manage_product_terms', + 'reports' => 'view_woocommerce_reports', + 'settings' => 'manage_woocommerce', + 'system-status' => 'manage_woocommerce', + 'attributes' => 'manage_product_terms', ); $permission = current_user_can( $objects[ $object ] ); From 8c682d751095126955a178429fd7be4418644470 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 26 Jul 2016 10:23:36 -0700 Subject: [PATCH 168/298] Test base --- tests/unit-tests/api/system-status/info.php | 39 +++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/unit-tests/api/system-status/info.php diff --git a/tests/unit-tests/api/system-status/info.php b/tests/unit-tests/api/system-status/info.php new file mode 100644 index 00000000000..96ed676bb05 --- /dev/null +++ b/tests/unit-tests/api/system-status/info.php @@ -0,0 +1,39 @@ +server = $wp_rest_server = new WP_Test_Spy_REST_Server; + do_action( 'rest_api_init' ); + } + + /** + * Unset the server. + */ + public function tearDown() { + parent::tearDown(); + global $wp_rest_server; + $wp_rest_server = null; + } + + /** + * Test route registration. + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v1/system-status', $routes ); + } + + +} From 817ed71d2a55a4ae732da78444f1c8bdee025b60 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 27 Jul 2016 10:26:35 -0700 Subject: [PATCH 169/298] Test file rename --- .../unit-tests/api/{system-status/info.php => system-status.php} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/unit-tests/api/{system-status/info.php => system-status.php} (100%) diff --git a/tests/unit-tests/api/system-status/info.php b/tests/unit-tests/api/system-status.php similarity index 100% rename from tests/unit-tests/api/system-status/info.php rename to tests/unit-tests/api/system-status.php From 8c5678f9676ab8c461d3650956f657aeec139ff7 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 27 Jul 2016 15:52:02 -0300 Subject: [PATCH 170/298] [2.6] Fixed shipping classes URLs, closes #11542 cc @mikejolley --- includes/shipping/flat-rate/includes/settings-flat-rate.php | 2 +- .../shipping/legacy-flat-rate/includes/settings-flat-rate.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/shipping/flat-rate/includes/settings-flat-rate.php b/includes/shipping/flat-rate/includes/settings-flat-rate.php index e6f304cf4c3..7f0cd8a1831 100644 --- a/includes/shipping/flat-rate/includes/settings-flat-rate.php +++ b/includes/shipping/flat-rate/includes/settings-flat-rate.php @@ -44,7 +44,7 @@ if ( ! empty( $shipping_classes ) ) { 'title' => __( 'Shipping Class Costs', 'woocommerce' ), 'type' => 'title', 'default' => '', - 'description' => sprintf( __( 'These costs can optionally be added based on the %sproduct shipping class%s.', 'woocommerce' ), '', '' ) + 'description' => sprintf( __( 'These costs can optionally be added based on the %sproduct shipping class%s.', 'woocommerce' ), '', '' ) ); foreach ( $shipping_classes as $shipping_class ) { if ( ! isset( $shipping_class->term_id ) ) { diff --git a/includes/shipping/legacy-flat-rate/includes/settings-flat-rate.php b/includes/shipping/legacy-flat-rate/includes/settings-flat-rate.php index a5ee38a0542..9e3f2a307d8 100644 --- a/includes/shipping/legacy-flat-rate/includes/settings-flat-rate.php +++ b/includes/shipping/legacy-flat-rate/includes/settings-flat-rate.php @@ -71,7 +71,7 @@ if ( ! empty( $shipping_classes ) ) { 'title' => __( 'Shipping Class Costs', 'woocommerce' ), 'type' => 'title', 'default' => '', - 'description' => sprintf( __( 'These costs can optionally be added based on the %sproduct shipping class%s.', 'woocommerce' ), '', '' ) + 'description' => sprintf( __( 'These costs can optionally be added based on the %sproduct shipping class%s.', 'woocommerce' ), '', '' ) ); foreach ( $shipping_classes as $shipping_class ) { if ( ! isset( $shipping_class->term_id ) ) { From 63a570f161f2f27e06392860fdb39ad082c6e0a2 Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 27 Jul 2016 16:16:54 -0300 Subject: [PATCH 171/298] [2.6] Display proper screen render text for custom range reports, closes #11543 --- includes/admin/views/html-report-by-date.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/includes/admin/views/html-report-by-date.php b/includes/admin/views/html-report-by-date.php index 6a80f6e0211..2abde0b0322 100644 --- a/includes/admin/views/html-report-by-date.php +++ b/includes/admin/views/html-report-by-date.php @@ -12,7 +12,11 @@ if ( ! defined( 'ABSPATH' ) ) {
    -

    + +

    + +

    +
    get_export_button(); ?> From 041b5745b4f8c9f44af6e91a54aebc0f63419ee9 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 27 Jul 2016 12:19:14 -0700 Subject: [PATCH 172/298] Finish system status tests --- ...class-wc-rest-system-status-controller.php | 2 +- includes/class-wc-api.php | 2 +- tests/unit-tests/api/system-status.php | 184 ++++++++++++++++-- 3 files changed, 169 insertions(+), 19 deletions(-) diff --git a/includes/api/class-wc-rest-system-status-controller.php b/includes/api/class-wc-rest-system-status-controller.php index 5b4b41f5e32..b2bd58890d7 100644 --- a/includes/api/class-wc-rest-system-status-controller.php +++ b/includes/api/class-wc-rest-system-status-controller.php @@ -57,7 +57,7 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { */ public function get_items_permissions_check( $request ) { if ( ! wc_rest_check_manager_permissions( 'system-status', 'read' ) ) { - // return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index c3f0b8817ff..98e575b51f3 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -169,7 +169,7 @@ class WC_API extends WC_Legacy_API { include_once( dirname( __FILE__ ) . '/api/class-wc-rest-taxes-controller.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-webhook-deliveries.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-webhooks-controller.php' ); - include_once( dirname( __FILE__ ) . 'api/class-wc-rest-system-status-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-system-status-controller.php' ); } /** diff --git a/tests/unit-tests/api/system-status.php b/tests/unit-tests/api/system-status.php index 96ed676bb05..50313c9133b 100644 --- a/tests/unit-tests/api/system-status.php +++ b/tests/unit-tests/api/system-status.php @@ -4,27 +4,17 @@ * @package WooCommerce\Tests\API * @since 2.7 */ -class WC_Tests_REST_System_Status extends WC_Unit_Test_Case { - - protected $server; +class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { /** - * Setup our test server. - */ + * Setup our test server. + */ public function setUp() { parent::setUp(); - global $wp_rest_server; - $this->server = $wp_rest_server = new WP_Test_Spy_REST_Server; - do_action( 'rest_api_init' ); - } - - /** - * Unset the server. - */ - public function tearDown() { - parent::tearDown(); - global $wp_rest_server; - $wp_rest_server = null; + $this->endpoint = new WC_REST_System_Status_Controller(); + $this->user = $this->factory->user->create( array( + 'role' => 'administrator', + ) ); } /** @@ -35,5 +25,165 @@ class WC_Tests_REST_System_Status extends WC_Unit_Test_Case { $this->assertArrayHasKey( '/wc/v1/system-status', $routes ); } + /** + * Test to make sure system status cannot be accessed without valid creds + * + * @since 2.7.0 + */ + public function test_get_system_status_info_without_permission() { + wp_set_current_user( 0 ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test to make sure root properties are present. + * (environment, theme, database, etc). + * + * @since 2.7.0 + */ + public function test_get_system_status_info_returns_root_properties() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $data = $response->get_data(); + + $this->assertArrayHasKey( 'environment', $data ); + $this->assertArrayHasKey( 'database', $data ); + $this->assertArrayHasKey( 'active_plugins', $data ); + $this->assertArrayHasKey( 'theme', $data ); + $this->assertArrayHasKey( 'settings', $data ); + $this->assertArrayHasKey( 'wc_pages', $data ); + } + + /** + * Test to make sure environment response is correct. + * + * @since 2.7.0 + */ + public function test_get_system_status_info_environment() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $data = $response->get_data(); + $environment = $data['environment']; + + // Make sure all expected data is present + $this->assertEquals( 30, count( $environment ) ); + + // Test some responses to make sure they match up + $this->assertEquals( get_option( 'home' ), $environment['home_url'] ); + $this->assertEquals( get_option( 'siteurl' ), $environment['site_url'] ); + $this->assertEquals( WC()->version, $environment['wc_version'] ); + } + + /** + * Test to make sure database response is correct. + * + * @since 2.7.0 + */ + public function test_get_system_status_info_database() { + global $wpdb; + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $data = $response->get_data(); + $database = $data['database']; + + $this->assertEquals( get_option( 'woocommerce_db_version' ), $database['wc_database_version'] ); + $this->assertEquals( $wpdb->prefix, $database['database_prefix'] ); + $this->assertEquals( WC_Geolocation::get_local_database_path(), $database['maxmind_geoip_database'] ); + $this->assertArrayHasKey( 'woocommerce_payment_tokens', $database['database_tables'] ); + } + + /** + * Test to make sure active plugins response is correct. + * + * @since 2.7.0 + */ + public function test_get_system_status_info_active_plugins() { + wp_set_current_user( $this->user ); + + $actual_plugins = array( 'hello.php' ); + update_option( 'active_plugins', $actual_plugins ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + update_option( 'active_plugins', array() ); + + $data = $response->get_data(); + $plugins = $data['active_plugins']; + + $this->assertEquals( 1, count( $plugins ) ); + $this->assertEquals( 'Hello Dolly', $plugins[0]['name'] ); + } + + /** + * Test to make sure theme response is correct. + * + * @since 2.7.0 + */ + public function test_get_system_status_info_theme() { + wp_set_current_user( $this->user ); + $active_theme = wp_get_theme(); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $data = $response->get_data(); + $theme = $data['theme']; + + $this->assertEquals( 9, count( $theme ) ); + $this->assertEquals( $active_theme->Name, $theme['name'] ); + } + + /** + * Test to make sure settings response is correct. + * + * @since 2.7.0 + */ + public function test_get_system_status_info_settings() { + wp_set_current_user( $this->user ); + + $term_response = array(); + $terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) ); + foreach ( $terms as $term ) { + $term_response[ $term->slug ] = strtolower( $term->name ); + } + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $data = $response->get_data(); + $settings = $data['settings']; + + $this->assertEquals( 10, count( $settings ) ); + $this->assertEquals( ( 'yes' === get_option( 'woocommerce_api_enabled' ) ), $settings['api_enabled'] ); + $this->assertEquals( get_woocommerce_currency(), $settings['currency'] ); + $this->assertEquals( $term_response, $settings['taxonomies'] ); + } + + /** + * Test to make sure wc_pages response is correct. + * + * @since 2.7.0 + */ + public function test_get_system_status_info_wc_pages() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $data = $response->get_data(); + $wc_pages = $data['wc_pages']; + $this->assertEquals( 4, count( $wc_pages ) ); + } + + /** + * Test system status schema. + * + * @since 2.7.0 + */ + public function test_system_status_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v1/system-status' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 6, count( $properties ) ); + $this->assertArrayHasKey( 'environment', $properties ); + $this->assertArrayHasKey( 'database', $properties ); + $this->assertArrayHasKey( 'active_plugins', $properties ); + $this->assertArrayHasKey( 'theme', $properties ); + $this->assertArrayHasKey( 'settings', $properties ); + $this->assertArrayHasKey( 'wc_pages', $properties ); + } } From a5ba8a05edc9d89a8d0fe27a60056e546e73f17d Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Wed, 27 Jul 2016 17:52:11 -0300 Subject: [PATCH 173/298] Fixed checkboxes in the admin settings This allow set yes/no or null/1 for checkboxes cc @mikejolley @jeffstieler --- includes/admin/class-wc-admin-settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/admin/class-wc-admin-settings.php b/includes/admin/class-wc-admin-settings.php index e53ed09ea3e..d2c8bc3e516 100644 --- a/includes/admin/class-wc-admin-settings.php +++ b/includes/admin/class-wc-admin-settings.php @@ -697,7 +697,7 @@ class WC_Admin_Settings { // Format the value based on option type. switch ( $option['type'] ) { case 'checkbox' : - $value = in_array( $raw_value, array( 'yes', 'no' ) ) ? $raw_value : 'no'; + $value = '1' === $raw_value || 'yes' === $raw_value ? 'yes' : 'no'; break; case 'textarea' : $value = wp_kses_post( trim( $raw_value ) ); From e436e96654bc55fcdd4aa845050b02d70dfa4ba9 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 27 Jul 2016 13:59:16 -0700 Subject: [PATCH 174/298] Add missing textdomains, remove wc_ prefix from a few fields, spacing/coding standard fixes. --- ...class-wc-rest-system-status-controller.php | 123 +++++++++--------- tests/unit-tests/api/system-status.php | 14 +- 2 files changed, 67 insertions(+), 70 deletions(-) diff --git a/includes/api/class-wc-rest-system-status-controller.php b/includes/api/class-wc-rest-system-status-controller.php index b2bd58890d7..f2961ba6292 100644 --- a/includes/api/class-wc-rest-system-status-controller.php +++ b/includes/api/class-wc-rest-system-status-controller.php @@ -50,7 +50,7 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { } /** - * Check whether a given request has permission to view system status + * Check whether a given request has permission to view system status. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean @@ -75,7 +75,7 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { foreach ( $mappings as $section => $values ) { settype( $values, $schema['properties'][ $section ]['type'] ); - foreach( $values as $key => $value ) { + foreach ( $values as $key => $value ) { if ( isset( $schema['properties'][ $section ]['properties'][ $key ]['type'] ) ) { settype( $values[ $key ], $schema['properties'][ $section ]['properties'][ $key ]['type'] ); } @@ -103,154 +103,154 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { 'context' => array( 'view', 'edit' ), 'properties' => array( 'home_url' => array( - 'description' => __( 'Home URL' ), + 'description' => __( 'Home URL', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'site_url' => array( - 'description' => __( 'Site URL' ), + 'description' => __( 'Site URL', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'wc_version' => array( - 'description' => __( 'WooCommerce Version' ), + 'description' => __( 'WooCommerce Version', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'log_directory' => array( - 'description' => __( 'Log Directory' ), + 'description' => __( 'Log Directory', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'log_directory_writable' => array( - 'description' => __( 'Is Log Directory Writable?' ), + 'description' => __( 'Is Log Directory Writable?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'wp_version' => array( - 'description' => __( 'WordPress Version' ), + 'description' => __( 'WordPress Version', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'wp_multisite' => array( - 'description' => __( 'Is WordPress Multisite?' ), + 'description' => __( 'Is WordPress Multisite?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'wp_memory_limit' => array( - 'description' => __( 'WordPress Memory Limit' ), + 'description' => __( 'WordPress Memory Limit', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'wp_debug_mode' => array( - 'description' => __( 'Is WordPress Debug Mode Active?' ), + 'description' => __( 'Is WordPress Debug Mode Active?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'wp_cron' => array( - 'description' => __( 'Are WordPress Cron Jobs Enabled?' ), + 'description' => __( 'Are WordPress Cron Jobs Enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'language' => array( - 'description' => __( 'WordPress Language' ), + 'description' => __( 'WordPress Language', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'server_info' => array( - 'description' => __( 'Server Info' ), + 'description' => __( 'Server Info', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'php_version' => array( - 'description' => __( 'PHP Version' ), + 'description' => __( 'PHP Version', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'php_post_max_size' => array( - 'description' => __( 'PHP Post Max Size' ), + 'description' => __( 'PHP Post Max Size', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'php_max_execution_time' => array( - 'description' => __( 'PHP Max Execution Time' ), + 'description' => __( 'PHP Max Execution Time', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'php_max_input_vars' => array( - 'description' => __( 'PHP Max Input Vars' ), + 'description' => __( 'PHP Max Input Vars', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'curl_version' => array( - 'description' => __( 'cURL Version' ), + 'description' => __( 'cURL Version', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'suhosin_installed' => array( - 'description' => __( 'Is SUHOSIN Installed?' ), + 'description' => __( 'Is SUHOSIN Installed?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'max_upload_size' => array( - 'description' => __( 'Max Upload Size' ), + 'description' => __( 'Max Upload Size', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'mysql_version' => array( - 'description' => __( 'MySQL Version' ), + 'description' => __( 'MySQL Version', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'default_timezone' => array( - 'description' => __( 'Default Timezone' ), + 'description' => __( 'Default Timezone', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'fsockopen_or_curl_enabled' => array( - 'description' => __( 'Is fsockopen/cURL Enabled?' ), + 'description' => __( 'Is fsockopen/cURL Enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'soapclient_enabled' => array( - 'description' => __( 'Is SoapClient Class Enabled?' ), + 'description' => __( 'Is SoapClient Class Enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'domdocument_enabled' => array( - 'description' => __( 'Is DomDocument Class Enabled?' ), + 'description' => __( 'Is DomDocument Class Enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'gzip_enabled' => array( - 'description' => __( 'Is GZip Enabled?' ), + 'description' => __( 'Is GZip Enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'mbstring_enabled' => array( - 'description' => __( 'Is mbstring Enabled?' ), + 'description' => __( 'Is mbstring Enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'remote_post_successful' => array( - 'description' => __( 'Remote POST Successful?' ), + 'description' => __( 'Remote POST Successful?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'remote_post_response' => array( - 'description' => __( 'Remote POST Response' ), + 'description' => __( 'Remote POST Response', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'remote_get_successful' => array( - 'description' => __( 'Remote GET Successful?' ), + 'description' => __( 'Remote GET Successful?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'remote_get_response' => array( - 'description' => __( 'Remote GET Response' ), + 'description' => __( 'Remote GET Response', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), @@ -262,22 +262,22 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { 'context' => array( 'view', 'edit' ), 'properties' => array( 'wc_database_version' => array( - 'description' => __( 'WC Database Version' ), + 'description' => __( 'WC Database Version', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'database_prefix' => array( - 'description' => __( 'Database Prefix' ), + 'description' => __( 'Database Prefix', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'maxmind_geoip_database' => array( - 'description' => __( 'MaxMind GeoIP Database' ), + 'description' => __( 'MaxMind GeoIP Database', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'database_tables' => array( - 'description' => __( 'Database Tables' ), + 'description' => __( 'Database Tables', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), ), @@ -294,28 +294,28 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { 'context' => array( 'view', 'edit' ), 'properties' => array( 'name' => array( - 'description' => __( 'Theme Name' ), + 'description' => __( 'Theme Name', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'version' => array( - 'description' => __( 'Theme Version' ), + 'description' => __( 'Theme Version', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'author_url' => array( - 'description' => __( 'Theme Author URL' ), + 'description' => __( 'Theme Author URL', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), ), 'is_child_theme' => array( - 'description' => __( 'Is this theme a child theme?' ), + 'description' => __( 'Is this theme a child theme?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'has_woocommerce_support' => array( - 'description' => __( 'Does the theme declare WooCommerce support?' ), + 'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), @@ -325,17 +325,17 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { 'context' => array( 'view', 'edit' ), ), 'parent_name' => array( - 'description' => __( 'Parent Theme Name' ), + 'description' => __( 'Parent Theme Name', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'parent_version' => array( - 'description' => __( 'Parent Theme Version' ), + 'description' => __( 'Parent Theme Version', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'parent_author_url' => array( - 'description' => __( 'Parent Theme Author URL' ), + 'description' => __( 'Parent Theme Author URL', 'woocommerce' ), 'type' => 'string', 'format' => 'uri', 'context' => array( 'view', 'edit' ), @@ -348,58 +348,58 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { 'context' => array( 'view', 'edit' ), 'properties' => array( 'api_enabled' => array( - 'description' => __( 'REST API Enabled?' ), + 'description' => __( 'REST API Enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'force_ssl' => array( - 'description' => __( 'SSL Forced?' ), + 'description' => __( 'SSL Forced?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'currency' => array( - 'description' => __( 'Currency' ), + 'description' => __( 'Currency', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'currency_symbol' => array( - 'description' => __( 'Currency Symbol' ), + 'description' => __( 'Currency Symbol', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'currency_position' => array( - 'description' => __( 'Currency Position' ), + 'description' => __( 'Currency Position', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'thousand_separator' => array( - 'description' => __( 'Thousand Separator' ), + 'description' => __( 'Thousand Separator', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'decimal_separator' => array( - 'description' => __( 'Decimal Separator' ), + 'description' => __( 'Decimal Separator', 'woocommerce' ), 'type' => 'string', 'context' => array( 'view', 'edit' ), ), 'number_of_decimals' => array( - 'description' => __( 'Number of Decimals' ), + 'description' => __( 'Number of Decimals', 'woocommerce' ), 'type' => 'integer', 'context' => array( 'view', 'edit' ), ), 'geolocation_enabled' => array( - 'description' => __( 'Geolocation Enabled?' ), + 'description' => __( 'Geolocation Enabled?', 'woocommerce' ), 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), 'taxonomies' => array( - 'description' => __( 'Taxonomy Terms for Product/Order Statuses' ), + 'description' => __( 'Taxonomy Terms for Product/Order Statuses', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), ), ) ), - 'wc_pages' => array( + 'pages' => array( 'description' => __( 'WooCommerce Pages', 'woocommerce' ), 'type' => 'array', 'context' => array( 'view', 'edit' ), @@ -411,21 +411,18 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { } /** - * Return an array of sections and the data associated with each + * Return an array of sections and the data associated with each. * * @return array */ public function get_item_mappings() { - global $wpdb; - - // Matches schema return array( 'environment' => $this->get_environment_info(), 'database' => $this->get_database_info(), 'active_plugins' => $this->get_active_plugins(), 'theme' => $this->get_theme_info(), 'settings' => $this->get_settings(), - 'wc_pages' => $this->get_wc_pages(), + 'pages' => $this->get_pages(), ); } @@ -476,7 +473,7 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { return array( 'home_url' => get_option( 'home' ), 'site_url' => get_option( 'siteurl' ), - 'wc_version' => WC()->version, + 'version' => WC()->version, 'log_directory' => WC_LOG_DIR, 'log_directory_writable' => ( @fopen( WC_LOG_DIR . 'test-log.log', 'a' ) ? true : false ), 'wp_version' => get_bloginfo('version'), @@ -591,7 +588,7 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { // Get parent theme info if this theme is a child theme, otherwise // pass empty info in the response. - if( is_child_theme() ) { + if ( is_child_theme() ) { $parent_theme = wp_get_theme( $active_theme->Template ); $parent_theme_info = array( 'parent_name' => $parent_theme->Name, @@ -673,7 +670,7 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { * * @return array */ - public function get_wc_pages() { + public function get_pages() { // WC pages to check against $check_pages = array( _x( 'Shop Base', 'Page setting', 'woocommerce' ) => array( diff --git a/tests/unit-tests/api/system-status.php b/tests/unit-tests/api/system-status.php index 50313c9133b..dd1f6cee195 100644 --- a/tests/unit-tests/api/system-status.php +++ b/tests/unit-tests/api/system-status.php @@ -52,7 +52,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { $this->assertArrayHasKey( 'active_plugins', $data ); $this->assertArrayHasKey( 'theme', $data ); $this->assertArrayHasKey( 'settings', $data ); - $this->assertArrayHasKey( 'wc_pages', $data ); + $this->assertArrayHasKey( 'pages', $data ); } /** @@ -72,7 +72,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { // Test some responses to make sure they match up $this->assertEquals( get_option( 'home' ), $environment['home_url'] ); $this->assertEquals( get_option( 'siteurl' ), $environment['site_url'] ); - $this->assertEquals( WC()->version, $environment['wc_version'] ); + $this->assertEquals( WC()->version, $environment['version'] ); } /** @@ -155,16 +155,16 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { } /** - * Test to make sure wc_pages response is correct. + * Test to make sure pages response is correct. * * @since 2.7.0 */ - public function test_get_system_status_info_wc_pages() { + public function test_get_system_status_info_pages() { wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); $data = $response->get_data(); - $wc_pages = $data['wc_pages']; - $this->assertEquals( 4, count( $wc_pages ) ); + $pages = $data['pages']; + $this->assertEquals( 4, count( $pages ) ); } /** @@ -183,7 +183,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { $this->assertArrayHasKey( 'active_plugins', $properties ); $this->assertArrayHasKey( 'theme', $properties ); $this->assertArrayHasKey( 'settings', $properties ); - $this->assertArrayHasKey( 'wc_pages', $properties ); + $this->assertArrayHasKey( 'pages', $properties ); } } From 5d95b76e1a6da4b86d58ba65d8ed18748922c035 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 27 Jul 2016 14:06:14 -0700 Subject: [PATCH 175/298] Rename the endpoint from system-status to system_status (matches the rest of WC endpoints). --- ...class-wc-rest-system-status-controller.php | 8 ++++---- includes/wc-rest-functions.php | 2 +- tests/unit-tests/api/system-status.php | 20 +++++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/includes/api/class-wc-rest-system-status-controller.php b/includes/api/class-wc-rest-system-status-controller.php index f2961ba6292..a40e7b5dbf4 100644 --- a/includes/api/class-wc-rest-system-status-controller.php +++ b/includes/api/class-wc-rest-system-status-controller.php @@ -2,7 +2,7 @@ /** * REST API WC System Status controller * - * Handles requests to the /system-status endpoint. + * Handles requests to the /system_status endpoint. * * @author WooThemes * @category API @@ -32,7 +32,7 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { * * @var string */ - protected $rest_base = 'system-status'; + protected $rest_base = 'system_status'; /** * Register the routes for coupons. @@ -56,7 +56,7 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { * @return WP_Error|boolean */ public function get_items_permissions_check( $request ) { - if ( ! wc_rest_check_manager_permissions( 'system-status', 'read' ) ) { + if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) { return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; @@ -94,7 +94,7 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { public function get_item_schema() { $schema = array( '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'system-status', + 'title' => 'system_status', 'type' => 'object', 'properties' => array( 'environment' => array( diff --git a/includes/wc-rest-functions.php b/includes/wc-rest-functions.php index a62195fe9ef..083fe11c330 100644 --- a/includes/wc-rest-functions.php +++ b/includes/wc-rest-functions.php @@ -308,7 +308,7 @@ function wc_rest_check_manager_permissions( $object, $context = 'read' ) { $objects = array( 'reports' => 'view_woocommerce_reports', 'settings' => 'manage_woocommerce', - 'system-status' => 'manage_woocommerce', + 'system_status' => 'manage_woocommerce', 'attributes' => 'manage_product_terms', ); diff --git a/tests/unit-tests/api/system-status.php b/tests/unit-tests/api/system-status.php index dd1f6cee195..f35ebf458e0 100644 --- a/tests/unit-tests/api/system-status.php +++ b/tests/unit-tests/api/system-status.php @@ -22,7 +22,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { */ public function test_register_routes() { $routes = $this->server->get_routes(); - $this->assertArrayHasKey( '/wc/v1/system-status', $routes ); + $this->assertArrayHasKey( '/wc/v1/system_status', $routes ); } /** @@ -32,7 +32,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { */ public function test_get_system_status_info_without_permission() { wp_set_current_user( 0 ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) ); $this->assertEquals( 401, $response->get_status() ); } @@ -44,7 +44,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { */ public function test_get_system_status_info_returns_root_properties() { wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) ); $data = $response->get_data(); $this->assertArrayHasKey( 'environment', $data ); @@ -62,7 +62,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { */ public function test_get_system_status_info_environment() { wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) ); $data = $response->get_data(); $environment = $data['environment']; @@ -83,7 +83,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { public function test_get_system_status_info_database() { global $wpdb; wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) ); $data = $response->get_data(); $database = $data['database']; @@ -103,7 +103,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { $actual_plugins = array( 'hello.php' ); update_option( 'active_plugins', $actual_plugins ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) ); update_option( 'active_plugins', array() ); $data = $response->get_data(); @@ -122,7 +122,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { wp_set_current_user( $this->user ); $active_theme = wp_get_theme(); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) ); $data = $response->get_data(); $theme = $data['theme']; @@ -144,7 +144,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { $term_response[ $term->slug ] = strtolower( $term->name ); } - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) ); $data = $response->get_data(); $settings = $data['settings']; @@ -161,7 +161,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { */ public function test_get_system_status_info_pages() { wp_set_current_user( $this->user ); - $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system-status' ) ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) ); $data = $response->get_data(); $pages = $data['pages']; $this->assertEquals( 4, count( $pages ) ); @@ -173,7 +173,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { * @since 2.7.0 */ public function test_system_status_schema() { - $request = new WP_REST_Request( 'OPTIONS', '/wc/v1/system-status' ); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v1/system_status' ); $response = $this->server->dispatch( $request ); $data = $response->get_data(); $properties = $data['schema']['properties']; From 4a23c41ab2e92762984a62b379dc6ecea412c721 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 28 Jul 2016 15:06:51 +0100 Subject: [PATCH 176/298] Hook in woocommerce_widget_shopping_cart_buttons for greater flexibility --- assets/css/woocommerce.css | 2 +- assets/css/woocommerce.scss | 4 ++++ includes/wc-template-functions.php | 24 +++++++++++++++++++++++- includes/wc-template-hooks.php | 5 +++++ templates/cart/mini-cart.php | 7 +++---- 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/assets/css/woocommerce.css b/assets/css/woocommerce.css index 9fbe2a59123..1263c6d5343 100644 --- a/assets/css/woocommerce.css +++ b/assets/css/woocommerce.css @@ -1 +1 @@ -@charset "UTF-8";.clear,.woocommerce .woocommerce-breadcrumb:after{clear:both}@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg)}}@-moz-keyframes spin{100%{-moz-transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}@font-face{font-family:star;src:url(../fonts/star.eot);src:url(../fonts/star.eot?#iefix) format("embedded-opentype"),url(../fonts/star.woff) format("woff"),url(../fonts/star.ttf) format("truetype"),url(../fonts/star.svg#star) format("svg");font-weight:400;font-style:normal}@font-face{font-family:WooCommerce;src:url(../fonts/WooCommerce.eot);src:url(../fonts/WooCommerce.eot?#iefix) format("embedded-opentype"),url(../fonts/WooCommerce.woff) format("woff"),url(../fonts/WooCommerce.ttf) format("truetype"),url(../fonts/WooCommerce.svg#WooCommerce) format("svg");font-weight:400;font-style:normal}p.demo_store{position:fixed;top:0;left:0;right:0;margin:0;width:100%;font-size:1em;padding:1em 0;text-align:center;background-color:#a46497;color:#fff;z-index:99998;box-shadow:0 1px 1em rgba(0,0,0,.2)}p.demo_store a{color:#fff}.admin-bar p.demo_store{top:32px}.woocommerce .blockUI.blockOverlay{position:relative}.woocommerce .blockUI.blockOverlay:before,.woocommerce .loader:before{height:1em;width:1em;position:absolute;top:50%;left:50%;margin-left:-.5em;margin-top:-.5em;display:block;content:"";-webkit-animation:spin 1s ease-in-out infinite;-moz-animation:spin 1s ease-in-out infinite;animation:spin 1s ease-in-out infinite;background:url(../images/icons/loader.svg) center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75)}.woocommerce a.remove{display:block;font-size:1.5em;height:1em;width:1em;text-align:center;line-height:1;border-radius:100%;color:red!important;text-decoration:none;font-weight:700;border:0}.woocommerce a.remove:hover{color:#fff!important;background:red}.woocommerce small.note{display:block;color:#777;font-size:.857em;margin-top:10px}.woocommerce .woocommerce-breadcrumb{margin:0 0 1em;padding:0;font-size:.92em;color:#777}.woocommerce .woocommerce-breadcrumb:after,.woocommerce .woocommerce-breadcrumb:before{content:" ";display:table}.woocommerce .woocommerce-breadcrumb a{color:#777}.woocommerce .quantity .qty{width:3.631em;text-align:center}.woocommerce div.product{margin-bottom:0;position:relative}.woocommerce div.product .product_title{clear:none;margin-top:0;padding:0}.woocommerce #reviews #comments .add_review:after,.woocommerce .products ul:after,.woocommerce div.product form.cart:after,.woocommerce div.product p.cart:after,.woocommerce nav.woocommerce-pagination ul,.woocommerce ul.products:after{clear:both}.woocommerce div.product p.price,.woocommerce div.product span.price{color:#77a464;font-size:1.25em}.woocommerce div.product p.price ins,.woocommerce div.product span.price ins{background:inherit;font-weight:700}.woocommerce div.product p.price del,.woocommerce div.product span.price del{opacity:.5}.woocommerce div.product p.stock{font-size:.92em}.woocommerce div.product .stock{color:#77a464}.woocommerce div.product .out-of-stock{color:red}.woocommerce div.product .woocommerce-product-rating{margin-bottom:1.618em}.woocommerce div.product div.images,.woocommerce div.product div.summary{margin-bottom:2em}.woocommerce div.product div.images img{display:block;width:100%;height:auto;box-shadow:none}.woocommerce div.product div.images div.thumbnails{padding-top:1em}.woocommerce div.product div.social{text-align:right;margin:0 0 1em}.woocommerce div.product div.social span{margin:0 0 0 2px}.woocommerce div.product div.social span span{margin:0}.woocommerce div.product div.social span .stButton .chicklets{padding-left:16px;width:0}.woocommerce div.product div.social iframe{float:left;margin-top:3px}.woocommerce div.product .woocommerce-tabs ul.tabs{list-style:none;padding:0 0 0 1em;margin:0 0 1.618em;overflow:hidden;position:relative}.woocommerce div.product .woocommerce-tabs ul.tabs li{border:1px solid #d3ced2;background-color:#ebe9eb;display:inline-block;position:relative;z-index:0;border-radius:4px 4px 0 0;margin:0 -5px;padding:0 1em}.woocommerce div.product .woocommerce-tabs ul.tabs li a{display:inline-block;padding:.5em 0;font-weight:700;color:#515151;text-decoration:none}.woocommerce div.product form.cart:after,.woocommerce div.product form.cart:before,.woocommerce div.product p.cart:after,.woocommerce div.product p.cart:before{display:table;content:" "}.woocommerce div.product .woocommerce-tabs ul.tabs li a:hover{text-decoration:none;color:#6b6b6b}.woocommerce div.product .woocommerce-tabs ul.tabs li.active{background:#fff;z-index:2;border-bottom-color:#fff}.woocommerce div.product .woocommerce-tabs ul.tabs li.active a{color:inherit;text-shadow:inherit}.woocommerce div.product .woocommerce-tabs ul.tabs li.active:before{box-shadow:2px 2px 0 #fff}.woocommerce div.product .woocommerce-tabs ul.tabs li.active:after{box-shadow:-2px 2px 0 #fff}.woocommerce div.product .woocommerce-tabs ul.tabs li:after,.woocommerce div.product .woocommerce-tabs ul.tabs li:before{border:1px solid #d3ced2;position:absolute;bottom:-1px;width:5px;height:5px;content:" "}.woocommerce div.product .woocommerce-tabs ul.tabs li:before{left:-6px;-webkit-border-bottom-right-radius:4px;-moz-border-bottom-right-radius:4px;border-bottom-right-radius:4px;border-width:0 1px 1px 0;box-shadow:2px 2px 0 #ebe9eb}.woocommerce div.product .woocommerce-tabs ul.tabs li:after{right:-6px;-webkit-border-bottom-left-radius:4px;-moz-border-bottom-left-radius:4px;border-bottom-left-radius:4px;border-width:0 0 1px 1px;box-shadow:-2px 2px 0 #ebe9eb}.woocommerce div.product .woocommerce-tabs ul.tabs:before{position:absolute;content:" ";width:100%;bottom:0;left:0;border-bottom:1px solid #d3ced2;z-index:1}.woocommerce div.product .woocommerce-tabs .panel{margin:0 0 2em;padding:0}.woocommerce div.product form.cart,.woocommerce div.product p.cart{margin-bottom:2em}.woocommerce div.product form.cart div.quantity{float:left;margin:0 4px 0 0}.woocommerce div.product form.cart table{border-width:0 0 1px}.woocommerce div.product form.cart table td{padding-left:0}.woocommerce div.product form.cart table div.quantity{float:none;margin:0}.woocommerce div.product form.cart table small.stock{display:block;float:none}.woocommerce div.product form.cart .variations{margin-bottom:1em;border:0;width:100%}.woocommerce div.product form.cart .variations td,.woocommerce div.product form.cart .variations th{border:0;vertical-align:top;line-height:2em}.woocommerce div.product form.cart .variations label{font-weight:700}.woocommerce div.product form.cart .variations select{max-width:100%;min-width:75%;display:inline-block;margin-right:1em}.woocommerce div.product form.cart .variations td.label{padding-right:1em}.woocommerce div.product form.cart .woocommerce-variation-description p{margin-bottom:1em}.woocommerce div.product form.cart .reset_variations{visibility:hidden;font-size:.83em}.woocommerce div.product form.cart .wc-no-matching-variations{display:none}.woocommerce div.product form.cart .button{vertical-align:middle;float:left}.woocommerce div.product form.cart .group_table td.label{padding-right:1em;padding-left:1em}.woocommerce div.product form.cart .group_table td{vertical-align:top;padding-bottom:.5em;border:0}.woocommerce span.onsale{min-height:3.236em;min-width:3.236em;padding:.202em;font-weight:700;position:absolute;text-align:center;line-height:3.236;top:-.5em;left:-.5em;margin:0;border-radius:100%;background-color:#77a464;color:#fff;font-size:.857em;-webkit-font-smoothing:antialiased}.woocommerce .products ul,.woocommerce ul.products{margin:0 0 1em;padding:0;list-style:none;clear:both}.woocommerce .products ul:after,.woocommerce .products ul:before,.woocommerce ul.products:after,.woocommerce ul.products:before{content:" ";display:table}.woocommerce .products ul li,.woocommerce ul.products li{list-style:none}.woocommerce ul.products li.product .onsale{top:0;right:0;left:auto;margin:-.5em -.5em 0 0}.woocommerce ul.products li.product h3{padding:.5em 0;margin:0;font-size:1em}.woocommerce ul.products li.product a{text-decoration:none}.woocommerce ul.products li.product a img{width:100%;height:auto;display:block;margin:0 0 1em;box-shadow:none}.woocommerce ul.products li.product strong{display:block}.woocommerce ul.products li.product .star-rating{font-size:.857em}.woocommerce ul.products li.product .button{margin-top:1em}.woocommerce ul.products li.product .price{color:#77a464;display:block;font-weight:400;margin-bottom:.5em;font-size:.857em}.woocommerce ul.products li.product .price del{color:inherit;opacity:.5;display:block}.woocommerce ul.products li.product .price ins{background:0 0;font-weight:700}.woocommerce ul.products li.product .price .from{font-size:.67em;margin:-2px 0 0;text-transform:uppercase;color:rgba(132,132,132,.5)}.woocommerce .woocommerce-ordering,.woocommerce .woocommerce-result-count{margin:0 0 1em}.woocommerce .woocommerce-ordering select{vertical-align:top}.woocommerce nav.woocommerce-pagination{text-align:center}.woocommerce nav.woocommerce-pagination ul{display:inline-block;white-space:nowrap;padding:0;border:1px solid #d3ced2;border-right:0;margin:1px}.woocommerce nav.woocommerce-pagination ul li{border-right:1px solid #d3ced2;padding:0;margin:0;float:left;display:inline;overflow:hidden}.woocommerce nav.woocommerce-pagination ul li a,.woocommerce nav.woocommerce-pagination ul li span{margin:0;text-decoration:none;line-height:1;font-size:1em;font-weight:400;padding:.5em;min-width:1em;display:block}.woocommerce nav.woocommerce-pagination ul li a:focus,.woocommerce nav.woocommerce-pagination ul li a:hover,.woocommerce nav.woocommerce-pagination ul li span.current{background:#ebe9eb;color:#8a7e88}.woocommerce #respond input#submit,.woocommerce a.button,.woocommerce button.button,.woocommerce input.button{font-size:100%;margin:0;line-height:1;cursor:pointer;position:relative;text-decoration:none;overflow:visible;padding:.618em 1em;font-weight:700;border-radius:3px;left:auto;color:#515151;background-color:#ebe9eb;border:0;white-space:nowrap;display:inline-block;background-image:none;box-shadow:none;-webkit-box-shadow:none;text-shadow:none}.woocommerce #respond input#submit.loading,.woocommerce a.button.loading,.woocommerce button.button.loading,.woocommerce input.button.loading{opacity:.25;padding-right:2.618em}.woocommerce #respond input#submit.loading:after,.woocommerce a.button.loading:after,.woocommerce button.button.loading:after,.woocommerce input.button.loading:after{font-family:WooCommerce;content:"\e01c";vertical-align:top;-webkit-font-smoothing:antialiased;font-weight:400;position:absolute;top:.618em;right:1em;-webkit-animation:spin 2s linear infinite;-moz-animation:spin 2s linear infinite;animation:spin 2s linear infinite}.woocommerce #respond input#submit.added:after,.woocommerce a.button.added:after,.woocommerce button.button.added:after,.woocommerce input.button.added:after{font-family:WooCommerce;content:"\e017";margin-left:.53em;vertical-align:bottom}.woocommerce #respond input#submit:hover,.woocommerce a.button:hover,.woocommerce button.button:hover,.woocommerce input.button:hover{background-color:#dad8da;text-decoration:none;background-image:none;color:#515151}.woocommerce #respond input#submit.alt,.woocommerce a.button.alt,.woocommerce button.button.alt,.woocommerce input.button.alt{background-color:#a46497;color:#fff;-webkit-font-smoothing:antialiased}.woocommerce #respond input#submit.alt:hover,.woocommerce a.button.alt:hover,.woocommerce button.button.alt:hover,.woocommerce input.button.alt:hover{background-color:#935386;color:#fff}.woocommerce #respond input#submit.alt.disabled,.woocommerce #respond input#submit.alt.disabled:hover,.woocommerce #respond input#submit.alt:disabled,.woocommerce #respond input#submit.alt:disabled:hover,.woocommerce #respond input#submit.alt:disabled[disabled],.woocommerce #respond input#submit.alt:disabled[disabled]:hover,.woocommerce a.button.alt.disabled,.woocommerce a.button.alt.disabled:hover,.woocommerce a.button.alt:disabled,.woocommerce a.button.alt:disabled:hover,.woocommerce a.button.alt:disabled[disabled],.woocommerce a.button.alt:disabled[disabled]:hover,.woocommerce button.button.alt.disabled,.woocommerce button.button.alt.disabled:hover,.woocommerce button.button.alt:disabled,.woocommerce button.button.alt:disabled:hover,.woocommerce button.button.alt:disabled[disabled],.woocommerce button.button.alt:disabled[disabled]:hover,.woocommerce input.button.alt.disabled,.woocommerce input.button.alt.disabled:hover,.woocommerce input.button.alt:disabled,.woocommerce input.button.alt:disabled:hover,.woocommerce input.button.alt:disabled[disabled],.woocommerce input.button.alt:disabled[disabled]:hover{background-color:#a46497;color:#fff}.woocommerce #respond input#submit.disabled,.woocommerce #respond input#submit:disabled,.woocommerce #respond input#submit:disabled[disabled],.woocommerce a.button.disabled,.woocommerce a.button:disabled,.woocommerce a.button:disabled[disabled],.woocommerce button.button.disabled,.woocommerce button.button:disabled,.woocommerce button.button:disabled[disabled],.woocommerce input.button.disabled,.woocommerce input.button:disabled,.woocommerce input.button:disabled[disabled]{color:inherit;cursor:not-allowed;opacity:.5;padding:.618em 1em}.woocommerce #respond input#submit.disabled:hover,.woocommerce #respond input#submit:disabled:hover,.woocommerce #respond input#submit:disabled[disabled]:hover,.woocommerce a.button.disabled:hover,.woocommerce a.button:disabled:hover,.woocommerce a.button:disabled[disabled]:hover,.woocommerce button.button.disabled:hover,.woocommerce button.button:disabled:hover,.woocommerce button.button:disabled[disabled]:hover,.woocommerce input.button.disabled:hover,.woocommerce input.button:disabled:hover,.woocommerce input.button:disabled[disabled]:hover{color:inherit;background-color:#ebe9eb}.woocommerce .cart .button,.woocommerce .cart input.button{float:none}.woocommerce a.added_to_cart{padding-top:.5em;white-space:nowrap;display:inline-block}.woocommerce #reviews #comments .add_review:after,.woocommerce #reviews #comments .add_review:before,.woocommerce #reviews #comments ol.commentlist li .comment-text:after,.woocommerce #reviews #comments ol.commentlist li .comment-text:before,.woocommerce #reviews #comments ol.commentlist:after,.woocommerce #reviews #comments ol.commentlist:before{content:" ";display:table}.woocommerce #reviews h2 small{float:right;color:#777;font-size:15px;margin:10px 0 0}.woocommerce #reviews h2 small a{text-decoration:none;color:#777}.woocommerce #reviews h3{margin:0}.woocommerce #reviews #respond{margin:0;border:0;padding:0}.woocommerce #reviews #comment{height:75px}.woocommerce #reviews #comments h2{clear:none}.woocommerce #review_form #respond:after,.woocommerce #reviews #comments ol.commentlist li .comment-text:after,.woocommerce #reviews #comments ol.commentlist:after,.woocommerce .woocommerce-product-rating:after,.woocommerce td.product-name dl.variation:after{clear:both}.woocommerce #reviews #comments ol.commentlist{margin:0;width:100%;background:0 0;list-style:none}.woocommerce #reviews #comments ol.commentlist li{padding:0;margin:0 0 20px;position:relative;background:0;border:0}.woocommerce #reviews #comments ol.commentlist li .meta{color:#777;font-size:.75em}.woocommerce #reviews #comments ol.commentlist li img.avatar{float:left;position:absolute;top:0;left:0;padding:3px;width:32px;height:auto;background:#ebe9eb;border:1px solid #e4e1e3;margin:0;box-shadow:none}.woocommerce #reviews #comments ol.commentlist li .comment-text{margin:0 0 0 50px;border:1px solid #e4e1e3;border-radius:4px;padding:1em 1em 0}.woocommerce #reviews #comments ol.commentlist li .comment-text p{margin:0 0 1em}.woocommerce #reviews #comments ol.commentlist li .comment-text p.meta{font-size:.83em}.woocommerce #reviews #comments ol.commentlist ul.children{list-style:none;margin:20px 0 0 50px}.woocommerce #reviews #comments ol.commentlist ul.children .star-rating{display:none}.woocommerce #reviews #comments ol.commentlist #respond{border:1px solid #e4e1e3;border-radius:4px;padding:1em 1em 0;margin:20px 0 0 50px}.woocommerce #reviews #comments .commentlist>li:before{content:""}.woocommerce .star-rating{float:right;overflow:hidden;position:relative;height:1em;line-height:1;font-size:1em;width:5.4em;font-family:star}.woocommerce .star-rating:before{content:"\73\73\73\73\73";color:#d3ced2;float:left;top:0;left:0;position:absolute}.woocommerce .star-rating span{overflow:hidden;float:left;top:0;left:0;position:absolute;padding-top:1.5em}.woocommerce .star-rating span:before{content:"\53\53\53\53\53";top:0;position:absolute;left:0}.woocommerce .woocommerce-product-rating{line-height:2;display:block}.woocommerce .woocommerce-product-rating:after,.woocommerce .woocommerce-product-rating:before{content:" ";display:table}.woocommerce .woocommerce-product-rating .star-rating{margin:.5em 4px 0 0;float:left}.woocommerce .products .star-rating{display:block;margin:0 0 .5em;float:none}.woocommerce .hreview-aggregate .star-rating{margin:10px 0 0}.woocommerce #review_form #respond{position:static;margin:0;width:auto;padding:0;background:0 0;border:0}.woocommerce #review_form #respond:after,.woocommerce #review_form #respond:before{content:" ";display:table}.woocommerce p.stars a:before,.woocommerce p.stars a:hover~a:before{content:"\e021"}.woocommerce #review_form #respond p{margin:0 0 10px}.woocommerce #review_form #respond .form-submit input{left:auto}.woocommerce #review_form #respond textarea{box-sizing:border-box;width:100%}.woocommerce p.stars a{position:relative;height:1em;width:1em;text-indent:-999em;display:inline-block;text-decoration:none}.woocommerce p.stars a:before{display:block;position:absolute;top:0;left:0;width:1em;height:1em;line-height:1;font-family:WooCommerce;text-indent:0}.woocommerce table.shop_attributes td,.woocommerce table.shop_attributes th{line-height:1.5;border-bottom:1px dotted rgba(0,0,0,.1);border-top:0;margin:0}.woocommerce p.stars.selected a.active:before,.woocommerce p.stars:hover a:before{content:"\e020"}.woocommerce p.stars.selected a.active~a:before{content:"\e021"}.woocommerce p.stars.selected a:not(.active):before{content:"\e020"}.woocommerce table.shop_attributes{border:0;border-top:1px dotted rgba(0,0,0,.1);margin-bottom:1.618em;width:100%}.woocommerce table.shop_attributes th{width:150px;font-weight:700;padding:8px}.woocommerce table.shop_attributes td{font-style:italic;padding:0}.woocommerce table.shop_attributes td p{margin:0;padding:8px 0}.woocommerce table.shop_attributes .alt td,.woocommerce table.shop_attributes .alt th{background:rgba(0,0,0,.025)}.woocommerce table.shop_table{border:1px solid rgba(0,0,0,.1);margin:0 -1px 24px 0;text-align:left;width:100%;border-collapse:separate;border-radius:5px}.woocommerce table.shop_table th{font-weight:700;padding:9px 12px}.woocommerce table.shop_table td{border-top:1px solid rgba(0,0,0,.1);padding:6px 12px;vertical-align:middle}.woocommerce table.shop_table td small{font-weight:400}.woocommerce table.shop_table tbody:first-child tr:first-child td,.woocommerce table.shop_table tbody:first-child tr:first-child th{border-top:0}.woocommerce table.shop_table tbody th,.woocommerce table.shop_table tfoot td,.woocommerce table.shop_table tfoot th{font-weight:700;border-top:1px solid rgba(0,0,0,.1)}.woocommerce table.my_account_orders{font-size:.85em}.woocommerce table.my_account_orders td,.woocommerce table.my_account_orders th{padding:4px 8px;vertical-align:middle}.woocommerce table.my_account_orders .button{white-space:nowrap}.woocommerce table.my_account_orders .order-actions{text-align:right}.woocommerce table.my_account_orders .order-actions .button{margin:.125em 0 .125em .25em}.woocommerce td.product-name dl.variation{margin:.25em 0}.woocommerce td.product-name dl.variation:after,.woocommerce td.product-name dl.variation:before{content:" ";display:table}.woocommerce td.product-name dl.variation dd,.woocommerce td.product-name dl.variation dt{display:inline-block;float:left;margin-bottom:1em}.woocommerce td.product-name dl.variation dt{font-weight:700;padding:0 0 .25em;margin:0 4px 0 0;clear:left}.woocommerce ul.cart_list li dl:after,.woocommerce ul.cart_list li:after,.woocommerce ul.product_list_widget li dl:after,.woocommerce ul.product_list_widget li:after{clear:both}.woocommerce td.product-name dl.variation dd{padding:0 0 .25em}.woocommerce td.product-name dl.variation dd p:last-child{margin-bottom:0}.woocommerce td.product-name p.backorder_notification{font-size:.83em}.woocommerce td.product-quantity{min-width:80px}.woocommerce ul.cart_list,.woocommerce ul.product_list_widget{list-style:none;padding:0;margin:0}.woocommerce ul.cart_list li,.woocommerce ul.product_list_widget li{padding:4px 0;margin:0;list-style:none}.woocommerce ul.cart_list li:after,.woocommerce ul.cart_list li:before,.woocommerce ul.product_list_widget li:after,.woocommerce ul.product_list_widget li:before{content:" ";display:table}.woocommerce ul.cart_list li a,.woocommerce ul.product_list_widget li a{display:block;font-weight:700}.woocommerce ul.cart_list li img,.woocommerce ul.product_list_widget li img{float:right;margin-left:4px;width:32px;height:auto;box-shadow:none}.woocommerce ul.cart_list li dl,.woocommerce ul.product_list_widget li dl{margin:0;padding-left:1em;border-left:2px solid rgba(0,0,0,.1)}.woocommerce ul.cart_list li dl:after,.woocommerce ul.cart_list li dl:before,.woocommerce ul.product_list_widget li dl:after,.woocommerce ul.product_list_widget li dl:before{content:" ";display:table}.woocommerce ul.cart_list li dl dd,.woocommerce ul.cart_list li dl dt,.woocommerce ul.product_list_widget li dl dd,.woocommerce ul.product_list_widget li dl dt{display:inline-block;float:left;margin-bottom:1em}.woocommerce ul.cart_list li dl dt,.woocommerce ul.product_list_widget li dl dt{font-weight:700;padding:0 0 .25em;margin:0 4px 0 0;clear:left}#add_payment_method .wc-proceed-to-checkout:after,.woocommerce .order_details:after,.woocommerce .widget_layered_nav ul li:after,.woocommerce .widget_rating_filter ul li:after,.woocommerce .widget_shopping_cart .buttons:after,.woocommerce-account .addresses .title:after,.woocommerce-account .woocommerce:after,.woocommerce-cart .wc-proceed-to-checkout:after,.woocommerce-checkout .wc-proceed-to-checkout:after,.woocommerce-error:after,.woocommerce-info:after,.woocommerce-message:after,.woocommerce.widget_shopping_cart .buttons:after{clear:both}.woocommerce ul.cart_list li dl dd,.woocommerce ul.product_list_widget li dl dd{padding:0 0 .25em}.woocommerce ul.cart_list li dl dd p:last-child,.woocommerce ul.product_list_widget li dl dd p:last-child{margin-bottom:0}.woocommerce ul.cart_list li .star-rating,.woocommerce ul.product_list_widget li .star-rating{float:none}.woocommerce .widget_shopping_cart .total,.woocommerce.widget_shopping_cart .total{border-top:3px double #ebe9eb;padding:4px 0 0}.woocommerce .widget_shopping_cart .total strong,.woocommerce.widget_shopping_cart .total strong{min-width:40px;display:inline-block}.woocommerce .widget_shopping_cart .cart_list li,.woocommerce.widget_shopping_cart .cart_list li{padding-left:2em;position:relative;padding-top:0}.woocommerce .widget_shopping_cart .cart_list li a.remove,.woocommerce.widget_shopping_cart .cart_list li a.remove{position:absolute;top:0;left:0}.woocommerce .widget_shopping_cart .buttons:after,.woocommerce .widget_shopping_cart .buttons:before,.woocommerce.widget_shopping_cart .buttons:after,.woocommerce.widget_shopping_cart .buttons:before{content:" ";display:table}.woocommerce form .form-row{padding:3px;margin:0 0 6px}.woocommerce form .form-row [placeholder]:focus::-webkit-input-placeholder{-webkit-transition:opacity .5s .5s ease;-moz-transition:opacity .5s .5s ease;transition:opacity .5s .5s ease;opacity:0}.woocommerce form .form-row label{line-height:2}.woocommerce form .form-row label.hidden{visibility:hidden}.woocommerce form .form-row label.inline{display:inline}.woocommerce form .form-row select{cursor:pointer;margin:0}.woocommerce form .form-row .required{color:red;font-weight:700;border:0}.woocommerce form .form-row .input-checkbox{display:inline;margin:-2px 8px 0 0;text-align:center;vertical-align:middle}.woocommerce form .form-row input.input-text,.woocommerce form .form-row textarea{box-sizing:border-box;width:100%;margin:0;outline:0;line-height:1}.woocommerce form .form-row textarea{height:4em;line-height:1.5;display:block;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.woocommerce form .form-row .select2-container{width:100%;line-height:2em}.woocommerce form .form-row.woocommerce-invalid label{color:#a00}.woocommerce form .form-row.woocommerce-invalid .select2-container,.woocommerce form .form-row.woocommerce-invalid input.input-text,.woocommerce form .form-row.woocommerce-invalid select{border-color:#a00}.woocommerce form .form-row.woocommerce-validated .select2-container,.woocommerce form .form-row.woocommerce-validated input.input-text,.woocommerce form .form-row.woocommerce-validated select{border-color:#69bf29}.woocommerce form .form-row ::-webkit-input-placeholder{line-height:normal}.woocommerce form .form-row :-moz-placeholder{line-height:normal}.woocommerce form .form-row :-ms-input-placeholder{line-height:normal}.woocommerce form.checkout_coupon,.woocommerce form.login,.woocommerce form.register{border:1px solid #d3ced2;padding:20px;margin:2em 0;text-align:left;border-radius:5px}.woocommerce ul#shipping_method{list-style:none;margin:0;padding:0}.woocommerce ul#shipping_method li{margin:0;padding:.25em 0 .25em 22px;text-indent:-22px;list-style:none}.woocommerce ul#shipping_method li input{margin:3px .5ex}.woocommerce ul#shipping_method li label{display:inline}.woocommerce ul#shipping_method .amount{font-weight:700}.woocommerce p.woocommerce-shipping-contents{margin:0}.woocommerce .order_details{margin:0 0 1.5em;list-style:none}.woocommerce .order_details:after,.woocommerce .order_details:before{content:" ";display:table}.woocommerce .order_details li{float:left;margin-right:2em;text-transform:uppercase;font-size:.715em;line-height:1;border-right:1px dashed #d3ced2;padding-right:2em;margin-left:0;padding-left:0;list-style-type:none}.woocommerce .order_details li strong{display:block;font-size:1.4em;text-transform:none;line-height:1.5}.woocommerce .order_details li:last-of-type{border:none}.woocommerce .widget_layered_nav ul{margin:0;padding:0;border:0;list-style:none}.woocommerce .widget_layered_nav ul li{padding:0 0 1px;list-style:none}.woocommerce .widget_layered_nav ul li:after,.woocommerce .widget_layered_nav ul li:before{content:" ";display:table}.woocommerce .widget_layered_nav ul li.chosen a:before,.woocommerce .widget_layered_nav_filters ul li a:before{line-height:1;content:"";font-family:WooCommerce;font-weight:400;color:#a00;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-decoration:none}.woocommerce .widget_layered_nav ul li a,.woocommerce .widget_layered_nav ul li span{padding:1px 0}.woocommerce .widget_layered_nav ul li.chosen a:before{margin-right:.618em}.woocommerce .widget_layered_nav_filters ul{margin:0;padding:0;border:0;list-style:none;overflow:hidden;zoom:1}.woocommerce .widget_layered_nav_filters ul li{float:left;padding:0 1px 1px 0;list-style:none}.woocommerce .widget_layered_nav_filters ul li a{text-decoration:none}.woocommerce .widget_layered_nav_filters ul li a:before{margin-right:.618em}.woocommerce .widget_price_filter .price_slider{margin-bottom:1em}.woocommerce .widget_price_filter .price_slider_amount{text-align:right;line-height:2.4;font-size:.8751em}.woocommerce .widget_price_filter .price_slider_amount .button{font-size:1.15em;float:left}.woocommerce .widget_price_filter .ui-slider{position:relative;text-align:left;margin-left:.5em;margin-right:.5em}.woocommerce .widget_price_filter .ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1em;height:1em;background-color:#a46497;border-radius:1em;cursor:ew-resize;outline:0;top:-.3em;margin-left:-.5em}.woocommerce .widget_price_filter .ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;border-radius:1em;background-color:#a46497}.woocommerce .widget_price_filter .price_slider_wrapper .ui-widget-content{border-radius:1em;background-color:#602053;border:0}.woocommerce .widget_price_filter .ui-slider-horizontal{height:.5em}.woocommerce .widget_price_filter .ui-slider-horizontal .ui-slider-range{top:0;height:100%}.woocommerce .widget_price_filter .ui-slider-horizontal .ui-slider-range-min{left:-1px}.woocommerce .widget_price_filter .ui-slider-horizontal .ui-slider-range-max{right:-1px}.woocommerce .widget_rating_filter ul{margin:0;padding:0;border:0;list-style:none}.woocommerce .widget_rating_filter ul li{padding:0 0 1px;list-style:none}.woocommerce .widget_rating_filter ul li:after,.woocommerce .widget_rating_filter ul li:before{content:" ";display:table}.woocommerce .widget_rating_filter ul li a{padding:1px 0;text-decoration:none}.woocommerce .widget_rating_filter ul li .star-rating{float:none;display:inline-block}.woocommerce .widget_rating_filter ul li.chosen a:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none;color:#a00}.woocommerce-error,.woocommerce-info,.woocommerce-message{padding:1em 2em 1em 3.5em!important;margin:0 0 2em!important;position:relative;background-color:#f7f6f7;color:#515151;border-top:3px solid #a46497;list-style:none!important;width:auto;word-wrap:break-word}.woocommerce-error:after,.woocommerce-error:before,.woocommerce-info:after,.woocommerce-info:before,.woocommerce-message:after,.woocommerce-message:before{content:" ";display:table}.woocommerce-error:before,.woocommerce-info:before,.woocommerce-message:before{font-family:WooCommerce;content:"\e028";display:inline-block;position:absolute;top:1em;left:1.5em}.woocommerce-error .button,.woocommerce-info .button,.woocommerce-message .button{float:right}.woocommerce-error li,.woocommerce-info li,.woocommerce-message li{list-style:none!important;padding-left:0!important;margin-left:0!important}.woocommerce-message{border-top-color:#8fae1b}.woocommerce-message:before{content:"\e015";color:#8fae1b}.woocommerce-info{border-top-color:#1e85be}.woocommerce-info:before{color:#1e85be}.woocommerce-error{border-top-color:#b81c23}.woocommerce-error:before{content:"\e016";color:#b81c23}.woocommerce-account .addresses .title:after,.woocommerce-account .addresses .title:before,.woocommerce-account .woocommerce:after,.woocommerce-account .woocommerce:before{content:" ";display:table}.woocommerce-account .addresses .title h3{float:left}.woocommerce-account .addresses .title .edit,.woocommerce-account ul.digital-downloads li .count{float:right}.woocommerce-account ol.commentlist.notes li.note p.meta{font-weight:700;margin-bottom:0}.woocommerce-account ol.commentlist.notes li.note .description p:last-child{margin-bottom:0}.woocommerce-account ul.digital-downloads{margin-left:0;padding-left:0}.woocommerce-account ul.digital-downloads li{list-style:none;margin-left:0;padding-left:0}.woocommerce-account ul.digital-downloads li:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}#add_payment_method table.cart .product-thumbnail,.woocommerce-cart table.cart .product-thumbnail,.woocommerce-checkout table.cart .product-thumbnail{min-width:32px}#add_payment_method table.cart img,.woocommerce-cart table.cart img,.woocommerce-checkout table.cart img{width:32px;box-shadow:none}#add_payment_method table.cart td,#add_payment_method table.cart th,.woocommerce-cart table.cart td,.woocommerce-cart table.cart th,.woocommerce-checkout table.cart td,.woocommerce-checkout table.cart th{vertical-align:middle}#add_payment_method table.cart td.actions .coupon .input-text,.woocommerce-cart table.cart td.actions .coupon .input-text,.woocommerce-checkout table.cart td.actions .coupon .input-text{float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;border:1px solid #d3ced2;padding:6px 6px 5px;margin:0 4px 0 0;outline:0;line-height:1}#add_payment_method table.cart input,.woocommerce-cart table.cart input,.woocommerce-checkout table.cart input{margin:0;vertical-align:middle;line-height:1}#add_payment_method .wc-proceed-to-checkout,.woocommerce-cart .wc-proceed-to-checkout,.woocommerce-checkout .wc-proceed-to-checkout{padding:1em 0}#add_payment_method .wc-proceed-to-checkout:after,#add_payment_method .wc-proceed-to-checkout:before,.woocommerce-cart .wc-proceed-to-checkout:after,.woocommerce-cart .wc-proceed-to-checkout:before,.woocommerce-checkout .wc-proceed-to-checkout:after,.woocommerce-checkout .wc-proceed-to-checkout:before{content:" ";display:table}#add_payment_method .wc-proceed-to-checkout a.checkout-button,.woocommerce-cart .wc-proceed-to-checkout a.checkout-button,.woocommerce-checkout .wc-proceed-to-checkout a.checkout-button{display:block;text-align:center;margin-bottom:1em;font-size:1.25em;padding:1em}#add_payment_method .cart-collaterals .shipping_calculator .button,.woocommerce-cart .cart-collaterals .shipping_calculator .button,.woocommerce-checkout .cart-collaterals .shipping_calculator .button{width:100%;float:none;display:block}#add_payment_method .cart-collaterals .shipping_calculator .shipping-calculator-button:after,.woocommerce-cart .cart-collaterals .shipping_calculator .shipping-calculator-button:after,.woocommerce-checkout .cart-collaterals .shipping_calculator .shipping-calculator-button:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-left:.618em;content:"";text-decoration:none}#add_payment_method #payment ul.payment_methods li:after,#add_payment_method #payment ul.payment_methods li:before,#add_payment_method #payment ul.payment_methods:after,#add_payment_method #payment ul.payment_methods:before,.woocommerce-cart #payment ul.payment_methods li:after,.woocommerce-cart #payment ul.payment_methods li:before,.woocommerce-cart #payment ul.payment_methods:after,.woocommerce-cart #payment ul.payment_methods:before,.woocommerce-checkout #payment ul.payment_methods li:after,.woocommerce-checkout #payment ul.payment_methods li:before,.woocommerce-checkout #payment ul.payment_methods:after,.woocommerce-checkout #payment ul.payment_methods:before{content:" ";display:table}#add_payment_method .cart-collaterals .cart_totals p small,.woocommerce-cart .cart-collaterals .cart_totals p small,.woocommerce-checkout .cart-collaterals .cart_totals p small{color:#777;font-size:.83em}#add_payment_method .cart-collaterals .cart_totals table,.woocommerce-cart .cart-collaterals .cart_totals table,.woocommerce-checkout .cart-collaterals .cart_totals table{border-collapse:separate;margin:0 0 6px;padding:0}#add_payment_method .cart-collaterals .cart_totals table tr:first-child td,#add_payment_method .cart-collaterals .cart_totals table tr:first-child th,.woocommerce-cart .cart-collaterals .cart_totals table tr:first-child td,.woocommerce-cart .cart-collaterals .cart_totals table tr:first-child th,.woocommerce-checkout .cart-collaterals .cart_totals table tr:first-child td,.woocommerce-checkout .cart-collaterals .cart_totals table tr:first-child th{border-top:0}#add_payment_method .cart-collaterals .cart_totals table th,.woocommerce-cart .cart-collaterals .cart_totals table th,.woocommerce-checkout .cart-collaterals .cart_totals table th{width:40%}#add_payment_method .cart-collaterals .cart_totals table td,#add_payment_method .cart-collaterals .cart_totals table th,.woocommerce-cart .cart-collaterals .cart_totals table td,.woocommerce-cart .cart-collaterals .cart_totals table th,.woocommerce-checkout .cart-collaterals .cart_totals table td,.woocommerce-checkout .cart-collaterals .cart_totals table th{vertical-align:top;border-left:0;border-right:0;line-height:1.5em}#add_payment_method .cart-collaterals .cart_totals table small,.woocommerce-cart .cart-collaterals .cart_totals table small,.woocommerce-checkout .cart-collaterals .cart_totals table small{color:#777}#add_payment_method .cart-collaterals .cart_totals table select,.woocommerce-cart .cart-collaterals .cart_totals table select,.woocommerce-checkout .cart-collaterals .cart_totals table select{width:100%}#add_payment_method .cart-collaterals .cart_totals .discount td,.woocommerce-cart .cart-collaterals .cart_totals .discount td,.woocommerce-checkout .cart-collaterals .cart_totals .discount td{color:#77a464}#add_payment_method .cart-collaterals .cart_totals tr td,#add_payment_method .cart-collaterals .cart_totals tr th,.woocommerce-cart .cart-collaterals .cart_totals tr td,.woocommerce-cart .cart-collaterals .cart_totals tr th,.woocommerce-checkout .cart-collaterals .cart_totals tr td,.woocommerce-checkout .cart-collaterals .cart_totals tr th{border-top:1px solid #ebe9eb}#add_payment_method .cart-collaterals .cross-sells ul.products li.product,.woocommerce-cart .cart-collaterals .cross-sells ul.products li.product,.woocommerce-checkout .cart-collaterals .cross-sells ul.products li.product{margin-top:0}#add_payment_method .checkout .col-2 h3#ship-to-different-address,.woocommerce-cart .checkout .col-2 h3#ship-to-different-address,.woocommerce-checkout .checkout .col-2 h3#ship-to-different-address{float:left;clear:none}#add_payment_method .checkout .col-2 .form-row-first,#add_payment_method .checkout .col-2 .notes,.woocommerce-cart .checkout .col-2 .form-row-first,.woocommerce-cart .checkout .col-2 .notes,.woocommerce-checkout .checkout .col-2 .form-row-first,.woocommerce-checkout .checkout .col-2 .notes{clear:left}#add_payment_method .checkout .create-account small,.woocommerce-cart .checkout .create-account small,.woocommerce-checkout .checkout .create-account small{font-size:11px;color:#777;font-weight:400}#add_payment_method .checkout div.shipping-address,.woocommerce-cart .checkout div.shipping-address,.woocommerce-checkout .checkout div.shipping-address{padding:0;clear:left;width:100%}#add_payment_method #payment ul.payment_methods li:after,#add_payment_method #payment ul.payment_methods:after,#add_payment_method .checkout .shipping_address,.single-product .twentythirteen p.stars,.woocommerce-cart #payment ul.payment_methods li:after,.woocommerce-cart #payment ul.payment_methods:after,.woocommerce-cart .checkout .shipping_address,.woocommerce-checkout #payment ul.payment_methods li:after,.woocommerce-checkout #payment ul.payment_methods:after,.woocommerce-checkout .checkout .shipping_address{clear:both}#add_payment_method #payment,.woocommerce-cart #payment,.woocommerce-checkout #payment{background:#ebe9eb;border-radius:5px}#add_payment_method #payment ul.payment_methods,.woocommerce-cart #payment ul.payment_methods,.woocommerce-checkout #payment ul.payment_methods{text-align:left;padding:1em;border-bottom:1px solid #d3ced2;margin:0;list-style:none}#add_payment_method #payment ul.payment_methods li,.woocommerce-cart #payment ul.payment_methods li,.woocommerce-checkout #payment ul.payment_methods li{line-height:2;text-align:left;margin:0;font-weight:400}#add_payment_method #payment ul.payment_methods li input,.woocommerce-cart #payment ul.payment_methods li input,.woocommerce-checkout #payment ul.payment_methods li input{margin:0 1em 0 0}#add_payment_method #payment ul.payment_methods li img,.woocommerce-cart #payment ul.payment_methods li img,.woocommerce-checkout #payment ul.payment_methods li img{vertical-align:middle;margin:-2px 0 0 .5em;padding:0;position:relative;box-shadow:none}#add_payment_method #payment ul.payment_methods li img+img,.woocommerce-cart #payment ul.payment_methods li img+img,.woocommerce-checkout #payment ul.payment_methods li img+img{margin-left:2px}#add_payment_method #payment div.form-row,.woocommerce-cart #payment div.form-row,.woocommerce-checkout #payment div.form-row{padding:1em}#add_payment_method #payment div.payment_box,.woocommerce-cart #payment div.payment_box,.woocommerce-checkout #payment div.payment_box{position:relative;box-sizing:border-box;width:100%;padding:1em;margin:1em 0;font-size:.92em;border-radius:2px;line-height:1.5;background-color:#dfdcde;color:#515151}#add_payment_method #payment div.payment_box input.input-text,#add_payment_method #payment div.payment_box textarea,.woocommerce-cart #payment div.payment_box input.input-text,.woocommerce-cart #payment div.payment_box textarea,.woocommerce-checkout #payment div.payment_box input.input-text,.woocommerce-checkout #payment div.payment_box textarea{border-color:#bbb3b9 #c7c1c6 #c7c1c6}#add_payment_method #payment div.payment_box ::-webkit-input-placeholder,.woocommerce-cart #payment div.payment_box ::-webkit-input-placeholder,.woocommerce-checkout #payment div.payment_box ::-webkit-input-placeholder{color:#bbb3b9}#add_payment_method #payment div.payment_box :-moz-placeholder,.woocommerce-cart #payment div.payment_box :-moz-placeholder,.woocommerce-checkout #payment div.payment_box :-moz-placeholder{color:#bbb3b9}#add_payment_method #payment div.payment_box :-ms-input-placeholder,.woocommerce-cart #payment div.payment_box :-ms-input-placeholder,.woocommerce-checkout #payment div.payment_box :-ms-input-placeholder{color:#bbb3b9}#add_payment_method #payment div.payment_box .woocommerce-SavedPaymentMethods,.woocommerce-cart #payment div.payment_box .woocommerce-SavedPaymentMethods,.woocommerce-checkout #payment div.payment_box .woocommerce-SavedPaymentMethods{list-style:none;margin:0}#add_payment_method #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-new,#add_payment_method #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-token,.woocommerce-cart #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-new,.woocommerce-cart #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-token,.woocommerce-checkout #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-new,.woocommerce-checkout #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-token{margin:0 0 .5em}#add_payment_method #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-new label,#add_payment_method #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-token label,.woocommerce-cart #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-new label,.woocommerce-cart #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-token label,.woocommerce-checkout #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-new label,.woocommerce-checkout #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-token label{cursor:pointer}#add_payment_method #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-tokenInput,.woocommerce-cart #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-tokenInput,.woocommerce-checkout #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-tokenInput{vertical-align:middle;margin:-3px 1em 0 0;position:relative}#add_payment_method #payment div.payment_box .wc-credit-card-form,.woocommerce-cart #payment div.payment_box .wc-credit-card-form,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form{border:0;padding:0;margin:1em 0 0}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number{font-size:1.5em;padding:8px;background-repeat:no-repeat;background-position:right .618em center;background-size:32px 20px}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.visa,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.visa,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.visa,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.visa,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.visa,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.visa,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.visa,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.visa,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.visa{background-image:url(../images/icons/credit-cards/visa.svg)}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.mastercard,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.mastercard,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.mastercard,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.mastercard,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.mastercard,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.mastercard,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.mastercard,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.mastercard,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.mastercard{background-image:url(../images/icons/credit-cards/mastercard.svg)}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.laser,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.laser,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.laser,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.laser,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.laser,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.laser,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.laser,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.laser,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.laser{background-image:url(../images/icons/credit-cards/laser.svg)}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.dinersclub,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.dinersclub,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.dinersclub,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.dinersclub,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.dinersclub,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.dinersclub,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.dinersclub,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.dinersclub,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.dinersclub{background-image:url(../images/icons/credit-cards/diners.svg)}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.maestro,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.maestro,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.maestro,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.maestro,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.maestro,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.maestro,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.maestro,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.maestro,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.maestro{background-image:url(../images/icons/credit-cards/maestro.svg)}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.jcb,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.jcb,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.jcb,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.jcb,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.jcb,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.jcb,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.jcb,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.jcb,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.jcb{background-image:url(../images/icons/credit-cards/jcb.svg)}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.amex,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.amex,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.amex,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.amex,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.amex,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.amex,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.amex,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.amex,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.amex{background-image:url(../images/icons/credit-cards/amex.svg)}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.discover,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.discover,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.discover,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.discover,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.discover,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.discover,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.discover,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.discover,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.discover{background-image:url(../images/icons/credit-cards/discover.svg)}#add_payment_method #payment div.payment_box span.help,.woocommerce-cart #payment div.payment_box span.help,.woocommerce-checkout #payment div.payment_box span.help{font-size:.857em;color:#777;font-weight:400}#add_payment_method #payment div.payment_box .form-row,.woocommerce-cart #payment div.payment_box .form-row,.woocommerce-checkout #payment div.payment_box .form-row{margin:0 0 1em}#add_payment_method #payment div.payment_box p:last-child,.woocommerce-cart #payment div.payment_box p:last-child,.woocommerce-checkout #payment div.payment_box p:last-child{margin-bottom:0}#add_payment_method #payment div.payment_box:before,.woocommerce-cart #payment div.payment_box:before,.woocommerce-checkout #payment div.payment_box:before{content:"";display:block;border:1em solid #dfdcde;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-.75em;left:0;margin:-1em 0 0 2em}#add_payment_method #payment .payment_method_paypal .about_paypal,.woocommerce-cart #payment .payment_method_paypal .about_paypal,.woocommerce-checkout #payment .payment_method_paypal .about_paypal{float:right;line-height:52px;font-size:.83em}#add_payment_method #payment .payment_method_paypal img,.woocommerce-cart #payment .payment_method_paypal img,.woocommerce-checkout #payment .payment_method_paypal img{max-height:52px;vertical-align:middle}.woocommerce-password-strength{text-align:center;font-weight:600;padding:3px .5em;font-size:1em}.woocommerce-password-strength.strong{background-color:#c1e1b9;border-color:#83c373}.woocommerce-password-strength.short{background-color:#f1adad;border-color:#e35b5b}.woocommerce-password-strength.bad{background-color:#fbc5a9;border-color:#f78b53}.woocommerce-password-strength.good{background-color:#ffe399;border-color:#ffc733}.woocommerce-password-hint{margin:.5em 0 0;display:block}.product.has-default-attributes.has-children>.images{opacity:0}#content.twentyeleven .woocommerce-pagination a{font-size:1em;line-height:1}.single-product .twentythirteen #reply-title,.single-product .twentythirteen #respond #commentform,.single-product .twentythirteen .entry-summary{padding:0}.twentythirteen .woocommerce-breadcrumb{padding-top:40px}.twentyfourteen ul.products li.product{margin-top:0!important}body:not(.search-results) .twentysixteen .entry-summary{color:inherit;font-size:inherit;line-height:inherit}.twentysixteen .price ins{background:inherit;color:inherit} \ No newline at end of file +@charset "UTF-8";.clear,.woocommerce .woocommerce-breadcrumb:after{clear:both}@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg)}}@-moz-keyframes spin{100%{-moz-transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}@font-face{font-family:star;src:url(../fonts/star.eot);src:url(../fonts/star.eot?#iefix) format("embedded-opentype"),url(../fonts/star.woff) format("woff"),url(../fonts/star.ttf) format("truetype"),url(../fonts/star.svg#star) format("svg");font-weight:400;font-style:normal}@font-face{font-family:WooCommerce;src:url(../fonts/WooCommerce.eot);src:url(../fonts/WooCommerce.eot?#iefix) format("embedded-opentype"),url(../fonts/WooCommerce.woff) format("woff"),url(../fonts/WooCommerce.ttf) format("truetype"),url(../fonts/WooCommerce.svg#WooCommerce) format("svg");font-weight:400;font-style:normal}p.demo_store{position:fixed;top:0;left:0;right:0;margin:0;width:100%;font-size:1em;padding:1em 0;text-align:center;background-color:#a46497;color:#fff;z-index:99998;box-shadow:0 1px 1em rgba(0,0,0,.2)}p.demo_store a{color:#fff}.admin-bar p.demo_store{top:32px}.woocommerce .blockUI.blockOverlay{position:relative}.woocommerce .blockUI.blockOverlay:before,.woocommerce .loader:before{height:1em;width:1em;position:absolute;top:50%;left:50%;margin-left:-.5em;margin-top:-.5em;display:block;content:"";-webkit-animation:spin 1s ease-in-out infinite;-moz-animation:spin 1s ease-in-out infinite;animation:spin 1s ease-in-out infinite;background:url(../images/icons/loader.svg) center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75)}.woocommerce a.remove{display:block;font-size:1.5em;height:1em;width:1em;text-align:center;line-height:1;border-radius:100%;color:red!important;text-decoration:none;font-weight:700;border:0}.woocommerce a.remove:hover{color:#fff!important;background:red}.woocommerce small.note{display:block;color:#777;font-size:.857em;margin-top:10px}.woocommerce .woocommerce-breadcrumb{margin:0 0 1em;padding:0;font-size:.92em;color:#777}.woocommerce .woocommerce-breadcrumb:after,.woocommerce .woocommerce-breadcrumb:before{content:" ";display:table}.woocommerce .woocommerce-breadcrumb a{color:#777}.woocommerce .quantity .qty{width:3.631em;text-align:center}.woocommerce div.product{margin-bottom:0;position:relative}.woocommerce div.product .product_title{clear:none;margin-top:0;padding:0}.woocommerce #reviews #comments .add_review:after,.woocommerce .products ul:after,.woocommerce div.product form.cart:after,.woocommerce div.product p.cart:after,.woocommerce nav.woocommerce-pagination ul,.woocommerce ul.products:after{clear:both}.woocommerce div.product p.price,.woocommerce div.product span.price{color:#77a464;font-size:1.25em}.woocommerce div.product p.price ins,.woocommerce div.product span.price ins{background:inherit;font-weight:700}.woocommerce div.product p.price del,.woocommerce div.product span.price del{opacity:.5}.woocommerce div.product p.stock{font-size:.92em}.woocommerce div.product .stock{color:#77a464}.woocommerce div.product .out-of-stock{color:red}.woocommerce div.product .woocommerce-product-rating{margin-bottom:1.618em}.woocommerce div.product div.images,.woocommerce div.product div.summary{margin-bottom:2em}.woocommerce div.product div.images img{display:block;width:100%;height:auto;box-shadow:none}.woocommerce div.product div.images div.thumbnails{padding-top:1em}.woocommerce div.product div.social{text-align:right;margin:0 0 1em}.woocommerce div.product div.social span{margin:0 0 0 2px}.woocommerce div.product div.social span span{margin:0}.woocommerce div.product div.social span .stButton .chicklets{padding-left:16px;width:0}.woocommerce div.product div.social iframe{float:left;margin-top:3px}.woocommerce div.product .woocommerce-tabs ul.tabs{list-style:none;padding:0 0 0 1em;margin:0 0 1.618em;overflow:hidden;position:relative}.woocommerce div.product .woocommerce-tabs ul.tabs li{border:1px solid #d3ced2;background-color:#ebe9eb;display:inline-block;position:relative;z-index:0;border-radius:4px 4px 0 0;margin:0 -5px;padding:0 1em}.woocommerce div.product .woocommerce-tabs ul.tabs li a{display:inline-block;padding:.5em 0;font-weight:700;color:#515151;text-decoration:none}.woocommerce div.product form.cart:after,.woocommerce div.product form.cart:before,.woocommerce div.product p.cart:after,.woocommerce div.product p.cart:before{display:table;content:" "}.woocommerce div.product .woocommerce-tabs ul.tabs li a:hover{text-decoration:none;color:#6b6b6b}.woocommerce div.product .woocommerce-tabs ul.tabs li.active{background:#fff;z-index:2;border-bottom-color:#fff}.woocommerce div.product .woocommerce-tabs ul.tabs li.active a{color:inherit;text-shadow:inherit}.woocommerce div.product .woocommerce-tabs ul.tabs li.active:before{box-shadow:2px 2px 0 #fff}.woocommerce div.product .woocommerce-tabs ul.tabs li.active:after{box-shadow:-2px 2px 0 #fff}.woocommerce div.product .woocommerce-tabs ul.tabs li:after,.woocommerce div.product .woocommerce-tabs ul.tabs li:before{border:1px solid #d3ced2;position:absolute;bottom:-1px;width:5px;height:5px;content:" "}.woocommerce div.product .woocommerce-tabs ul.tabs li:before{left:-6px;-webkit-border-bottom-right-radius:4px;-moz-border-bottom-right-radius:4px;border-bottom-right-radius:4px;border-width:0 1px 1px 0;box-shadow:2px 2px 0 #ebe9eb}.woocommerce div.product .woocommerce-tabs ul.tabs li:after{right:-6px;-webkit-border-bottom-left-radius:4px;-moz-border-bottom-left-radius:4px;border-bottom-left-radius:4px;border-width:0 0 1px 1px;box-shadow:-2px 2px 0 #ebe9eb}.woocommerce div.product .woocommerce-tabs ul.tabs:before{position:absolute;content:" ";width:100%;bottom:0;left:0;border-bottom:1px solid #d3ced2;z-index:1}.woocommerce div.product .woocommerce-tabs .panel{margin:0 0 2em;padding:0}.woocommerce div.product form.cart,.woocommerce div.product p.cart{margin-bottom:2em}.woocommerce div.product form.cart div.quantity{float:left;margin:0 4px 0 0}.woocommerce div.product form.cart table{border-width:0 0 1px}.woocommerce div.product form.cart table td{padding-left:0}.woocommerce div.product form.cart table div.quantity{float:none;margin:0}.woocommerce div.product form.cart table small.stock{display:block;float:none}.woocommerce div.product form.cart .variations{margin-bottom:1em;border:0;width:100%}.woocommerce div.product form.cart .variations td,.woocommerce div.product form.cart .variations th{border:0;vertical-align:top;line-height:2em}.woocommerce div.product form.cart .variations label{font-weight:700}.woocommerce div.product form.cart .variations select{max-width:100%;min-width:75%;display:inline-block;margin-right:1em}.woocommerce div.product form.cart .variations td.label{padding-right:1em}.woocommerce div.product form.cart .woocommerce-variation-description p{margin-bottom:1em}.woocommerce div.product form.cart .reset_variations{visibility:hidden;font-size:.83em}.woocommerce div.product form.cart .wc-no-matching-variations{display:none}.woocommerce div.product form.cart .button{vertical-align:middle;float:left}.woocommerce div.product form.cart .group_table td.label{padding-right:1em;padding-left:1em}.woocommerce div.product form.cart .group_table td{vertical-align:top;padding-bottom:.5em;border:0}.woocommerce span.onsale{min-height:3.236em;min-width:3.236em;padding:.202em;font-weight:700;position:absolute;text-align:center;line-height:3.236;top:-.5em;left:-.5em;margin:0;border-radius:100%;background-color:#77a464;color:#fff;font-size:.857em;-webkit-font-smoothing:antialiased}.woocommerce .products ul,.woocommerce ul.products{margin:0 0 1em;padding:0;list-style:none;clear:both}.woocommerce .products ul:after,.woocommerce .products ul:before,.woocommerce ul.products:after,.woocommerce ul.products:before{content:" ";display:table}.woocommerce .products ul li,.woocommerce ul.products li{list-style:none}.woocommerce ul.products li.product .onsale{top:0;right:0;left:auto;margin:-.5em -.5em 0 0}.woocommerce ul.products li.product h3{padding:.5em 0;margin:0;font-size:1em}.woocommerce ul.products li.product a{text-decoration:none}.woocommerce ul.products li.product a img{width:100%;height:auto;display:block;margin:0 0 1em;box-shadow:none}.woocommerce ul.products li.product strong{display:block}.woocommerce ul.products li.product .star-rating{font-size:.857em}.woocommerce ul.products li.product .button{margin-top:1em}.woocommerce ul.products li.product .price{color:#77a464;display:block;font-weight:400;margin-bottom:.5em;font-size:.857em}.woocommerce ul.products li.product .price del{color:inherit;opacity:.5;display:block}.woocommerce ul.products li.product .price ins{background:0 0;font-weight:700}.woocommerce ul.products li.product .price .from{font-size:.67em;margin:-2px 0 0;text-transform:uppercase;color:rgba(132,132,132,.5)}.woocommerce .woocommerce-ordering,.woocommerce .woocommerce-result-count{margin:0 0 1em}.woocommerce .woocommerce-ordering select{vertical-align:top}.woocommerce nav.woocommerce-pagination{text-align:center}.woocommerce nav.woocommerce-pagination ul{display:inline-block;white-space:nowrap;padding:0;border:1px solid #d3ced2;border-right:0;margin:1px}.woocommerce nav.woocommerce-pagination ul li{border-right:1px solid #d3ced2;padding:0;margin:0;float:left;display:inline;overflow:hidden}.woocommerce nav.woocommerce-pagination ul li a,.woocommerce nav.woocommerce-pagination ul li span{margin:0;text-decoration:none;line-height:1;font-size:1em;font-weight:400;padding:.5em;min-width:1em;display:block}.woocommerce nav.woocommerce-pagination ul li a:focus,.woocommerce nav.woocommerce-pagination ul li a:hover,.woocommerce nav.woocommerce-pagination ul li span.current{background:#ebe9eb;color:#8a7e88}.woocommerce #respond input#submit,.woocommerce a.button,.woocommerce button.button,.woocommerce input.button{font-size:100%;margin:0;line-height:1;cursor:pointer;position:relative;text-decoration:none;overflow:visible;padding:.618em 1em;font-weight:700;border-radius:3px;left:auto;color:#515151;background-color:#ebe9eb;border:0;white-space:nowrap;display:inline-block;background-image:none;box-shadow:none;-webkit-box-shadow:none;text-shadow:none}.woocommerce #respond input#submit.loading,.woocommerce a.button.loading,.woocommerce button.button.loading,.woocommerce input.button.loading{opacity:.25;padding-right:2.618em}.woocommerce #respond input#submit.loading:after,.woocommerce a.button.loading:after,.woocommerce button.button.loading:after,.woocommerce input.button.loading:after{font-family:WooCommerce;content:"\e01c";vertical-align:top;-webkit-font-smoothing:antialiased;font-weight:400;position:absolute;top:.618em;right:1em;-webkit-animation:spin 2s linear infinite;-moz-animation:spin 2s linear infinite;animation:spin 2s linear infinite}.woocommerce #respond input#submit.added:after,.woocommerce a.button.added:after,.woocommerce button.button.added:after,.woocommerce input.button.added:after{font-family:WooCommerce;content:"\e017";margin-left:.53em;vertical-align:bottom}.woocommerce #respond input#submit:hover,.woocommerce a.button:hover,.woocommerce button.button:hover,.woocommerce input.button:hover{background-color:#dad8da;text-decoration:none;background-image:none;color:#515151}.woocommerce #respond input#submit.alt,.woocommerce a.button.alt,.woocommerce button.button.alt,.woocommerce input.button.alt{background-color:#a46497;color:#fff;-webkit-font-smoothing:antialiased}.woocommerce #respond input#submit.alt:hover,.woocommerce a.button.alt:hover,.woocommerce button.button.alt:hover,.woocommerce input.button.alt:hover{background-color:#935386;color:#fff}.woocommerce #respond input#submit.alt.disabled,.woocommerce #respond input#submit.alt.disabled:hover,.woocommerce #respond input#submit.alt:disabled,.woocommerce #respond input#submit.alt:disabled:hover,.woocommerce #respond input#submit.alt:disabled[disabled],.woocommerce #respond input#submit.alt:disabled[disabled]:hover,.woocommerce a.button.alt.disabled,.woocommerce a.button.alt.disabled:hover,.woocommerce a.button.alt:disabled,.woocommerce a.button.alt:disabled:hover,.woocommerce a.button.alt:disabled[disabled],.woocommerce a.button.alt:disabled[disabled]:hover,.woocommerce button.button.alt.disabled,.woocommerce button.button.alt.disabled:hover,.woocommerce button.button.alt:disabled,.woocommerce button.button.alt:disabled:hover,.woocommerce button.button.alt:disabled[disabled],.woocommerce button.button.alt:disabled[disabled]:hover,.woocommerce input.button.alt.disabled,.woocommerce input.button.alt.disabled:hover,.woocommerce input.button.alt:disabled,.woocommerce input.button.alt:disabled:hover,.woocommerce input.button.alt:disabled[disabled],.woocommerce input.button.alt:disabled[disabled]:hover{background-color:#a46497;color:#fff}.woocommerce #respond input#submit.disabled,.woocommerce #respond input#submit:disabled,.woocommerce #respond input#submit:disabled[disabled],.woocommerce a.button.disabled,.woocommerce a.button:disabled,.woocommerce a.button:disabled[disabled],.woocommerce button.button.disabled,.woocommerce button.button:disabled,.woocommerce button.button:disabled[disabled],.woocommerce input.button.disabled,.woocommerce input.button:disabled,.woocommerce input.button:disabled[disabled]{color:inherit;cursor:not-allowed;opacity:.5;padding:.618em 1em}.woocommerce #respond input#submit.disabled:hover,.woocommerce #respond input#submit:disabled:hover,.woocommerce #respond input#submit:disabled[disabled]:hover,.woocommerce a.button.disabled:hover,.woocommerce a.button:disabled:hover,.woocommerce a.button:disabled[disabled]:hover,.woocommerce button.button.disabled:hover,.woocommerce button.button:disabled:hover,.woocommerce button.button:disabled[disabled]:hover,.woocommerce input.button.disabled:hover,.woocommerce input.button:disabled:hover,.woocommerce input.button:disabled[disabled]:hover{color:inherit;background-color:#ebe9eb}.woocommerce .cart .button,.woocommerce .cart input.button{float:none}.woocommerce a.added_to_cart{padding-top:.5em;white-space:nowrap;display:inline-block}.woocommerce #reviews #comments .add_review:after,.woocommerce #reviews #comments .add_review:before,.woocommerce #reviews #comments ol.commentlist li .comment-text:after,.woocommerce #reviews #comments ol.commentlist li .comment-text:before,.woocommerce #reviews #comments ol.commentlist:after,.woocommerce #reviews #comments ol.commentlist:before{content:" ";display:table}.woocommerce #reviews h2 small{float:right;color:#777;font-size:15px;margin:10px 0 0}.woocommerce #reviews h2 small a{text-decoration:none;color:#777}.woocommerce #reviews h3{margin:0}.woocommerce #reviews #respond{margin:0;border:0;padding:0}.woocommerce #reviews #comment{height:75px}.woocommerce #reviews #comments h2{clear:none}.woocommerce #review_form #respond:after,.woocommerce #reviews #comments ol.commentlist li .comment-text:after,.woocommerce #reviews #comments ol.commentlist:after,.woocommerce .woocommerce-product-rating:after,.woocommerce td.product-name dl.variation:after{clear:both}.woocommerce #reviews #comments ol.commentlist{margin:0;width:100%;background:0 0;list-style:none}.woocommerce #reviews #comments ol.commentlist li{padding:0;margin:0 0 20px;position:relative;background:0;border:0}.woocommerce #reviews #comments ol.commentlist li .meta{color:#777;font-size:.75em}.woocommerce #reviews #comments ol.commentlist li img.avatar{float:left;position:absolute;top:0;left:0;padding:3px;width:32px;height:auto;background:#ebe9eb;border:1px solid #e4e1e3;margin:0;box-shadow:none}.woocommerce #reviews #comments ol.commentlist li .comment-text{margin:0 0 0 50px;border:1px solid #e4e1e3;border-radius:4px;padding:1em 1em 0}.woocommerce #reviews #comments ol.commentlist li .comment-text p{margin:0 0 1em}.woocommerce #reviews #comments ol.commentlist li .comment-text p.meta{font-size:.83em}.woocommerce #reviews #comments ol.commentlist ul.children{list-style:none;margin:20px 0 0 50px}.woocommerce #reviews #comments ol.commentlist ul.children .star-rating{display:none}.woocommerce #reviews #comments ol.commentlist #respond{border:1px solid #e4e1e3;border-radius:4px;padding:1em 1em 0;margin:20px 0 0 50px}.woocommerce #reviews #comments .commentlist>li:before{content:""}.woocommerce .star-rating{float:right;overflow:hidden;position:relative;height:1em;line-height:1;font-size:1em;width:5.4em;font-family:star}.woocommerce .star-rating:before{content:"\73\73\73\73\73";color:#d3ced2;float:left;top:0;left:0;position:absolute}.woocommerce .star-rating span{overflow:hidden;float:left;top:0;left:0;position:absolute;padding-top:1.5em}.woocommerce .star-rating span:before{content:"\53\53\53\53\53";top:0;position:absolute;left:0}.woocommerce .woocommerce-product-rating{line-height:2;display:block}.woocommerce .woocommerce-product-rating:after,.woocommerce .woocommerce-product-rating:before{content:" ";display:table}.woocommerce .woocommerce-product-rating .star-rating{margin:.5em 4px 0 0;float:left}.woocommerce .products .star-rating{display:block;margin:0 0 .5em;float:none}.woocommerce .hreview-aggregate .star-rating{margin:10px 0 0}.woocommerce #review_form #respond{position:static;margin:0;width:auto;padding:0;background:0 0;border:0}.woocommerce #review_form #respond:after,.woocommerce #review_form #respond:before{content:" ";display:table}.woocommerce p.stars a:before,.woocommerce p.stars a:hover~a:before{content:"\e021"}.woocommerce #review_form #respond p{margin:0 0 10px}.woocommerce #review_form #respond .form-submit input{left:auto}.woocommerce #review_form #respond textarea{box-sizing:border-box;width:100%}.woocommerce p.stars a{position:relative;height:1em;width:1em;text-indent:-999em;display:inline-block;text-decoration:none}.woocommerce p.stars a:before{display:block;position:absolute;top:0;left:0;width:1em;height:1em;line-height:1;font-family:WooCommerce;text-indent:0}.woocommerce table.shop_attributes td,.woocommerce table.shop_attributes th{line-height:1.5;border-bottom:1px dotted rgba(0,0,0,.1);border-top:0;margin:0}.woocommerce p.stars.selected a.active:before,.woocommerce p.stars:hover a:before{content:"\e020"}.woocommerce p.stars.selected a.active~a:before{content:"\e021"}.woocommerce p.stars.selected a:not(.active):before{content:"\e020"}.woocommerce table.shop_attributes{border:0;border-top:1px dotted rgba(0,0,0,.1);margin-bottom:1.618em;width:100%}.woocommerce table.shop_attributes th{width:150px;font-weight:700;padding:8px}.woocommerce table.shop_attributes td{font-style:italic;padding:0}.woocommerce table.shop_attributes td p{margin:0;padding:8px 0}.woocommerce table.shop_attributes .alt td,.woocommerce table.shop_attributes .alt th{background:rgba(0,0,0,.025)}.woocommerce table.shop_table{border:1px solid rgba(0,0,0,.1);margin:0 -1px 24px 0;text-align:left;width:100%;border-collapse:separate;border-radius:5px}.woocommerce table.shop_table th{font-weight:700;padding:9px 12px}.woocommerce table.shop_table td{border-top:1px solid rgba(0,0,0,.1);padding:6px 12px;vertical-align:middle}.woocommerce table.shop_table td small{font-weight:400}.woocommerce table.shop_table tbody:first-child tr:first-child td,.woocommerce table.shop_table tbody:first-child tr:first-child th{border-top:0}.woocommerce table.shop_table tbody th,.woocommerce table.shop_table tfoot td,.woocommerce table.shop_table tfoot th{font-weight:700;border-top:1px solid rgba(0,0,0,.1)}.woocommerce table.my_account_orders{font-size:.85em}.woocommerce table.my_account_orders td,.woocommerce table.my_account_orders th{padding:4px 8px;vertical-align:middle}.woocommerce table.my_account_orders .button{white-space:nowrap}.woocommerce table.my_account_orders .order-actions{text-align:right}.woocommerce table.my_account_orders .order-actions .button{margin:.125em 0 .125em .25em}.woocommerce td.product-name dl.variation{margin:.25em 0}.woocommerce td.product-name dl.variation:after,.woocommerce td.product-name dl.variation:before{content:" ";display:table}.woocommerce td.product-name dl.variation dd,.woocommerce td.product-name dl.variation dt{display:inline-block;float:left;margin-bottom:1em}.woocommerce td.product-name dl.variation dt{font-weight:700;padding:0 0 .25em;margin:0 4px 0 0;clear:left}.woocommerce ul.cart_list li dl:after,.woocommerce ul.cart_list li:after,.woocommerce ul.product_list_widget li dl:after,.woocommerce ul.product_list_widget li:after{clear:both}.woocommerce td.product-name dl.variation dd{padding:0 0 .25em}.woocommerce td.product-name dl.variation dd p:last-child{margin-bottom:0}.woocommerce td.product-name p.backorder_notification{font-size:.83em}.woocommerce td.product-quantity{min-width:80px}.woocommerce ul.cart_list,.woocommerce ul.product_list_widget{list-style:none;padding:0;margin:0}.woocommerce ul.cart_list li,.woocommerce ul.product_list_widget li{padding:4px 0;margin:0;list-style:none}.woocommerce ul.cart_list li:after,.woocommerce ul.cart_list li:before,.woocommerce ul.product_list_widget li:after,.woocommerce ul.product_list_widget li:before{content:" ";display:table}.woocommerce ul.cart_list li a,.woocommerce ul.product_list_widget li a{display:block;font-weight:700}.woocommerce ul.cart_list li img,.woocommerce ul.product_list_widget li img{float:right;margin-left:4px;width:32px;height:auto;box-shadow:none}.woocommerce ul.cart_list li dl,.woocommerce ul.product_list_widget li dl{margin:0;padding-left:1em;border-left:2px solid rgba(0,0,0,.1)}.woocommerce ul.cart_list li dl:after,.woocommerce ul.cart_list li dl:before,.woocommerce ul.product_list_widget li dl:after,.woocommerce ul.product_list_widget li dl:before{content:" ";display:table}.woocommerce ul.cart_list li dl dd,.woocommerce ul.cart_list li dl dt,.woocommerce ul.product_list_widget li dl dd,.woocommerce ul.product_list_widget li dl dt{display:inline-block;float:left;margin-bottom:1em}.woocommerce ul.cart_list li dl dt,.woocommerce ul.product_list_widget li dl dt{font-weight:700;padding:0 0 .25em;margin:0 4px 0 0;clear:left}#add_payment_method .wc-proceed-to-checkout:after,.woocommerce .order_details:after,.woocommerce .widget_layered_nav ul li:after,.woocommerce .widget_rating_filter ul li:after,.woocommerce .widget_shopping_cart .buttons:after,.woocommerce-account .addresses .title:after,.woocommerce-account .woocommerce:after,.woocommerce-cart .wc-proceed-to-checkout:after,.woocommerce-checkout .wc-proceed-to-checkout:after,.woocommerce-error:after,.woocommerce-info:after,.woocommerce-message:after,.woocommerce.widget_shopping_cart .buttons:after{clear:both}.woocommerce ul.cart_list li dl dd,.woocommerce ul.product_list_widget li dl dd{padding:0 0 .25em}.woocommerce ul.cart_list li dl dd p:last-child,.woocommerce ul.product_list_widget li dl dd p:last-child{margin-bottom:0}.woocommerce ul.cart_list li .star-rating,.woocommerce ul.product_list_widget li .star-rating{float:none}.woocommerce .widget_shopping_cart .total,.woocommerce.widget_shopping_cart .total{border-top:3px double #ebe9eb;padding:4px 0 0}.woocommerce .widget_shopping_cart .total strong,.woocommerce.widget_shopping_cart .total strong{min-width:40px;display:inline-block}.woocommerce .widget_shopping_cart .cart_list li,.woocommerce.widget_shopping_cart .cart_list li{padding-left:2em;position:relative;padding-top:0}.woocommerce .widget_shopping_cart .cart_list li a.remove,.woocommerce.widget_shopping_cart .cart_list li a.remove{position:absolute;top:0;left:0}.woocommerce .widget_shopping_cart .buttons:after,.woocommerce .widget_shopping_cart .buttons:before,.woocommerce.widget_shopping_cart .buttons:after,.woocommerce.widget_shopping_cart .buttons:before{content:" ";display:table}.woocommerce .widget_shopping_cart .buttons a,.woocommerce.widget_shopping_cart .buttons a{margin-right:5px;margin-bottom:5px}.woocommerce form .form-row{padding:3px;margin:0 0 6px}.woocommerce form .form-row [placeholder]:focus::-webkit-input-placeholder{-webkit-transition:opacity .5s .5s ease;-moz-transition:opacity .5s .5s ease;transition:opacity .5s .5s ease;opacity:0}.woocommerce form .form-row label{line-height:2}.woocommerce form .form-row label.hidden{visibility:hidden}.woocommerce form .form-row label.inline{display:inline}.woocommerce form .form-row select{cursor:pointer;margin:0}.woocommerce form .form-row .required{color:red;font-weight:700;border:0}.woocommerce form .form-row .input-checkbox{display:inline;margin:-2px 8px 0 0;text-align:center;vertical-align:middle}.woocommerce form .form-row input.input-text,.woocommerce form .form-row textarea{box-sizing:border-box;width:100%;margin:0;outline:0;line-height:1}.woocommerce form .form-row textarea{height:4em;line-height:1.5;display:block;-moz-box-shadow:none;-webkit-box-shadow:none;box-shadow:none}.woocommerce form .form-row .select2-container{width:100%;line-height:2em}.woocommerce form .form-row.woocommerce-invalid label{color:#a00}.woocommerce form .form-row.woocommerce-invalid .select2-container,.woocommerce form .form-row.woocommerce-invalid input.input-text,.woocommerce form .form-row.woocommerce-invalid select{border-color:#a00}.woocommerce form .form-row.woocommerce-validated .select2-container,.woocommerce form .form-row.woocommerce-validated input.input-text,.woocommerce form .form-row.woocommerce-validated select{border-color:#69bf29}.woocommerce form .form-row ::-webkit-input-placeholder{line-height:normal}.woocommerce form .form-row :-moz-placeholder{line-height:normal}.woocommerce form .form-row :-ms-input-placeholder{line-height:normal}.woocommerce form.checkout_coupon,.woocommerce form.login,.woocommerce form.register{border:1px solid #d3ced2;padding:20px;margin:2em 0;text-align:left;border-radius:5px}.woocommerce ul#shipping_method{list-style:none;margin:0;padding:0}.woocommerce ul#shipping_method li{margin:0;padding:.25em 0 .25em 22px;text-indent:-22px;list-style:none}.woocommerce ul#shipping_method li input{margin:3px .5ex}.woocommerce ul#shipping_method li label{display:inline}.woocommerce ul#shipping_method .amount{font-weight:700}.woocommerce p.woocommerce-shipping-contents{margin:0}.woocommerce .order_details{margin:0 0 1.5em;list-style:none}.woocommerce .order_details:after,.woocommerce .order_details:before{content:" ";display:table}.woocommerce .order_details li{float:left;margin-right:2em;text-transform:uppercase;font-size:.715em;line-height:1;border-right:1px dashed #d3ced2;padding-right:2em;margin-left:0;padding-left:0;list-style-type:none}.woocommerce .order_details li strong{display:block;font-size:1.4em;text-transform:none;line-height:1.5}.woocommerce .order_details li:last-of-type{border:none}.woocommerce .widget_layered_nav ul{margin:0;padding:0;border:0;list-style:none}.woocommerce .widget_layered_nav ul li{padding:0 0 1px;list-style:none}.woocommerce .widget_layered_nav ul li:after,.woocommerce .widget_layered_nav ul li:before{content:" ";display:table}.woocommerce .widget_layered_nav ul li.chosen a:before,.woocommerce .widget_layered_nav_filters ul li a:before{line-height:1;content:"";font-family:WooCommerce;font-weight:400;color:#a00;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-decoration:none}.woocommerce .widget_layered_nav ul li a,.woocommerce .widget_layered_nav ul li span{padding:1px 0}.woocommerce .widget_layered_nav ul li.chosen a:before{margin-right:.618em}.woocommerce .widget_layered_nav_filters ul{margin:0;padding:0;border:0;list-style:none;overflow:hidden;zoom:1}.woocommerce .widget_layered_nav_filters ul li{float:left;padding:0 1px 1px 0;list-style:none}.woocommerce .widget_layered_nav_filters ul li a{text-decoration:none}.woocommerce .widget_layered_nav_filters ul li a:before{margin-right:.618em}.woocommerce .widget_price_filter .price_slider{margin-bottom:1em}.woocommerce .widget_price_filter .price_slider_amount{text-align:right;line-height:2.4;font-size:.8751em}.woocommerce .widget_price_filter .price_slider_amount .button{font-size:1.15em;float:left}.woocommerce .widget_price_filter .ui-slider{position:relative;text-align:left;margin-left:.5em;margin-right:.5em}.woocommerce .widget_price_filter .ui-slider .ui-slider-handle{position:absolute;z-index:2;width:1em;height:1em;background-color:#a46497;border-radius:1em;cursor:ew-resize;outline:0;top:-.3em;margin-left:-.5em}.woocommerce .widget_price_filter .ui-slider .ui-slider-range{position:absolute;z-index:1;font-size:.7em;display:block;border:0;border-radius:1em;background-color:#a46497}.woocommerce .widget_price_filter .price_slider_wrapper .ui-widget-content{border-radius:1em;background-color:#602053;border:0}.woocommerce .widget_price_filter .ui-slider-horizontal{height:.5em}.woocommerce .widget_price_filter .ui-slider-horizontal .ui-slider-range{top:0;height:100%}.woocommerce .widget_price_filter .ui-slider-horizontal .ui-slider-range-min{left:-1px}.woocommerce .widget_price_filter .ui-slider-horizontal .ui-slider-range-max{right:-1px}.woocommerce .widget_rating_filter ul{margin:0;padding:0;border:0;list-style:none}.woocommerce .widget_rating_filter ul li{padding:0 0 1px;list-style:none}.woocommerce .widget_rating_filter ul li:after,.woocommerce .widget_rating_filter ul li:before{content:" ";display:table}.woocommerce .widget_rating_filter ul li a{padding:1px 0;text-decoration:none}.woocommerce .widget_rating_filter ul li .star-rating{float:none;display:inline-block}.woocommerce .widget_rating_filter ul li.chosen a:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none;color:#a00}.woocommerce-error,.woocommerce-info,.woocommerce-message{padding:1em 2em 1em 3.5em!important;margin:0 0 2em!important;position:relative;background-color:#f7f6f7;color:#515151;border-top:3px solid #a46497;list-style:none!important;width:auto;word-wrap:break-word}.woocommerce-error:after,.woocommerce-error:before,.woocommerce-info:after,.woocommerce-info:before,.woocommerce-message:after,.woocommerce-message:before{content:" ";display:table}.woocommerce-error:before,.woocommerce-info:before,.woocommerce-message:before{font-family:WooCommerce;content:"\e028";display:inline-block;position:absolute;top:1em;left:1.5em}.woocommerce-error .button,.woocommerce-info .button,.woocommerce-message .button{float:right}.woocommerce-error li,.woocommerce-info li,.woocommerce-message li{list-style:none!important;padding-left:0!important;margin-left:0!important}.woocommerce-message{border-top-color:#8fae1b}.woocommerce-message:before{content:"\e015";color:#8fae1b}.woocommerce-info{border-top-color:#1e85be}.woocommerce-info:before{color:#1e85be}.woocommerce-error{border-top-color:#b81c23}.woocommerce-error:before{content:"\e016";color:#b81c23}.woocommerce-account .addresses .title:after,.woocommerce-account .addresses .title:before,.woocommerce-account .woocommerce:after,.woocommerce-account .woocommerce:before{content:" ";display:table}.woocommerce-account .addresses .title h3{float:left}.woocommerce-account .addresses .title .edit,.woocommerce-account ul.digital-downloads li .count{float:right}.woocommerce-account ol.commentlist.notes li.note p.meta{font-weight:700;margin-bottom:0}.woocommerce-account ol.commentlist.notes li.note .description p:last-child{margin-bottom:0}.woocommerce-account ul.digital-downloads{margin-left:0;padding-left:0}.woocommerce-account ul.digital-downloads li{list-style:none;margin-left:0;padding-left:0}.woocommerce-account ul.digital-downloads li:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}#add_payment_method table.cart .product-thumbnail,.woocommerce-cart table.cart .product-thumbnail,.woocommerce-checkout table.cart .product-thumbnail{min-width:32px}#add_payment_method table.cart img,.woocommerce-cart table.cart img,.woocommerce-checkout table.cart img{width:32px;box-shadow:none}#add_payment_method table.cart td,#add_payment_method table.cart th,.woocommerce-cart table.cart td,.woocommerce-cart table.cart th,.woocommerce-checkout table.cart td,.woocommerce-checkout table.cart th{vertical-align:middle}#add_payment_method table.cart td.actions .coupon .input-text,.woocommerce-cart table.cart td.actions .coupon .input-text,.woocommerce-checkout table.cart td.actions .coupon .input-text{float:left;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;border:1px solid #d3ced2;padding:6px 6px 5px;margin:0 4px 0 0;outline:0;line-height:1}#add_payment_method table.cart input,.woocommerce-cart table.cart input,.woocommerce-checkout table.cart input{margin:0;vertical-align:middle;line-height:1}#add_payment_method .wc-proceed-to-checkout,.woocommerce-cart .wc-proceed-to-checkout,.woocommerce-checkout .wc-proceed-to-checkout{padding:1em 0}#add_payment_method .wc-proceed-to-checkout:after,#add_payment_method .wc-proceed-to-checkout:before,.woocommerce-cart .wc-proceed-to-checkout:after,.woocommerce-cart .wc-proceed-to-checkout:before,.woocommerce-checkout .wc-proceed-to-checkout:after,.woocommerce-checkout .wc-proceed-to-checkout:before{content:" ";display:table}#add_payment_method .wc-proceed-to-checkout a.checkout-button,.woocommerce-cart .wc-proceed-to-checkout a.checkout-button,.woocommerce-checkout .wc-proceed-to-checkout a.checkout-button{display:block;text-align:center;margin-bottom:1em;font-size:1.25em;padding:1em}#add_payment_method .cart-collaterals .shipping_calculator .button,.woocommerce-cart .cart-collaterals .shipping_calculator .button,.woocommerce-checkout .cart-collaterals .shipping_calculator .button{width:100%;float:none;display:block}#add_payment_method .cart-collaterals .shipping_calculator .shipping-calculator-button:after,.woocommerce-cart .cart-collaterals .shipping_calculator .shipping-calculator-button:after,.woocommerce-checkout .cart-collaterals .shipping_calculator .shipping-calculator-button:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-left:.618em;content:"";text-decoration:none}#add_payment_method #payment ul.payment_methods li:after,#add_payment_method #payment ul.payment_methods li:before,#add_payment_method #payment ul.payment_methods:after,#add_payment_method #payment ul.payment_methods:before,.woocommerce-cart #payment ul.payment_methods li:after,.woocommerce-cart #payment ul.payment_methods li:before,.woocommerce-cart #payment ul.payment_methods:after,.woocommerce-cart #payment ul.payment_methods:before,.woocommerce-checkout #payment ul.payment_methods li:after,.woocommerce-checkout #payment ul.payment_methods li:before,.woocommerce-checkout #payment ul.payment_methods:after,.woocommerce-checkout #payment ul.payment_methods:before{content:" ";display:table}#add_payment_method .cart-collaterals .cart_totals p small,.woocommerce-cart .cart-collaterals .cart_totals p small,.woocommerce-checkout .cart-collaterals .cart_totals p small{color:#777;font-size:.83em}#add_payment_method .cart-collaterals .cart_totals table,.woocommerce-cart .cart-collaterals .cart_totals table,.woocommerce-checkout .cart-collaterals .cart_totals table{border-collapse:separate;margin:0 0 6px;padding:0}#add_payment_method .cart-collaterals .cart_totals table tr:first-child td,#add_payment_method .cart-collaterals .cart_totals table tr:first-child th,.woocommerce-cart .cart-collaterals .cart_totals table tr:first-child td,.woocommerce-cart .cart-collaterals .cart_totals table tr:first-child th,.woocommerce-checkout .cart-collaterals .cart_totals table tr:first-child td,.woocommerce-checkout .cart-collaterals .cart_totals table tr:first-child th{border-top:0}#add_payment_method .cart-collaterals .cart_totals table th,.woocommerce-cart .cart-collaterals .cart_totals table th,.woocommerce-checkout .cart-collaterals .cart_totals table th{width:40%}#add_payment_method .cart-collaterals .cart_totals table td,#add_payment_method .cart-collaterals .cart_totals table th,.woocommerce-cart .cart-collaterals .cart_totals table td,.woocommerce-cart .cart-collaterals .cart_totals table th,.woocommerce-checkout .cart-collaterals .cart_totals table td,.woocommerce-checkout .cart-collaterals .cart_totals table th{vertical-align:top;border-left:0;border-right:0;line-height:1.5em}#add_payment_method .cart-collaterals .cart_totals table small,.woocommerce-cart .cart-collaterals .cart_totals table small,.woocommerce-checkout .cart-collaterals .cart_totals table small{color:#777}#add_payment_method .cart-collaterals .cart_totals table select,.woocommerce-cart .cart-collaterals .cart_totals table select,.woocommerce-checkout .cart-collaterals .cart_totals table select{width:100%}#add_payment_method .cart-collaterals .cart_totals .discount td,.woocommerce-cart .cart-collaterals .cart_totals .discount td,.woocommerce-checkout .cart-collaterals .cart_totals .discount td{color:#77a464}#add_payment_method .cart-collaterals .cart_totals tr td,#add_payment_method .cart-collaterals .cart_totals tr th,.woocommerce-cart .cart-collaterals .cart_totals tr td,.woocommerce-cart .cart-collaterals .cart_totals tr th,.woocommerce-checkout .cart-collaterals .cart_totals tr td,.woocommerce-checkout .cart-collaterals .cart_totals tr th{border-top:1px solid #ebe9eb}#add_payment_method .cart-collaterals .cross-sells ul.products li.product,.woocommerce-cart .cart-collaterals .cross-sells ul.products li.product,.woocommerce-checkout .cart-collaterals .cross-sells ul.products li.product{margin-top:0}#add_payment_method .checkout .col-2 h3#ship-to-different-address,.woocommerce-cart .checkout .col-2 h3#ship-to-different-address,.woocommerce-checkout .checkout .col-2 h3#ship-to-different-address{float:left;clear:none}#add_payment_method .checkout .col-2 .form-row-first,#add_payment_method .checkout .col-2 .notes,.woocommerce-cart .checkout .col-2 .form-row-first,.woocommerce-cart .checkout .col-2 .notes,.woocommerce-checkout .checkout .col-2 .form-row-first,.woocommerce-checkout .checkout .col-2 .notes{clear:left}#add_payment_method .checkout .create-account small,.woocommerce-cart .checkout .create-account small,.woocommerce-checkout .checkout .create-account small{font-size:11px;color:#777;font-weight:400}#add_payment_method .checkout div.shipping-address,.woocommerce-cart .checkout div.shipping-address,.woocommerce-checkout .checkout div.shipping-address{padding:0;clear:left;width:100%}#add_payment_method #payment ul.payment_methods li:after,#add_payment_method #payment ul.payment_methods:after,#add_payment_method .checkout .shipping_address,.single-product .twentythirteen p.stars,.woocommerce-cart #payment ul.payment_methods li:after,.woocommerce-cart #payment ul.payment_methods:after,.woocommerce-cart .checkout .shipping_address,.woocommerce-checkout #payment ul.payment_methods li:after,.woocommerce-checkout #payment ul.payment_methods:after,.woocommerce-checkout .checkout .shipping_address{clear:both}#add_payment_method #payment,.woocommerce-cart #payment,.woocommerce-checkout #payment{background:#ebe9eb;border-radius:5px}#add_payment_method #payment ul.payment_methods,.woocommerce-cart #payment ul.payment_methods,.woocommerce-checkout #payment ul.payment_methods{text-align:left;padding:1em;border-bottom:1px solid #d3ced2;margin:0;list-style:none}#add_payment_method #payment ul.payment_methods li,.woocommerce-cart #payment ul.payment_methods li,.woocommerce-checkout #payment ul.payment_methods li{line-height:2;text-align:left;margin:0;font-weight:400}#add_payment_method #payment ul.payment_methods li input,.woocommerce-cart #payment ul.payment_methods li input,.woocommerce-checkout #payment ul.payment_methods li input{margin:0 1em 0 0}#add_payment_method #payment ul.payment_methods li img,.woocommerce-cart #payment ul.payment_methods li img,.woocommerce-checkout #payment ul.payment_methods li img{vertical-align:middle;margin:-2px 0 0 .5em;padding:0;position:relative;box-shadow:none}#add_payment_method #payment ul.payment_methods li img+img,.woocommerce-cart #payment ul.payment_methods li img+img,.woocommerce-checkout #payment ul.payment_methods li img+img{margin-left:2px}#add_payment_method #payment div.form-row,.woocommerce-cart #payment div.form-row,.woocommerce-checkout #payment div.form-row{padding:1em}#add_payment_method #payment div.payment_box,.woocommerce-cart #payment div.payment_box,.woocommerce-checkout #payment div.payment_box{position:relative;box-sizing:border-box;width:100%;padding:1em;margin:1em 0;font-size:.92em;border-radius:2px;line-height:1.5;background-color:#dfdcde;color:#515151}#add_payment_method #payment div.payment_box input.input-text,#add_payment_method #payment div.payment_box textarea,.woocommerce-cart #payment div.payment_box input.input-text,.woocommerce-cart #payment div.payment_box textarea,.woocommerce-checkout #payment div.payment_box input.input-text,.woocommerce-checkout #payment div.payment_box textarea{border-color:#bbb3b9 #c7c1c6 #c7c1c6}#add_payment_method #payment div.payment_box ::-webkit-input-placeholder,.woocommerce-cart #payment div.payment_box ::-webkit-input-placeholder,.woocommerce-checkout #payment div.payment_box ::-webkit-input-placeholder{color:#bbb3b9}#add_payment_method #payment div.payment_box :-moz-placeholder,.woocommerce-cart #payment div.payment_box :-moz-placeholder,.woocommerce-checkout #payment div.payment_box :-moz-placeholder{color:#bbb3b9}#add_payment_method #payment div.payment_box :-ms-input-placeholder,.woocommerce-cart #payment div.payment_box :-ms-input-placeholder,.woocommerce-checkout #payment div.payment_box :-ms-input-placeholder{color:#bbb3b9}#add_payment_method #payment div.payment_box .woocommerce-SavedPaymentMethods,.woocommerce-cart #payment div.payment_box .woocommerce-SavedPaymentMethods,.woocommerce-checkout #payment div.payment_box .woocommerce-SavedPaymentMethods{list-style:none;margin:0}#add_payment_method #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-new,#add_payment_method #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-token,.woocommerce-cart #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-new,.woocommerce-cart #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-token,.woocommerce-checkout #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-new,.woocommerce-checkout #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-token{margin:0 0 .5em}#add_payment_method #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-new label,#add_payment_method #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-token label,.woocommerce-cart #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-new label,.woocommerce-cart #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-token label,.woocommerce-checkout #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-new label,.woocommerce-checkout #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-token label{cursor:pointer}#add_payment_method #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-tokenInput,.woocommerce-cart #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-tokenInput,.woocommerce-checkout #payment div.payment_box .woocommerce-SavedPaymentMethods .woocommerce-SavedPaymentMethods-tokenInput{vertical-align:middle;margin:-3px 1em 0 0;position:relative}#add_payment_method #payment div.payment_box .wc-credit-card-form,.woocommerce-cart #payment div.payment_box .wc-credit-card-form,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form{border:0;padding:0;margin:1em 0 0}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number{font-size:1.5em;padding:8px;background-repeat:no-repeat;background-position:right .618em center;background-size:32px 20px}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.visa,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.visa,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.visa,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.visa,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.visa,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.visa,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.visa,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.visa,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.visa{background-image:url(../images/icons/credit-cards/visa.svg)}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.mastercard,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.mastercard,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.mastercard,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.mastercard,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.mastercard,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.mastercard,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.mastercard,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.mastercard,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.mastercard{background-image:url(../images/icons/credit-cards/mastercard.svg)}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.laser,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.laser,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.laser,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.laser,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.laser,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.laser,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.laser,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.laser,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.laser{background-image:url(../images/icons/credit-cards/laser.svg)}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.dinersclub,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.dinersclub,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.dinersclub,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.dinersclub,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.dinersclub,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.dinersclub,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.dinersclub,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.dinersclub,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.dinersclub{background-image:url(../images/icons/credit-cards/diners.svg)}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.maestro,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.maestro,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.maestro,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.maestro,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.maestro,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.maestro,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.maestro,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.maestro,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.maestro{background-image:url(../images/icons/credit-cards/maestro.svg)}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.jcb,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.jcb,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.jcb,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.jcb,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.jcb,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.jcb,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.jcb,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.jcb,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.jcb{background-image:url(../images/icons/credit-cards/jcb.svg)}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.amex,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.amex,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.amex,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.amex,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.amex,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.amex,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.amex,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.amex,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.amex{background-image:url(../images/icons/credit-cards/amex.svg)}#add_payment_method #payment div.payment_box .wc-credit-card-form-card-cvc.discover,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-expiry.discover,#add_payment_method #payment div.payment_box .wc-credit-card-form-card-number.discover,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-cvc.discover,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-expiry.discover,.woocommerce-cart #payment div.payment_box .wc-credit-card-form-card-number.discover,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-cvc.discover,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-expiry.discover,.woocommerce-checkout #payment div.payment_box .wc-credit-card-form-card-number.discover{background-image:url(../images/icons/credit-cards/discover.svg)}#add_payment_method #payment div.payment_box span.help,.woocommerce-cart #payment div.payment_box span.help,.woocommerce-checkout #payment div.payment_box span.help{font-size:.857em;color:#777;font-weight:400}#add_payment_method #payment div.payment_box .form-row,.woocommerce-cart #payment div.payment_box .form-row,.woocommerce-checkout #payment div.payment_box .form-row{margin:0 0 1em}#add_payment_method #payment div.payment_box p:last-child,.woocommerce-cart #payment div.payment_box p:last-child,.woocommerce-checkout #payment div.payment_box p:last-child{margin-bottom:0}#add_payment_method #payment div.payment_box:before,.woocommerce-cart #payment div.payment_box:before,.woocommerce-checkout #payment div.payment_box:before{content:"";display:block;border:1em solid #dfdcde;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-.75em;left:0;margin:-1em 0 0 2em}#add_payment_method #payment .payment_method_paypal .about_paypal,.woocommerce-cart #payment .payment_method_paypal .about_paypal,.woocommerce-checkout #payment .payment_method_paypal .about_paypal{float:right;line-height:52px;font-size:.83em}#add_payment_method #payment .payment_method_paypal img,.woocommerce-cart #payment .payment_method_paypal img,.woocommerce-checkout #payment .payment_method_paypal img{max-height:52px;vertical-align:middle}.woocommerce-password-strength{text-align:center;font-weight:600;padding:3px .5em;font-size:1em}.woocommerce-password-strength.strong{background-color:#c1e1b9;border-color:#83c373}.woocommerce-password-strength.short{background-color:#f1adad;border-color:#e35b5b}.woocommerce-password-strength.bad{background-color:#fbc5a9;border-color:#f78b53}.woocommerce-password-strength.good{background-color:#ffe399;border-color:#ffc733}.woocommerce-password-hint{margin:.5em 0 0;display:block}.product.has-default-attributes.has-children>.images{opacity:0}#content.twentyeleven .woocommerce-pagination a{font-size:1em;line-height:1}.single-product .twentythirteen #reply-title,.single-product .twentythirteen #respond #commentform,.single-product .twentythirteen .entry-summary{padding:0}.twentythirteen .woocommerce-breadcrumb{padding-top:40px}.twentyfourteen ul.products li.product{margin-top:0!important}body:not(.search-results) .twentysixteen .entry-summary{color:inherit;font-size:inherit;line-height:inherit}.twentysixteen .price ins{background:inherit;color:inherit} \ No newline at end of file diff --git a/assets/css/woocommerce.scss b/assets/css/woocommerce.scss index bc243d367c0..296f391165b 100644 --- a/assets/css/woocommerce.scss +++ b/assets/css/woocommerce.scss @@ -1140,6 +1140,10 @@ p.demo_store { .buttons { @include clearfix(); + a { + margin-right: 5px; + margin-bottom: 5px; + } } } diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 51e288a3b0a..eb00bfeaa02 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -606,7 +606,7 @@ if ( ! function_exists( 'woocommerce_product_archive_description' ) ) { if ( is_search() ) { return; } - + if ( is_post_type_archive( 'product' ) && 0 === absint( get_query_var( 'paged' ) ) ) { $shop_page = get_post( wc_get_page_id( 'shop' ) ); if ( $shop_page ) { @@ -1364,7 +1364,29 @@ if ( ! function_exists( 'woocommerce_button_proceed_to_checkout' ) ) { } } +if ( ! function_exists( 'woocommerce_widget_shopping_cart_button_view_cart' ) ) { + /** + * Output the proceed to checkout button. + * + * @subpackage Cart + */ + function woocommerce_widget_shopping_cart_button_view_cart() { + echo '' . __( 'View Cart', 'woocommerce' ) . ''; + } +} + +if ( ! function_exists( 'woocommerce_widget_shopping_cart_proceed_to_checkout' ) ) { + + /** + * Output the proceed to checkout button. + * + * @subpackage Cart + */ + function woocommerce_widget_shopping_cart_proceed_to_checkout() { + echo '' . __( 'Checkout', 'woocommerce' ) . ''; + } +} /** Mini-Cart *************************************************************/ diff --git a/includes/wc-template-hooks.php b/includes/wc-template-hooks.php index 6795f98ddeb..275263824fb 100644 --- a/includes/wc-template-hooks.php +++ b/includes/wc-template-hooks.php @@ -204,6 +204,11 @@ add_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_coupon_for add_action( 'woocommerce_checkout_order_review', 'woocommerce_order_review', 10 ); add_action( 'woocommerce_checkout_order_review', 'woocommerce_checkout_payment', 20 ); +/** + * Cart widget + */ +add_action( 'woocommerce_widget_shopping_cart_buttons', 'woocommerce_widget_shopping_cart_button_view_cart', 10 ); +add_action( 'woocommerce_widget_shopping_cart_buttons', 'woocommerce_widget_shopping_cart_proceed_to_checkout', 20 ); /** * Cart. diff --git a/templates/cart/mini-cart.php b/templates/cart/mini-cart.php index c2dd4980feb..89728a0a772 100644 --- a/templates/cart/mini-cart.php +++ b/templates/cart/mini-cart.php @@ -31,7 +31,7 @@ if ( ! defined( 'ABSPATH' ) ) { cart->is_empty() ) : ?> - + cart->get_cart() as $cart_item_key => $cart_item ) { $_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key ); @@ -70,7 +70,7 @@ if ( ! defined( 'ABSPATH' ) ) { ?> - +
  • @@ -86,8 +86,7 @@ if ( ! defined( 'ABSPATH' ) ) {

    - - +

    From 9759d3826562039a9922e34b1d400116eb63dfcd Mon Sep 17 00:00:00 2001 From: Nicola Mustone Date: Fri, 29 Jul 2016 11:51:58 +0200 Subject: [PATCH 177/298] coding standards and escaping --- .../class-product-cat-dropdown-walker.php | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/includes/walkers/class-product-cat-dropdown-walker.php b/includes/walkers/class-product-cat-dropdown-walker.php index 9e88bf608c1..5ee5bd32450 100644 --- a/includes/walkers/class-product-cat-dropdown-walker.php +++ b/includes/walkers/class-product-cat-dropdown-walker.php @@ -47,26 +47,26 @@ class WC_Product_Cat_Dropdown_Walker extends Walker { */ public function start_el( &$output, $cat, $depth = 0, $args = array(), $current_object_id = 0 ) { - if ( ! empty( $args['hierarchical'] ) ) + if ( ! empty( $args['hierarchical'] ) ) { $pad = str_repeat(' ', $depth * 3); - else + } else { $pad = ''; + } $cat_name = apply_filters( 'list_product_cats', $cat->name, $cat ); + $value = isset( $args['value'] ) && $args['value'] == 'id' ? $cat->term_id : $cat->slug; + $output .= "\t\n"; } From 6591ff1866b40be8e00d16cb840db69c0a0ea7e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Mei=C3=9Felbach?= Date: Fri, 29 Jul 2016 16:31:16 +0200 Subject: [PATCH 178/298] Provide 2 hooks for adding fields to the attribute creation form --- includes/admin/class-wc-admin-attributes.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/admin/class-wc-admin-attributes.php b/includes/admin/class-wc-admin-attributes.php index 453de2c551b..4d31a89b3ea 100644 --- a/includes/admin/class-wc-admin-attributes.php +++ b/includes/admin/class-wc-admin-attributes.php @@ -440,6 +440,7 @@ class WC_Admin_Attributes {

    +
    @@ -488,7 +489,7 @@ class WC_Admin_Attributes {

    - +

    From 35c499aa8134630e122d22e18cc69069b68425cc Mon Sep 17 00:00:00 2001 From: Claudio Sanches Date: Fri, 29 Jul 2016 18:46:39 -0300 Subject: [PATCH 179/298] Fixed product archive on front #11500 --- includes/class-wc-query.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-query.php b/includes/class-wc-query.php index 54f98bb218b..17b0b60e9dd 100644 --- a/includes/class-wc-query.php +++ b/includes/class-wc-query.php @@ -275,7 +275,7 @@ class WC_Query { } // Special check for shops with the product archive on front - if ( $this->is_showing_page_on_front( $q ) && absint( $q->get( 'page_id' ) ) === wc_get_page_id( 'shop' ) ) { + if ( $q->is_page() && 'page' === get_option( 'show_on_front' ) && absint( $q->get( 'page_id' ) ) === wc_get_page_id( 'shop' ) ) { // This is a front-page shop $q->set( 'post_type', 'product' ); $q->set( 'page_id', '' ); From 68abee516e4656ec88339eba6032acbda9e48081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Mei=C3=9Felbach?= Date: Mon, 1 Aug 2016 09:04:11 +0200 Subject: [PATCH 180/298] Rename hooks as suggested --- includes/admin/class-wc-admin-attributes.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/admin/class-wc-admin-attributes.php b/includes/admin/class-wc-admin-attributes.php index 4d31a89b3ea..2f4581d1980 100644 --- a/includes/admin/class-wc-admin-attributes.php +++ b/includes/admin/class-wc-admin-attributes.php @@ -440,7 +440,7 @@ class WC_Admin_Attributes {

    - +
    @@ -489,7 +489,7 @@ class WC_Admin_Attributes {

    - +

    From 97b0161c4cecb5e15381f80a523c53220c7d0024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20Mei=C3=9Felbach?= Date: Mon, 1 Aug 2016 09:13:21 +0200 Subject: [PATCH 181/298] Add hooks to edit form --- includes/admin/class-wc-admin-attributes.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/includes/admin/class-wc-admin-attributes.php b/includes/admin/class-wc-admin-attributes.php index 2f4581d1980..18eee6e38e5 100644 --- a/includes/admin/class-wc-admin-attributes.php +++ b/includes/admin/class-wc-admin-attributes.php @@ -271,7 +271,8 @@ class WC_Admin_Attributes {
    - + + @@ -335,6 +336,7 @@ class WC_Admin_Attributes {

    +

    From 45d6b88ac60978ab8c6be3021e294f8af3ad09a7 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 10:27:15 +0100 Subject: [PATCH 182/298] woocommerce_after_/before prefixes --- includes/admin/class-wc-admin-attributes.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/includes/admin/class-wc-admin-attributes.php b/includes/admin/class-wc-admin-attributes.php index 18eee6e38e5..3f589efa9d5 100644 --- a/includes/admin/class-wc-admin-attributes.php +++ b/includes/admin/class-wc-admin-attributes.php @@ -271,8 +271,8 @@ class WC_Admin_Attributes { - - + + @@ -310,7 +310,6 @@ class WC_Admin_Attributes {

    - +

    @@ -376,7 +375,6 @@ class WC_Admin_Attributes { if ( $attribute_taxonomies = wc_get_attribute_taxonomies() ) : foreach ( $attribute_taxonomies as $tax ) : ?> - attribute_label ); ?> @@ -442,7 +440,8 @@ class WC_Admin_Attributes {

    - + +
    @@ -491,7 +490,9 @@ class WC_Admin_Attributes {

    - + + +

    From 423a18f5c122a4404051be2fb0b0f86d12845ab0 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 10:31:05 +0100 Subject: [PATCH 183/298] [2.6] When checking needs_shipping, ignore anything after : in the method ID Fixes #11552 --- includes/abstracts/abstract-wc-order.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/includes/abstracts/abstract-wc-order.php b/includes/abstracts/abstract-wc-order.php index 00c2abd5718..527e1b503c3 100644 --- a/includes/abstracts/abstract-wc-order.php +++ b/includes/abstracts/abstract-wc-order.php @@ -2741,11 +2741,14 @@ abstract class WC_Abstract_Order { return false; } - $hide = apply_filters( 'woocommerce_order_hide_shipping_address', array( 'local_pickup' ), $this ); + $hide = apply_filters( 'woocommerce_order_hide_shipping_address', array( 'local_pickup' ), $this ); $needs_address = false; foreach ( $this->get_shipping_methods() as $shipping_method ) { - if ( ! in_array( $shipping_method['method_id'], $hide ) ) { + // Remove any instance IDs after : + $shipping_method_id = current( explode( ':', $shipping_method['method_id'] ) ); + + if ( ! in_array( $shipping_method_id, $hide ) ) { $needs_address = true; break; } From bc65d87fce3f1005bfbbe4833edf1647015df428 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 11:41:52 +0100 Subject: [PATCH 184/298] [2.6] Fixes add to cart message for IDs and allows the message to be returned Fixes #11563 --- includes/wc-cart-functions.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/includes/wc-cart-functions.php b/includes/wc-cart-functions.php index 0a1279cb365..977f4f93c4a 100644 --- a/includes/wc-cart-functions.php +++ b/includes/wc-cart-functions.php @@ -85,13 +85,14 @@ function wc_get_raw_referer() { * @access public * @param int|array $products * @param bool $show_qty Should qty's be shown? Added in 2.6.0 + * @param bool $return Return message rather than add it. */ -function wc_add_to_cart_message( $products, $show_qty = false ) { +function wc_add_to_cart_message( $products, $show_qty = false, $return = false ) { $titles = array(); $count = 0; if ( ! is_array( $products ) ) { - $products = array( $products ); + $products = array( $products => 1 ); $show_qty = false; } @@ -115,7 +116,13 @@ function wc_add_to_cart_message( $products, $show_qty = false ) { $message = sprintf( '%s %s', esc_url( wc_get_page_permalink( 'cart' ) ), esc_html__( 'View Cart', 'woocommerce' ), esc_html( $added_text ) ); } - wc_add_notice( apply_filters( 'wc_add_to_cart_message', $message, $product_id ) ); + $message = apply_filters( 'wc_add_to_cart_message', $message, $product_id ); + + if ( $return ) { + return $message; + } else { + wc_add_notice( $message ); + } } /** From 1f664e7c5ec66c1cd96bbd57a61ac9cfdc510b7d Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 11:42:03 +0100 Subject: [PATCH 185/298] Check for class not version --- includes/class-wc-api.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 68d7fa42104..a6b63caff37 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -110,10 +110,8 @@ class WC_API extends WC_Legacy_API { * @since 2.6.0 */ private function rest_api_init() { - global $wp_version; - // REST API was included starting WordPress 4.4. - if ( version_compare( $wp_version, 4.4, '<' ) ) { + if ( ! class_exists( 'WP_REST_Server' ) ) { return; } From e735903c043467df404bd07b3cc641d66dba36cc Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 11:42:19 +0100 Subject: [PATCH 186/298] Unit tests for wc_add_to_cart_message For #11563 --- tests/unit-tests/cart/functions.php | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tests/unit-tests/cart/functions.php b/tests/unit-tests/cart/functions.php index 00960754fef..3cebc91116c 100644 --- a/tests/unit-tests/cart/functions.php +++ b/tests/unit-tests/cart/functions.php @@ -46,7 +46,7 @@ class WC_Tests_Cart_Functions extends WC_Unit_Test_Case { public function test_get_checkout_url_regular() { // Make sure pages exist WC_Install::create_pages(); - + // Get the original setting $o_setting = get_option( 'woocommerce_force_ssl_checkout' ); @@ -154,4 +154,29 @@ class WC_Tests_Cart_Functions extends WC_Unit_Test_Case { $this->assertEquals( apply_filters( 'woocommerce_get_cart_url', $cart_page_url ? $cart_page_url : '' ), wc_get_cart_url() ); } + + /** + * Test wc_add_to_cart_message + */ + public function test_wc_add_to_cart_message() { + $product = WC_Helper_Product::create_simple_product(); + + $message = wc_add_to_cart_message( array( $product->id => 1 ), false, true ); + $this->assertEquals( 'View Cart “Dummy Product” has been added to your cart.', $message ); + + $message = wc_add_to_cart_message( array( $product->id => 3 ), false, true ); + $this->assertEquals( 'View Cart “Dummy Product” has been added to your cart.', $message ); + + $message = wc_add_to_cart_message( array( $product->id => 1 ), true, true ); + $this->assertEquals( 'View Cart “Dummy Product” has been added to your cart.', $message ); + + $message = wc_add_to_cart_message( array( $product->id => 3 ), true, true ); + $this->assertEquals( 'View Cart 3 × “Dummy Product” have been added to your cart.', $message ); + + $message = wc_add_to_cart_message( $product->id, false, true ); + $this->assertEquals( 'View Cart “Dummy Product” has been added to your cart.', $message ); + + $message = wc_add_to_cart_message( $product->id, true, true ); + $this->assertEquals( 'View Cart “Dummy Product” has been added to your cart.', $message ); + } } From a5ed0e43fd9e12395d6992fbdc8e23157dab558c Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 11:51:27 +0100 Subject: [PATCH 187/298] Adjustments from feedback --- .../class-wc-gateway-paypal-api-handler.php | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php b/includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php index dc3edcc901a..384515097cf 100644 --- a/includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php +++ b/includes/gateways/paypal/includes/class-wc-gateway-paypal-api-handler.php @@ -19,7 +19,7 @@ class WC_Gateway_Paypal_API_Handler { /** @var string API Signature */ public static $api_signature; - /** @var string API Signature */ + /** @var bool Sandbox */ public static $sandbox = false; /** @@ -27,7 +27,6 @@ class WC_Gateway_Paypal_API_Handler { * See https://developer.paypal.com/docs/classic/api/merchant/DoCapture_API_Operation_NVP/. * @param WC_Order $order * @param float $amount - * @param string $reason * @return array */ public static function get_capture_request( $order, $amount = null ) { @@ -61,7 +60,7 @@ class WC_Gateway_Paypal_API_Handler { 'METHOD' => 'RefundTransaction', 'TRANSACTIONID' => $order->get_transaction_id(), 'NOTE' => html_entity_decode( wc_trim_string( $reason, 255 ), ENT_NOQUOTES, 'UTF-8' ), - 'REFUNDTYPE' => 'Full' + 'REFUNDTYPE' => 'Full', ); if ( ! is_null( $amount ) ) { $request['AMT'] = number_format( $amount, 2, '.', '' ); @@ -84,8 +83,8 @@ class WC_Gateway_Paypal_API_Handler { 'method' => 'POST', 'body' => self::get_capture_request( $order, $amount ), 'timeout' => 70, - 'user-agent' => 'WooCommerce', - 'httpversion' => '1.1' + 'user-agent' => 'WooCommerce/' . WC()->version, + 'httpversion' => '1.1', ) ); @@ -116,8 +115,8 @@ class WC_Gateway_Paypal_API_Handler { 'method' => 'POST', 'body' => self::get_refund_request( $order, $amount, $reason ), 'timeout' => 70, - 'user-agent' => 'WooCommerce', - 'httpversion' => '1.1' + 'user-agent' => 'WooCommerce/' . WC()->version, + 'httpversion' => '1.1', ) ); From bdd6f1baadf43970b7ef5efb32b5083f80517862 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 11:52:42 +0100 Subject: [PATCH 188/298] readme --- readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.txt b/readme.txt index 992ba0f52b2..8f837af4cad 100644 --- a/readme.txt +++ b/readme.txt @@ -163,6 +163,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc * Added Nigerian Provinces to i18n/state. * Improved handling of shop page rewrite rules to allow subpages. * Redirect to login after password reset. +* When using authorizations in PayPal standard, automatically capture funds when the order goes processing/completed. [See changelog for all versions](https://raw.githubusercontent.com/woothemes/woocommerce/master/CHANGELOG.txt). From a2c7f2bf8361c96e842181e49a485dc48c573e8a Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 11:55:45 +0100 Subject: [PATCH 189/298] feedback --- includes/wc-template-functions.php | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 7094c7abd95..d285e6aa553 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -339,11 +339,12 @@ function wc_product_post_class( $classes, $class = '', $post_id = '' ) { /** * Outputs hidden form inputs for each query string variable. - * @param array $values name value pairs - * @param array $exclude keys to exclude * @since 2.7.0 + * @param array $values Name value pairs. + * @param array $exclude Keys to exclude. + * @param string $current_key Current key we are outputting. */ -function wc_query_string_form_fields( $values = null, $exclude = array(), $currentkey = '' ) { +function wc_query_string_form_fields( $values = null, $exclude = array(), $current_key = '' ) { if ( is_null( $values ) ) { $values = $_GET; } @@ -351,8 +352,8 @@ function wc_query_string_form_fields( $values = null, $exclude = array(), $curre if ( in_array( $key, $exclude ) ) { continue; } - if ( $currentkey ) { - $key = $currentkey . '[' . $key . ']'; + if ( $current_key ) { + $key = $current_key . '[' . $key . ']'; } if ( is_array( $value ) ) { wc_query_string_form_fields( $value, $exclude, $key ); From 806f70416d3660451412275c7f55d82582cc4aec Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 12:02:49 +0100 Subject: [PATCH 190/298] Don't run IPN code if processing or completed. Closes #11566 --- .../paypal/includes/class-wc-gateway-paypal-ipn-handler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php b/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php index 202a931519f..39eab1f89c0 100644 --- a/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php +++ b/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php @@ -172,7 +172,7 @@ class WC_Gateway_Paypal_IPN_Handler extends WC_Gateway_Paypal_Response { * @param array $posted */ protected function payment_status_completed( $order, $posted ) { - if ( $order->has_status( 'completed' ) ) { + if ( $order->has_status( array( 'processing', 'completed' ) ) ) { WC_Gateway_Paypal::log( 'Aborting, Order #' . $order->id . ' is already complete.' ); exit; } From 582133cb43f3b477bc3cc40d0a86bd28a42b64f0 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 12:05:34 +0100 Subject: [PATCH 191/298] [2.6] Spinners need more room on windows Closes #11565 --- assets/css/admin.css | 2 +- assets/css/admin.scss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/css/admin.css b/assets/css/admin.css index 973dea007aa..84dfe9d2d2b 100644 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -1 +1 @@ -@charset "UTF-8";.button.wc-reload:after,.woocommerce-help-tip:after{speak:none;text-transform:none;-webkit-font-smoothing:antialiased}@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg)}}@-moz-keyframes spin{100%{-moz-transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}.select2-container{margin:0;position:relative;display:block!important;zoom:1;vertical-align:middle}.select2-container,.select2-drop,.select2-search,.select2-search input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{display:block;padding:0 0 0 8px;overflow:hidden;position:relative;border:1px solid #ccc;white-space:nowrap;color:#444;text-decoration:none;border-radius:3px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;font-weight:400}html[dir=rtl] .select2-container .select2-choice{padding:0 8px 0 0}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#ccc;border-radius:0 0 4px 4px}.select2-container.select2-allowclear .select2-choice .select2-chosen{margin-right:42px}.select2-container .select2-choice>.select2-chosen{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:none;width:auto}html[dir=rtl] .select2-container .select2-choice>.select2-chosen{margin-left:26px;margin-right:0}.select2-container .select2-choice abbr{display:none;width:12px;height:12px;position:absolute;right:24px;top:5px;font-size:1px;text-decoration:none;border:0;background:url(../images/select2.png) right top no-repeat;cursor:pointer;outline:0}.select2-container.select2-allowclear .select2-choice abbr{display:inline-block}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop-mask{border:0;margin:0;padding:0;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:9998;background-color:#fff;filter:alpha(opacity=0)}.select2-drop{width:100%;margin-top:-1px;position:absolute;top:100%;background:#fff;color:#000;border:1px solid #ccc;border-top:0;border-radius:0 0 3px 3px}.select2-drop.select2-drop-above{margin-top:1px;border-top:1px solid #ccc;border-bottom:0;border-radius:3px 3px 0 0}.select2-drop-active{border:1px solid #666;border-top:none}.select2-drop.select2-drop-above.select2-drop-active{border-top:1px solid #666}.select2-drop-auto-width{border-top:1px solid #ccc;width:auto}.select2-drop-auto-width .select2-search{padding-top:4px}.select2-container .select2-choice .select2-arrow{display:inline-block;width:18px;height:100%;position:absolute;right:0;top:0;border-radius:0 3px 3px 0;background-clip:padding-box}html[dir=rtl] .select2-container .select2-choice .select2-arrow{left:0;right:auto;border-radius:3px 0 0 3px}.select2-container .select2-choice .select2-arrow b{display:block;width:100%;height:100%;position:relative}.select2-container .select2-choice .select2-arrow b:after{position:absolute;display:block;content:"";top:50%;left:50%;border:4px solid transparent;border-top-color:#666;margin-left:-7px;margin-top:-2px}.select2-search{display:inline-block;width:100%;margin:0;padding-left:4px;padding-right:4px;position:relative;z-index:10000;white-space:nowrap;padding-bottom:4px}.select2-search input{width:100%;height:auto!important;padding:4px 20px 4px 5px!important;margin:0;outline:0;font-family:sans-serif;font-size:1em;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none;background:url(../images/select2.png) 100% -22px no-repeat #fff}html[dir=rtl] .select2-search input{padding:4px 5px 4px 20px;background:url(../images/select2.png) -37px -22px no-repeat #fff}.select2-drop.select2-drop-above .select2-search input{margin-top:4px}.select2-search input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff}.select2-container-active .select2-choice,.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-dropdown-open .select2-choice{border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-dropdown-open .select2-choice .select2-arrow b:after{border-top-color:transparent;border-bottom-color:#666;margin-top:-6px}.select2-dropdown-open.select2-drop-above .select2-choice,.select2-dropdown-open.select2-drop-above .select2-choices{border:1px solid #666;border-top-color:transparent}.select2-dropdown-open .select2-choice .select2-arrow{background:0 0;border-left:none;filter:none}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow{border-right:none}.select2-dropdown-open .select2-choice .select2-arrow b{background-position:-18px 1px}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow b{background-position:-16px 1px}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.select2-results{max-height:200px;padding:4px;margin:0;position:relative;overflow-x:hidden;overflow-y:auto;-webkit-tap-highlight-color:transparent;background:#fafafa}html[dir=rtl] .select2-results{padding:0 4px 0 0;margin:4px 0 4px 4px}.select2-results ul.select2-result-sub{margin:0;padding-left:0}.select2-results li{list-style:none;display:list-item;background-image:none;margin:3px 0}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:700}.select2-results .select2-result-label{padding:5px 7px;margin:0;cursor:pointer;min-height:1em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select2-results-dept-1 .select2-result-label{padding-left:20px}.select2-results-dept-2 .select2-result-label{padding-left:40px}.select2-results-dept-3 .select2-result-label{padding-left:60px}.select2-results-dept-4 .select2-result-label{padding-left:80px}.select2-results-dept-5 .select2-result-label{padding-left:100px}.select2-results-dept-6 .select2-result-label{padding-left:110px}.select2-results-dept-7 .select2-result-label{padding-left:120px}.select2-results .select2-highlighted{background:#f1f1f1;color:#000;border-radius:3px}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:0 0}.select2-results .select2-highlighted ul{background:#fff;color:#000}.select2-results .select2-ajax-error,.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item;padding-left:5px}.select2-results .select2-disabled.select2-highlighted{color:#666;background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-disabled{background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-selected{display:none}.select2-more-results.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #f4f4f4}.select2-results .select2-ajax-error{background:rgba(255,50,50,.2)}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice .select2-arrow{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container.select2-container-disabled .select2-choice abbr{display:none}.select2-container-multi .select2-choices{height:auto!important;height:1%;margin:0;padding:0 5px 0 0;position:relative;border:1px solid #ccc;cursor:text;overflow:hidden;background-color:#fff;min-height:26px}html[dir=rtl] .select2-container-multi .select2-choices{padding:0 0 0 5px}.select2-locked{padding:3px 5px!important}.select2-container-multi.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-container-multi .select2-choices li{float:left;list-style:none}html[dir=rtl] .select2-container-multi .select2-choices li{float:right}.select2-container-multi .select2-choices .select2-search-field{margin:0;padding:0;white-space:nowrap}.select2-container-multi .select2-choices .select2-search-field:first-child{width:100%}.select2-container-multi .select2-choices .select2-search-field input{margin:1px 0;outline:0;border:0;-webkit-box-shadow:none;box-shadow:none;background:0 0!important}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff!important}.select2-default{color:#999!important}.select2-container-multi .select2-choices .select2-search-choice{padding:5px 8px 5px 24px;margin:3px 0 3px 5px;position:relative;line-height:15px;color:#333;cursor:default;border-radius:2px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#e4e4e4}html[dir=rtl] .select2-container-multi .select2-choices .select2-search-choice{margin:3px 5px 3px 0;padding:5px 24px 5px 8px}.select2-container-multi .select2-choices .select2-search-choice .select2-chosen{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;width:12px;height:13px;position:absolute;right:7px;top:6px;font-size:1px;outline:0;background:url(../images/select2.png) right top no-repeat}html[dir=rtl] .select2-search-choice-close{right:auto;left:7px}.select2-container-multi .select2-search-choice-close{left:7px}html[dir=rtl] .select2-container-multi .select2-search-choice-close{left:auto;right:7px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover,.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{padding:3px 5px;border:1px solid #ddd;background-image:none;background-color:#f4f4f4}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none;background:0 0}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-match{text-decoration:underline}.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.select2-display-none{display:none}.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:2dppx){.select2-search input{background-image:url(../images/select2x2.png)!important;background-repeat:no-repeat!important;background-size:60px 40px!important;background-position:100% -21px!important}}@font-face{font-family:star;src:url(../fonts/star.eot);src:url(../fonts/star.eot?#iefix) format("embedded-opentype"),url(../fonts/star.woff) format("woff"),url(../fonts/star.ttf) format("truetype"),url(../fonts/star.svg#star) format("svg");font-weight:400;font-style:normal}@font-face{font-family:WooCommerce;src:url(../fonts/WooCommerce.eot);src:url(../fonts/WooCommerce.eot?#iefix) format("embedded-opentype"),url(../fonts/WooCommerce.woff) format("woff"),url(../fonts/WooCommerce.ttf) format("truetype"),url(../fonts/WooCommerce.svg#WooCommerce) format("svg");font-weight:400;font-style:normal}.blockUI.blockOverlay:before{height:1em;width:1em;position:absolute;top:50%;left:50%;margin-left:-.5em;margin-top:-.5em;display:block;content:"";-webkit-animation:spin 1s ease-in-out infinite;-moz-animation:spin 1s ease-in-out infinite;animation:spin 1s ease-in-out infinite;background:url(../images/icons/loader.svg) center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75)}.wc_addons_wrap .products{overflow:hidden}.wc_addons_wrap .products li{float:left;margin:0 1em 1em 0!important;padding:0;vertical-align:top;width:300px}.wc_addons_wrap .products li a{text-decoration:none;color:inherit;border:1px solid #ddd;display:block;min-height:220px;overflow:hidden;background:#f5f5f5;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1)}.wc_addons_wrap .products li a img{max-width:258px;max-height:24px;padding:17px 20px;display:block;margin:0;background:#fff;border-right:260px solid #fff}.wc_addons_wrap .products li a .price,.wc_addons_wrap .products li a img.extension-thumb+h3{display:none}.wc_addons_wrap .products li a h2,.wc_addons_wrap .products li a h3{margin:0!important;padding:20px!important;background:#fff}.wc_addons_wrap .products li a p{padding:20px!important;margin:0!important;border-top:1px solid #f1f1f1}.wc_addons_wrap .products li a:focus,.wc_addons_wrap .products li a:hover{background-color:#fff}.wc_addons_wrap .storefront{background:url(../images/storefront-bg.jpg) bottom right #f6f6f6;border:1px solid #ddd;padding:20px;overflow:hidden;zoom:1}.wc_addons_wrap .storefront img{width:278px;height:auto;float:left;margin:0 20px 0 0;box-shadow:0 1px 6px rgba(0,0,0,.1)}.wc_addons_wrap .storefront p{max-width:750px}.woocommerce-BlankState a.button-primary,.woocommerce-BlankState button.button-primary,.woocommerce-message a.button-primary,.woocommerce-message button.button-primary{background:#bb77ae;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;color:#fff;text-shadow:0 -1px 1px #A36597,1px 0 1px #A36597,0 1px 1px #A36597,-1px 0 1px #A36597}.woocommerce-BlankState a.button-primary:active,.woocommerce-BlankState a.button-primary:focus,.woocommerce-BlankState a.button-primary:hover,.woocommerce-BlankState button.button-primary:active,.woocommerce-BlankState button.button-primary:focus,.woocommerce-BlankState button.button-primary:hover,.woocommerce-message a.button-primary:active,.woocommerce-message a.button-primary:focus,.woocommerce-message a.button-primary:hover,.woocommerce-message button.button-primary:active,.woocommerce-message button.button-primary:focus,.woocommerce-message button.button-primary:hover{background:#A36597;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597}.woocommerce-message{position:relative;border-left-color:#cc99c2!important;overflow:hidden}.woocommerce-message a.docs,.woocommerce-message a.skip{text-decoration:none!important}.woocommerce-message a.woocommerce-message-close{position:absolute;top:10px;right:10px;padding:10px 15px 10px 21px;font-size:13px;line-height:1.23076923;text-decoration:none}.woocommerce-message a.woocommerce-message-close:before{position:absolute;top:8px;left:0;-webkit-transition:all .1s ease-in-out;transition:all .1s ease-in-out}.woocommerce-message .twitter-share-button{margin-top:-3px;margin-left:3px;vertical-align:middle}#variable_product_options #message,#variable_product_options .notice{margin:10px}.clear{clear:both}#woocommerce-fields-bulk.inline-edit-col label,#woocommerce-fields.inline-edit-col{clear:left}.wrap.woocommerce div.error,.wrap.woocommerce div.updated{margin-top:10px}mark.amount{background:0 0;color:inherit}.postbox,.woocommerce{input:invalid;input-border:1px solid #cc010b;input-background:#ffebe8}.simplify-commerce-banner{overflow:hidden}.simplify-commerce-banner img{float:right;padding:15px 0;margin-left:1em;width:200px}.woocommerce-help-tip{color:#666;display:inline-block;font-size:1.1em;font-style:normal;height:16px;line-height:16px;position:relative;vertical-align:middle;width:16px}.woocommerce-help-tip:after{font-family:Dashicons;font-weight:400;font-variant:normal;line-height:1;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";cursor:help}h2 .woocommerce-help-tip{margin-top:-5px;margin-left:.25em}table.wc_status_table{margin-bottom:1em}table.wc_status_table h2{font-size:14px;margin:0}table.wc_status_table tr:nth-child(2n) td,table.wc_status_table tr:nth-child(2n) th{background:#fcfcfc}table.wc_status_table th{font-weight:700;padding:9px}table.wc_status_table td:first-child{width:33%}table.wc_status_table td.help{width:1em}table.wc_status_table td{padding:9px;font-size:1.1em}table.wc_status_table td mark{background:0 0}table.wc_status_table td mark.yes{color:#7ad03a}table.wc_status_table td mark.no{color:#999}table.wc_status_table td mark.error{color:#a00}table.wc_status_table td ul{margin:0}table.wc_status_table .help_tip{cursor:help}#debug-report{display:none;margin:10px 0;padding:0;position:relative}#debug-report textarea{font-family:monospace;width:100%;margin:0;height:300px;padding:20px;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;resize:none;font-size:12px;line-height:20px;outline:0}#log-viewer-select{padding:10px 0 8px;line-height:180%}#log-viewer textarea{width:100%;resize:vertical}.inline-edit-product.quick-edit-row .inline-edit-col-center,.inline-edit-product.quick-edit-row .inline-edit-col-right{float:right!important}#woocommerce-fields.inline-edit-col label.featured,#woocommerce-fields.inline-edit-col label.manage_stock{margin-left:10px}#woocommerce-fields.inline-edit-col .dimensions div{display:block;margin:.2em 0}#woocommerce-fields.inline-edit-col .dimensions div span.title{display:block;float:left;width:5em}#woocommerce-fields.inline-edit-col .dimensions div span.input-text-wrap{display:block;margin-left:5em}#woocommerce-fields.inline-edit-col .text{box-sizing:border-box;width:99%;float:left;margin:1px 1% 1px 1px}#woocommerce-fields.inline-edit-col .height,#woocommerce-fields.inline-edit-col .length,#woocommerce-fields.inline-edit-col .width{width:32.33%}#woocommerce-fields.inline-edit-col .height{margin-right:0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group label{clear:none;width:49%;margin:.2em 0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group.dimensions label{width:75%;max-width:75%}#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .regular_price,#woocommerce-fields-bulk.inline-edit-col .sale_price,#woocommerce-fields-bulk.inline-edit-col .stock,#woocommerce-fields-bulk.inline-edit-col .weight{box-sizing:border-box;width:100%;margin-left:4.4em}#woocommerce-fields-bulk.inline-edit-col .height,#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .width{box-sizing:border-box;width:25%}.column-coupon_code{line-height:2.25em}.column-coupon_code,ul.wc_coupon_list{margin:0;overflow:hidden;zoom:1;clear:both}ul.wc_coupon_list li{margin:0}ul.wc_coupon_list li.code{display:inline-block}ul.wc_coupon_list li.code:after{content:", "}ul.wc_coupon_list li.code:last-of-type:after{display:none}ul.wc_coupon_list li.code .tips{cursor:pointer}ul.wc_coupon_list_block{margin:0;padding-bottom:2px}ul.wc_coupon_list_block li{border-top:1px solid #fff;border-bottom:1px solid #ccc;line-height:2.5em;margin:0;padding:.5em 0}ul.wc_coupon_list_block li:first-child{border-top:0;padding-top:0}ul.wc_coupon_list_block li:last-child{border-bottom:0;padding-bottom:0}.button.wc-reload{text-indent:-9999px;position:relative;padding:0;height:28px;width:28px!important;display:inline-block}.button.wc-reload:after{font-family:Dashicons;font-weight:400;font-variant:normal;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:28px}#order_data h2,#order_data p.order_number{font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif;font-weight:400}.tablenav .actions{overflow:visible}.tablenav .select2-container{float:left;max-width:200px;font-size:14px;vertical-align:middle;margin:1px 6px 1px 1px}#woocommerce-order-data .handlediv,#woocommerce-order-data .hndle{display:none}#woocommerce-order-data .inside{display:block!important}#order_data{padding:23px 24px 12px}#order_data h2{margin:0;font-size:21px;line-height:1.2;text-shadow:1px 1px 1px #fff;padding:0}#order_data h3{font-size:14px}#order_data h3,#order_data h4{color:#333;margin:1.33em 0 0}#order_data p{color:#777}#order_data p.order_number{margin:0;line-height:1.6em;font-size:16px}#order_data .order_data_column_container{clear:both}#order_data .order_data_column{width:32%;padding:0 2% 0 0;float:left}#order_data .order_data_column:last-child{padding-right:0}#order_data .order_data_column p{padding:0!important}#order_data .order_data_column .address strong{display:block}#order_data .order_data_column .form-field{float:left;width:48%;padding:0;margin:9px 0 0}#order_data .order_data_column .form-field label{display:block;padding:0 0 3px}#order_data .order_data_column .form-field input,#order_data .order_data_column .form-field select,#order_data .order_data_column .form-field textarea{width:100%}#order_data .order_data_column .form-field .select2-container{width:100%!important}#order_data .order_data_column .form-field .date-picker{width:50%}#order_data .order_data_column .form-field .hour,#order_data .order_data_column .form-field .minute{width:3em}#order_data .order_data_column .form-field small{display:block;margin:5px 0 0;color:#999}#order_data .order_data_column .form-field.last{float:right}#order_data .order_data_column .form-field-wide{width:100%;clear:both}#order_data .order_data_column .form-field-wide .wc-customer-search,#order_data .order_data_column .form-field-wide .wc-enhanced-select,#order_data .order_data_column .form-field-wide input,#order_data .order_data_column .form-field-wide select,#order_data .order_data_column .form-field-wide textarea{width:100%}#order_data .order_data_column p.none_set{color:#999}#order_data .order_data_column ._billing_address_1_field,#order_data .order_data_column ._billing_city_field,#order_data .order_data_column ._billing_country_field,#order_data .order_data_column ._billing_email_field,#order_data .order_data_column ._billing_first_name_field,#order_data .order_data_column ._shipping_address_1_field,#order_data .order_data_column ._shipping_city_field,#order_data .order_data_column ._shipping_country_field,#order_data .order_data_column ._shipping_first_name_field{float:left}#order_data .order_data_column ._billing_address_2_field,#order_data .order_data_column ._billing_last_name_field,#order_data .order_data_column ._billing_phone_field,#order_data .order_data_column ._billing_postcode_field,#order_data .order_data_column ._billing_state_field,#order_data .order_data_column ._shipping_address_2_field,#order_data .order_data_column ._shipping_last_name_field,#order_data .order_data_column ._shipping_postcode_field,#order_data .order_data_column ._shipping_state_field,#order_data .order_data_column .wc-customer-user label a,#order_data .order_data_column .wc-order-status label a{float:right}#order_data .order_data_column ._billing_company_field,#order_data .order_data_column ._shipping_company_field,#order_data .order_data_column ._transaction_id_field{clear:both;width:100%}#order_data .order_data_column ._billing_email_field{clear:left}#order_data .order_data_column div.edit_address{display:none;zoom:1;padding-right:1px}#order_data .order_data_column .billing-same-as-shipping,#order_data .order_data_column .load_customer_billing,#order_data .order_data_column .load_customer_shipping,#order_data .order_data_column a.edit_address{width:14px;height:0;padding:14px 0 0;margin:0 0 0 6px;overflow:hidden;position:relative;color:#999;border:0;float:right}#order_data .order_data_column .billing-same-as-shipping:focus,#order_data .order_data_column .billing-same-as-shipping:hover,#order_data .order_data_column .load_customer_billing:focus,#order_data .order_data_column .load_customer_billing:hover,#order_data .order_data_column .load_customer_shipping:focus,#order_data .order_data_column .load_customer_shipping:hover,#order_data .order_data_column a.edit_address:focus,#order_data .order_data_column a.edit_address:hover{color:#000}#order_data .order_data_column .billing-same-as-shipping:after,#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after,#order_data .order_data_column a.edit_address: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}#order_data .order_data_column .billing-same-as-shipping:after{content:"\e008"}#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after{content:"\e03a"}#order_data .order_data_column a.edit_address:after{font-family:Dashicons;content:"\f464"}.order_actions{margin:0;overflow:hidden;zoom:1}.order_actions li{border-top:1px solid #fff;border-bottom:1px solid #ddd;padding:6px 0;margin:0;line-height:1.6em;float:left;width:50%;text-align:center}.order_actions li a{float:none;text-align:center;text-decoration:underline}.order_actions li.wide{width:auto;float:none;clear:both;padding:6px;text-align:left;overflow:hidden}.order_actions li #delete-action{line-height:25px;vertical-align:middle;text-align:left;float:left}.order_actions li .save_order{float:right}.order_actions li#actions{overflow:hidden}.order_actions li#actions .button{width:24px;box-sizing:border-box;float:right}.order_actions li#actions select{width:225px;box-sizing:border-box;float:left}#woocommerce-order-items .inside{margin:0;padding:0;background:#fefefe}#woocommerce-order-items .wc-order-data-row{border-bottom:1px solid #DFDFDF;padding:1.5em 2em;background:#f8f8f8;line-height:2em;text-align:right}#woocommerce-order-items .wc-order-data-row:after,#woocommerce-order-items .wc-order-data-row:before{content:" ";display:table}#woocommerce-order-items .wc-order-data-row:after{clear:both}#woocommerce-order-items .wc-order-data-row p{margin:0;line-height:2em}#woocommerce-order-items .wc-order-data-row .wc-used-coupons{text-align:left}#woocommerce-order-items .wc-order-data-row .wc-used-coupons .tips{display:inline-block}#woocommerce-order-items .wc-order-add-item{background:#fff;vertical-align:top;border-top:none}#woocommerce-order-items .wc-order-add-item .add_item_id,#woocommerce-order-items .wc-order-add-item .select2-container{vertical-align:top}#woocommerce-order-items .wc-order-add-item .add_item_id .search-field input,#woocommerce-order-items .wc-order-add-item .select2-container .search-field input{min-width:100px}#woocommerce-order-items .wc-order-add-item .select2-container{width:400px!important;text-align:left}#woocommerce-order-items .wc-order-add-item .calculate-action,#woocommerce-order-items .wc-order-add-item .cancel-action,#woocommerce-order-items .wc-order-add-item .save-action{float:left;margin-right:2px}#woocommerce-order-items .wc-used-coupons{float:left;width:50%}#woocommerce-order-items .wc-order-totals{float:right;width:50%;margin:0;padding:0;text-align:right}#woocommerce-order-items .wc-order-totals .amount{font-weight:700}#woocommerce-order-items .wc-order-totals .label{vertical-align:top}#woocommerce-order-items .wc-order-totals .total{font-size:1em!important;width:10em;margin:0 0 0 .5em;box-sizing:border-box}#woocommerce-order-items .wc-order-totals .total input[type=text]{width:96%;float:right}#woocommerce-order-items .wc-order-totals .refunded-total{color:#a00}#woocommerce-order-items .refund-actions{margin-top:5px;padding-top:12px;border-top:1px solid #DFDFDF}#woocommerce-order-items .refund-actions .button{float:right;margin-left:4px}#woocommerce-order-items .refund-actions .cancel-action,#woocommerce-order-items .wc-order-item-bulk-edit .cancel-action{float:left;margin-left:0}#woocommerce-order-items .add_meta{margin-left:0!important}#woocommerce-order-items h3 small{color:#999}#woocommerce-order-items .amount{white-space:nowrap}#woocommerce-order-items .add-items .description{margin-right:10px}#woocommerce-order-items .add-items .button{float:left;margin-right:.25em}#woocommerce-order-items .add-items .button-primary{float:none;margin-right:0}#woocommerce-order-items .inside{display:block!important}#woocommerce-order-items .handlediv,#woocommerce-order-items .hndle{display:none}#woocommerce-order-items .woocommerce_order_items_wrapper{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items{width:100%;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th{text-align:left;padding:1em;font-weight:400;color:#999;background:#f8f8f8;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th.sortable{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th .wc-arrow{float:right;position:relative;margin-right:-1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td{padding:1.5em 1em 1em;text-align:left;line-height:1.5em;vertical-align:top;border-bottom:1px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td select{width:50%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{font-size:14px;padding:4px;color:#555}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr td{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected{background:#F5EBF3}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected td{border-color:#E6CCE1;opacity:.8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:last-child td{border-bottom:1px solid #dfdfdf}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:first-child td{border-top:8px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody#order_line_items tr:first-child td{border-top:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb{text-align:left;width:38px;padding-bottom:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail{width:38px;height:38px;border:2px solid #e8e8e8;background:#f8f8f8;color:#ccc;position:relative;font-size:21px;display:block;text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;height:100%;text-align:center;content:"";width:38px;line-height:38px;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail img{width:100%;height:100%;margin:0;padding:0;position:relative}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-sku,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-variation{display:block;margin-top:.5em;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item{min-width:200px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .center,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .variation-id{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class{text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label{white-space:nowrap;color:#999;font-size:.833em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label input{display:inline}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class input{width:70px;vertical-align:middle;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class select{width:85px;height:26px;vertical-align:middle;font-size:1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input{display:inline-block;background:#fff;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);margin:1px 0;min-width:80px;overflow:hidden;line-height:1em;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input{width:100%;box-sizing:border-box}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input label{font-size:.75em;padding:4px 6px 0;color:#555;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input{width:100%;box-sizing:border-box;border:0;box-shadow:none;margin:0;padding:0 6px 4px;color:#555;background:0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input::-webkit-input-placeholder{color:#ddd}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child{border-bottom:1px dashed #ddd;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child label{color:#ccc}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .view{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .edit{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes label{display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount{display:block;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{margin-right:.25em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input{text-align:center;width:50px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items span.subtotal{opacity:.5}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.tax_class,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.tax_class{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .calculated{border-color:#ae8ca2;border-style:dotted}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{margin:.5em 0 0;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{color:#ccc;top:0;left:0;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-align:center;font-family:WooCommerce}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr th{border:0;padding:0 4px .5em 0;line-height:1.5em;width:20%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td{padding:0 4px .5em 0;border:0;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input{width:100%;margin:0;position:relative;border-bottom:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .refund_by,ul.order_notes li p.meta .exact-date{border-bottom:1px dotted #999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td textarea{width:100%;height:4em;margin:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input:focus+textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input:focus+textarea{border-top-color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p{margin:0 0 .5em;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p:last-child{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method_name{width:100%;margin:0 0 .5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;float:right;font-size:14px;visibility:hidden;margin:3px -18px 0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:hover:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:hover:before{color:#a00}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax:hover .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax:hover .delete-order-tax{visibility:visible}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded{display:block;color:#a00;white-space:nowrap;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;width:100%;height:100%;text-align:center;content:"";position:relative;top:auto;left:auto;margin:-1px 4px 0 0;vertical-align:middle;line-height:1em}#woocommerce-order-items .wc-order-edit-line-item{padding-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions{width:44px;text-align:right;padding-left:0;vertical-align:middle}#woocommerce-order-items .wc-order-edit-line-item-actions a{color:#ccc;display:inline-block;cursor:pointer;padding:0 0 .5em;margin:0 0 0 12px;vertical-align:middle;text-decoration:none;line-height:16px;width:16px;overflow:hidden}#woocommerce-order-items .wc-order-edit-line-item-actions a:before{margin:0;padding:0;font-size:16px;width:16px;height:16px}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before,#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{font-family:Dashicons;-webkit-font-smoothing:antialiased;text-indent:0;top:0;left:0;width:100%;height:100%;margin:0;text-align:center;position:relative;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1}#woocommerce-order-items .wc-order-edit-line-item-actions a:hover:before{color:#999}#woocommerce-order-items .wc-order-edit-line-item-actions a:first-child{margin-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:hover:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:hover:before{color:#a00}#woocommerce-order-items tbody tr .wc-order-edit-line-item-actions{visibility:hidden}#woocommerce-order-items tbody tr:hover .wc-order-edit-line-item-actions{visibility:visible}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions{width:1.5em;visibility:visible!important}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions a{padding:0}#woocommerce-order-downloads .buttons{float:left;padding:0;margin:0;vertical-align:top}#woocommerce-order-downloads .buttons .add_item_id,#woocommerce-order-downloads .buttons .select2-container{width:400px!important;margin-right:9px;vertical-align:top;float:left}#woocommerce-order-downloads .buttons button{margin:2px 0 0}#woocommerce-order-downloads h3 small{color:#999}#poststuff #woocommerce-order-actions .inside{margin:0;padding:0}#poststuff #woocommerce-order-actions .inside ul.order_actions li{padding:6px 10px;box-sizing:border-box}#poststuff #woocommerce-order-actions .inside ul.order_actions li:last-child{border-bottom:0}#poststuff #woocommerce-order-notes .inside{margin:0;padding:0}#poststuff #woocommerce-order-notes .inside ul.order_notes li{padding:0 10px}#woocommerce_customers p.search-box{margin:6px 0 4px;float:left}#woocommerce_customers .tablenav{float:right;clear:none}.widefat.customers td{vertical-align:middle;padding:4px 7px}.widefat .column-order_title{width:15%}.widefat .column-order_title time{display:block;color:#999;margin:3px 0}.widefat .column-orders,.widefat .column-paying,.widefat .column-spent{text-align:center;width:8%}.widefat .column-last_order{width:11%}.widefat .column-order_actions,.widefat .column-user_actions,.widefat .column-wc_actions{width:110px}.widefat .column-order_actions a.button,.widefat .column-user_actions a.button,.widefat .column-wc_actions a.button{float:left;margin:0 4px 2px 0;cursor:pointer;padding:3px 4px;height:auto}.widefat .column-order_actions a.button img,.widefat .column-user_actions a.button img,.widefat .column-wc_actions a.button img{display:block;width:12px;height:auto}.widefat small.meta{display:block;color:#999;font-size:inherit;margin:3px 0}.widefat .column-order_date,.widefat .column-order_total{width:9%}.widefat .column-order_status{width:45px;text-align:center}.widefat .column-order_status mark{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;background:0 0;font-size:1.4em;margin:0 auto}.widefat .column-order_status mark.cancelled:after,.widefat .column-order_status mark.completed:after,.widefat .column-order_status mark.failed:after,.widefat .column-order_status mark.on-hold:after,.widefat .column-order_status mark.pending:after,.widefat .column-order_status mark.processing:after,.widefat .column-order_status mark.refunded:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.column-customer_message .note-on:after,.column-order_notes .note-on:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;left:0;text-align:center;line-height:16px;font-family:WooCommerce}.widefat .column-order_status mark.pending:after{content:"\e012";color:#ffba00}.widefat .column-order_status mark.completed:after{content:"\e015";color:#2ea2cc}.widefat .column-order_status mark.on-hold:after{content:"\e033";color:#999}.widefat .column-order_status mark.failed:after{content:"\e016";color:#d0c21f}.widefat .column-order_status mark.cancelled:after{content:"\e013";color:#a00}.widefat .column-order_status mark.processing:after{content:"\e011";color:#73a724}.widefat .column-order_status mark.refunded:after{content:"\e014";color:#999}.widefat td.column-order_status{padding-top:9px}.column-customer_message .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-customer_message .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.column-order_notes .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-order_notes .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.order_actions .complete,.order_actions .processing,.order_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.order_actions .processing:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.order_actions .complete:after,.order_actions .view:after{font-family:Dashicons;text-indent:0;position:absolute;width:100%;height:100%;left:0;line-height:1.85;margin:0;text-align:center;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;font-weight:400}.order_actions .complete:after{content:""}.order_actions .view:after{content:""}.user_actions .edit,.user_actions .link,.user_actions .refresh,.user_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.user_actions .edit:after,.user_actions .link:after,.user_actions .refresh:after,.user_actions .view:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.user_actions .edit:after{font-family:Dashicons;content:"\f464"}.user_actions .link:after{content:"\e00d"}.user_actions .view:after{content:"\e010"}.user_actions .refresh:after{content:"\e031"}.attributes-table td,.attributes-table th{width:15%;vertical-align:top}.attributes-table .attribute-terms{width:32%}.attributes-table .attribute-actions{width:2em}.attributes-table .attribute-actions .configure-terms{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.attributes-table .attribute-actions .configure-terms:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}ul.order_notes{padding:2px 0 0}ul.order_notes li .note_content{padding:10px;background:#efefef;position:relative}ul.order_notes li .note_content p{margin:0;padding:0;word-wrap:break-word}ul.order_notes li p.meta{padding:10px;color:#999;margin:0;font-size:11px}ul.order_notes li a.delete_note{color:#a00}table.wp-list-table .row-actions,table.wp-list-table span.na{color:#999}ul.order_notes li .note_content:after{content:"";display:block;position:absolute;bottom:-10px;left:20px;width:0;height:0;border-width:10px 10px 0 0;border-style:solid;border-color:#efefef transparent}ul.order_notes li.customer-note .note_content{background:#A7CEDC}ul.order_notes li.customer-note .note_content:after{border-color:#A7CEDC transparent}ul.order_notes li.system-note .note_content{background:#d7cad2}ul.order_notes li.system-note .note_content:after{border-color:#d7cad2 transparent}.add_note{border-top:1px solid #ddd;padding:10px 10px 0}.add_note h4{margin-top:5px!important}.add_note #add_order_note{width:100%;height:50px}table.wp-list-table .column-thumb{width:52px;text-align:center;white-space:nowrap}table.wp-list-table .column-name{width:22%}table.wp-list-table .column-product_cat,table.wp-list-table .column-product_tag{width:11%!important}table.wp-list-table .column-featured,table.wp-list-table .column-product_type{width:48px;text-align:left!important}table.wp-list-table .column-customer_message,table.wp-list-table .column-order_notes{width:48px;text-align:center}table.wp-list-table .column-customer_message img,table.wp-list-table .column-order_notes img{margin:0 auto;padding-top:0!important}table.wp-list-table .manage-column.column-featured img,table.wp-list-table .manage-column.column-product_type img{padding-left:2px}table.wp-list-table .column-price .woocommerce-price-suffix{display:none}table.wp-list-table img{margin:1px 2px}table.wp-list-table td.column-thumb img{margin:0;width:auto;height:auto;max-width:40px;max-height:40px;vertical-align:middle}table.wp-list-table .column-is_in_stock{text-align:left!important}table.wp-list-table span.wc-featured,table.wp-list-table span.wc-image,table.wp-list-table span.wc-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table span.wc-featured:before,table.wp-list-table span.wc-image:before,table.wp-list-table span.wc-type:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:""}table.wp-list-table span.wc-featured{margin:0;cursor:pointer}table.wp-list-table span.wc-featured:before{content:"\f155"}table.wp-list-table span.wc-featured.not-featured:before{content:"\f154"}table.wp-list-table td.column-featured span.wc-featured{font-size:1.6em}table.wp-list-table span.wc-type{margin:0}table.wp-list-table span.wc-type:before{font-family:WooCommerce;content:"\e006"}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after,table.wp-list-table span.product-type:before{font-family:WooCommerce;text-align:center;line-height:1;top:0;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;left:0}table.wp-list-table span.product-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.6em}table.wp-list-table span.product-type:before{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}table.wp-list-table span.product-type.grouped:before{content:"\e002"}table.wp-list-table span.product-type.external:before{content:"\e034"}table.wp-list-table span.product-type.variable:before{content:"\e003"}table.wp-list-table span.product-type.downloadable:before{content:"\e001"}table.wp-list-table span.product-type.virtual:before{content:"\e000"}table.wp-list-table mark.instock{font-weight:700;color:#7ad03a;background:0 0;line-height:1}table.wp-list-table mark.outofstock{font-weight:700;color:#a44;background:0 0;line-height:1}table.wp-list-table .notes_head,table.wp-list-table .order-notes_head,table.wp-list-table .status_head{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%}table.wc_emails .wc-email-settings-table-name,table.wc_emails td.name,table.wc_gateways .wc-email-settings-table-name,table.wc_gateways td.name,table.wc_shipping .wc-email-settings-table-name,table.wc_shipping td.name{font-weight:700}table.wp-list-table .order-notes_head:after{content:"\e028"}table.wp-list-table .notes_head:after{content:"\e026"}table.wp-list-table .status_head:after{content:"\e011"}table.wp-list-table .column-order_items{width:12%}table.wp-list-table .column-order_items table.order_items{width:100%;margin:3px 0 0;padding:0;display:none}table.wp-list-table .column-order_items table.order_items td{border:0;margin:0;padding:0 0 3px}table.wp-list-table .column-order_items table.order_items td.qty{color:#999;padding-right:6px;text-align:left}mark.notice{background:#fff;color:#a00;margin:0 0 0 10px}a.export_rates,a.import_rates{float:right;margin-left:9px;margin-top:-2px;margin-bottom:0}#rates-search{float:right}#rates-search input.wc-tax-rates-search-field{padding:4px 8px;font-size:1.2em}#rates-pagination{float:right;margin-right:.5em}#rates-pagination .tablenav{margin:0}table.wc_input_table,table.wc_tax_rates{width:100%}table.wc_input_table span.tips,table.wc_tax_rates span.tips{color:#2ea2cc}table.wc_input_table td,table.wc_tax_rates td{padding:0;border-right:1px solid #DFDFDF;border-bottom:1px solid #DFDFDF;border-top:0;background:#fff}table.wc_input_table td input[type=text],table.wc_input_table td input[type=number],table.wc_tax_rates td input[type=text],table.wc_tax_rates td input[type=number]{width:100%;padding:5px 7px;margin:0;border:0;background:0 0}table.wc_input_table td.apply_to_shipping,table.wc_input_table td.compound,table.wc_tax_rates td.apply_to_shipping,table.wc_tax_rates td.compound{padding:5px 7px;vertical-align:middle}table.wc_input_table td.apply_to_shipping input,table.wc_input_table td.compound input,table.wc_tax_rates td.apply_to_shipping input,table.wc_tax_rates td.compound input{width:auto;padding:0}table.wc_input_table td:last-child,table.wc_tax_rates td:last-child{border-right:0}table.wc_input_table tr.current td,table.wc_tax_rates tr.current td{background-color:#fefbcc}table.wc_input_table .cost,table.wc_input_table .cost input,table.wc_input_table .item_cost,table.wc_input_table .item_cost input,table.wc_tax_rates .cost,table.wc_tax_rates .cost input,table.wc_tax_rates .item_cost,table.wc_tax_rates .item_cost input{text-align:right}table.wc_input_table th.sort,table.wc_tax_rates th.sort{width:17px;padding:0 4px}table.wc_input_table td.sort,table.wc_tax_rates td.sort{padding:0 4px}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort{cursor:move;font-size:15px;background:#f9f9f9;text-align:center;vertical-align:middle}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before{color:#333}table.wc_input_table .button,table.wc_tax_rates .button{float:left;margin-right:5px}table.wc_input_table .export,table.wc_input_table .import,table.wc_tax_rates .export,table.wc_tax_rates .import{float:right;margin-right:0;margin-left:5px}table.wc_input_table span.tips,table.wc_tax_rates span.tips{padding:0 3px}table.wc_input_table .pagination,table.wc_tax_rates .pagination{float:right}table.wc_input_table .pagination .button,table.wc_tax_rates .pagination .button{margin-left:5px;margin-right:0}table.wc_input_table .pagination .current,table.wc_tax_rates .pagination .current{background:#bbb;text-shadow:none}table.wc_input_table tfoot th,table.wc_tax_rates tfoot th{padding-left:20px;padding-right:20px}table.wc_input_table tr:last-child td,table.wc_tax_rates tr:last-child td{border-bottom:0}table.wc_emails,table.wc_gateways,table.wc_shipping{position:relative}table.wc_emails td,table.wc_gateways td,table.wc_shipping td{vertical-align:middle;padding:7px;line-height:2em}table.wc_emails tr:nth-child(odd) td,table.wc_gateways tr:nth-child(odd) td,table.wc_shipping tr:nth-child(odd) td{background:#f9f9f9}table.wc_emails th,table.wc_gateways th,table.wc_shipping th{padding:9px 7px!important;vertical-align:middle}table.wc_emails .settings,table.wc_gateways .settings,table.wc_shipping .settings{text-align:right}table.wc_emails .default,table.wc_emails .radio,table.wc_emails .status,table.wc_gateways .default,table.wc_gateways .radio,table.wc_gateways .status,table.wc_shipping .default,table.wc_shipping .radio,table.wc_shipping .status{text-align:center}table.wc_emails .default .tips,table.wc_emails .radio .tips,table.wc_emails .status .tips,table.wc_gateways .default .tips,table.wc_gateways .radio .tips,table.wc_gateways .status .tips,table.wc_shipping .default .tips,table.wc_shipping .radio .tips,table.wc_shipping .status .tips{margin:0 auto}table.wc_emails .default input,table.wc_emails .radio input,table.wc_emails .status input,table.wc_gateways .default input,table.wc_gateways .radio input,table.wc_gateways .status input,table.wc_shipping .default input,table.wc_shipping .radio input,table.wc_shipping .status input{margin:0}table.wc_emails th.sort,table.wc_gateways th.sort,table.wc_shipping th.sort{width:28px;padding:0}table.wc_emails td.sort,table.wc_gateways td.sort,table.wc_shipping td.sort{padding:0 7px;cursor:move;font-size:15px;text-align:center;vertical-align:middle}table.wc_emails td.sort:before,table.wc_gateways td.sort:before,table.wc_shipping td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_emails .wc-email-settings-table-name span,table.wc_gateways .wc-email-settings-table-name span,table.wc_shipping .wc-email-settings-table-name span{font-weight:400;color:#999;margin:0 0 0 4px!important}table.wc_emails .wc-email-settings-table-status,table.wc_gateways .wc-email-settings-table-status,table.wc_shipping .wc-email-settings-table-status{text-align:center;width:1em}table.wc_emails .wc-email-settings-table-status .tips,table.wc_gateways .wc-email-settings-table-status .tips,table.wc_shipping .wc-email-settings-table-status .tips{margin:0 auto}table.wc_emails .wc-email-settings-table-actions a,table.wc_gateways .wc-email-settings-table-actions a,table.wc_shipping .wc-email-settings-table-actions a{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}table.wc_emails .wc-email-settings-table-actions a:after,table.wc_gateways .wc-email-settings-table-actions a:after,table.wc_shipping .wc-email-settings-table-actions a:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}table.wc-shipping-classes td,table.wc-shipping-classes th,table.wc-shipping-zone-methods td,table.wc-shipping-zone-methods th,table.wc-shipping-zones td,table.wc-shipping-zones th{vertical-align:top;line-height:24px;padding:1em;font-size:14px;background:#fff}table.wc-shipping-classes td li,table.wc-shipping-classes th li,table.wc-shipping-zone-methods td li,table.wc-shipping-zone-methods th li,table.wc-shipping-zones td li,table.wc-shipping-zones th li{line-height:24px;font-size:14px}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state,table.wc-shipping-classes td.wc-shipping-zones-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state,table.wc-shipping-zones td.wc-shipping-zones-blank-state{background:#F7F1F6!important;overflow:hidden;position:relative;padding:7.5em 7.5%;border-bottom:2px solid #EEE2EC}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zones td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state p{color:#a46497;font-size:1.5em;line-height:1.5em;margin:0 0 1em;position:relative;z-index:1;text-shadow:1px 1px 1px #fff}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state p.main{font-size:2em}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state li{margin-left:1em;list-style:circle inside}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-classes td.wc-shipping-zones-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state:before,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zones td.wc-shipping-zones-blank-state:before{content:"\e01b";font-family:WooCommerce;text-align:center;line-height:1;color:#EEE2EC;display:block;width:1em;font-size:40em;top:50%;right:-3.75%;margin-top:-.1875em;position:absolute}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-classes td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zones-blank-state .button-primary{background-color:#804877;border-color:#804877;-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);margin:0;opacity:1;text-shadow:0 -1px 1px #8a4f7f,1px 0 1px #8a4f7f,0 1px 1px #8a4f7f,-1px 0 1px #8a4f7f;font-size:1.5em;padding:.75em 1em;height:auto;position:relative;z-index:1}table.wc-shipping-classes .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-classes .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-classes tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-classes tr.odd td,table.wc-shipping-zone-methods .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tr.odd td,table.wc-shipping-zones .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zones .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zones tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zones tr.odd td{background:#f9f9f9}table.wc-shipping-classes p,table.wc-shipping-classes ul,table.wc-shipping-zone-methods p,table.wc-shipping-zone-methods ul,table.wc-shipping-zones p,table.wc-shipping-zones ul{margin:0}table.wc-shipping-classes td.wc-shipping-zone-method-sort,table.wc-shipping-classes td.wc-shipping-zone-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-sort,table.wc-shipping-zones td.wc-shipping-zone-method-sort,table.wc-shipping-zones td.wc-shipping-zone-sort{cursor:move;font-size:15px;text-align:center}table.wc-shipping-classes td.wc-shipping-zone-method-sort:before,table.wc-shipping-classes td.wc-shipping-zone-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:before,table.wc-shipping-zones td.wc-shipping-zone-sort:before{content:"\f333";font-family:Dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-classes td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-sort:hover:before{color:#333}table.wc-shipping-classes td.wc-shipping-zone-worldwide,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide,table.wc-shipping-zones td.wc-shipping-zone-worldwide{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-worldwide:before,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide:before,table.wc-shipping-zones td.wc-shipping-zone-worldwide:before{content:"\f319";font-family:dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes .wc-shipping-zone-methods,table.wc-shipping-classes .wc-shipping-zone-name,table.wc-shipping-zone-methods .wc-shipping-zone-methods,table.wc-shipping-zone-methods .wc-shipping-zone-name,table.wc-shipping-zones .wc-shipping-zone-methods,table.wc-shipping-zones .wc-shipping-zone-name{width:25%}table.wc-shipping-classes .wc-shipping-class-description input,table.wc-shipping-classes .wc-shipping-class-description select,table.wc-shipping-classes .wc-shipping-class-description textarea,table.wc-shipping-classes .wc-shipping-class-name input,table.wc-shipping-classes .wc-shipping-class-name select,table.wc-shipping-classes .wc-shipping-class-name textarea,table.wc-shipping-classes .wc-shipping-class-slug input,table.wc-shipping-classes .wc-shipping-class-slug select,table.wc-shipping-classes .wc-shipping-class-slug textarea,table.wc-shipping-classes .wc-shipping-zone-name input,table.wc-shipping-classes .wc-shipping-zone-name select,table.wc-shipping-classes .wc-shipping-zone-name textarea,table.wc-shipping-classes .wc-shipping-zone-region input,table.wc-shipping-classes .wc-shipping-zone-region select,table.wc-shipping-classes .wc-shipping-zone-region textarea,table.wc-shipping-zone-methods .wc-shipping-class-description input,table.wc-shipping-zone-methods .wc-shipping-class-description select,table.wc-shipping-zone-methods .wc-shipping-class-description textarea,table.wc-shipping-zone-methods .wc-shipping-class-name input,table.wc-shipping-zone-methods .wc-shipping-class-name select,table.wc-shipping-zone-methods .wc-shipping-class-name textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug input,table.wc-shipping-zone-methods .wc-shipping-class-slug select,table.wc-shipping-zone-methods .wc-shipping-class-slug textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name input,table.wc-shipping-zone-methods .wc-shipping-zone-name select,table.wc-shipping-zone-methods .wc-shipping-zone-name textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region input,table.wc-shipping-zone-methods .wc-shipping-zone-region select,table.wc-shipping-zone-methods .wc-shipping-zone-region textarea,table.wc-shipping-zones .wc-shipping-class-description input,table.wc-shipping-zones .wc-shipping-class-description select,table.wc-shipping-zones .wc-shipping-class-description textarea,table.wc-shipping-zones .wc-shipping-class-name input,table.wc-shipping-zones .wc-shipping-class-name select,table.wc-shipping-zones .wc-shipping-class-name textarea,table.wc-shipping-zones .wc-shipping-class-slug input,table.wc-shipping-zones .wc-shipping-class-slug select,table.wc-shipping-zones .wc-shipping-class-slug textarea,table.wc-shipping-zones .wc-shipping-zone-name input,table.wc-shipping-zones .wc-shipping-zone-name select,table.wc-shipping-zones .wc-shipping-zone-name textarea,table.wc-shipping-zones .wc-shipping-zone-region input,table.wc-shipping-zones .wc-shipping-zone-region select,table.wc-shipping-zones .wc-shipping-zone-region textarea{width:100%}table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-zone-delete{color:red}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle{float:right;margin:0;font-size:.9em;text-decoration:underline}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes{display:none}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea{margin-top:1em}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes .description{font-size:.9em;color:#999}table.wc-shipping-classes .wc-shipping-class-count,table.wc-shipping-zone-methods .wc-shipping-class-count,table.wc-shipping-zones .wc-shipping-class-count{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-methods,table.wc-shipping-zone-methods td.wc-shipping-zone-methods,table.wc-shipping-zones td.wc-shipping-zone-methods{color:#999}table.wc-shipping-classes td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .method_disabled{text-decoration:line-through}table.wc-shipping-classes td.wc-shipping-zone-methods ul,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul,table.wc-shipping-zones td.wc-shipping-zone-methods ul{color:#999;position:relative;padding-right:32px}table.wc-shipping-classes td.wc-shipping-zone-methods ul li,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li,table.wc-shipping-zones td.wc-shipping-zone-methods ul li{display:inline;margin:0}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:before{content:", "}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-classes td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:nth-child(2):before{content:""}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child{display:block}table.wc-shipping-classes td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zones td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row{position:absolute;right:0;top:0}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method{display:block;width:24px;padding:24px 0 0;height:0;overflow:hidden;cursor:pointer}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method:before{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;font-family:Dashicons;content:"\f502";color:#999;vertical-align:middle;line-height:24px;font-size:16px;margin:0}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled:before{line-height:inherit}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled{margin-top:1px;display:inline-block}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled{cursor:not-allowed}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled:before{color:#ccc}table.wc-shipping-classes .wc-shipping-zone-method-title,table.wc-shipping-zone-methods .wc-shipping-zone-method-title,table.wc-shipping-zones .wc-shipping-zone-method-title{width:33%}table.wc-shipping-classes .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zone-methods .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zones .wc-shipping-zone-method-title .wc-shipping-zone-method-delete{color:red}table.wc-shipping-classes .wc-shipping-zone-method-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled{text-align:center}table.wc-shipping-classes tfoot input,table.wc-shipping-classes tfoot select,table.wc-shipping-zone-methods tfoot input,table.wc-shipping-zone-methods tfoot select,table.wc-shipping-zones tfoot input,table.wc-shipping-zones tfoot select{vertical-align:middle!important}table.wc-shipping-classes tfoot .button-secondary,table.wc-shipping-zone-methods tfoot .button-secondary,table.wc-shipping-zones tfoot .button-secondary{float:right}table.wc-shipping-classes .editing .wc-shipping-zone-edit,table.wc-shipping-classes .editing .wc-shipping-zone-view,table.wc-shipping-zone-methods .editing .wc-shipping-zone-edit,table.wc-shipping-zone-methods .editing .wc-shipping-zone-view,table.wc-shipping-zones .editing .wc-shipping-zone-edit,table.wc-shipping-zones .editing .wc-shipping-zone-view{display:none}.wc-modal-shipping-method-settings{background:#f8f8f8;padding:1em!important}.wc-modal-shipping-method-settings form .form-table{width:100%;background:#fff;margin:0 0 1.5em}.wc-modal-shipping-method-settings form .form-table tr th{width:30%;position:relative}.wc-modal-shipping-method-settings form .form-table tr th .woocommerce-help-tip{float:right;margin:-8px -.5em 0 0;vertical-align:middle;right:0;top:50%;position:absolute}.wc-modal-shipping-method-settings form .form-table tr td input,.wc-modal-shipping-method-settings form .form-table tr td select,.wc-modal-shipping-method-settings form .form-table tr td textarea{width:50%;min-width:250px}.wc-modal-shipping-method-settings form .form-table tr td input[type=checkbox]{width:auto;min-width:16px}.wc-modal-shipping-method-settings form .form-table tr td,.wc-modal-shipping-method-settings form .form-table tr th{vertical-align:middle;margin:0;line-height:24px;padding:1em;border-bottom:1px solid #f8f8f8}.wc-modal-shipping-method-settings form .form-table:last-of-type{margin-bottom:0}.wc-backbone-modal .wc-shipping-zone-method-selector p{margin-top:0}.wc-backbone-modal .wc-shipping-zone-method-selector .wc-shipping-zone-method-description{margin:.75em 1px 0;line-height:1.5em;color:#999;font-style:italic}.wc-backbone-modal .wc-shipping-zone-method-selector select{width:100%;cursor:pointer}img.help_tip{margin:0 0 0 9px;vertical-align:middle}.postbox img.help_tip{margin-top:0}.postbox .woocommerce-help-tip{margin:0 0 0 9px}.status-disabled,.status-enabled,.status-manual{font-size:1.4em;display:block;text-indent:-9999px;position:relative;height:1em;width:1em}.status-disabled:before,.status-enabled:before,.status-manual:before{font-family:WooCommerce;line-height:1;margin:0;position:absolute;width:100%;height:100%;text-indent:0;top:0;font-variant:normal;-webkit-font-smoothing:antialiased;font-weight:400;text-align:center;left:0;speak:none;text-transform:none}.status-manual:before{content:"";color:#999}.status-enabled:before{content:"";color:#a46497}.status-disabled:before{content:"";color:#ccc}.woocommerce h2.woo-nav-tab-wrapper{margin-bottom:1em}.woocommerce nav.woo-nav-tab-wrapper{margin:1.5em 0 1em;border-bottom:1px solid #ccc}.woocommerce .subsubsub{margin:-8px 0 0}.woocommerce .wc-admin-breadcrumb{margin-left:.5em}.woocommerce .wc-admin-breadcrumb a{color:#a46497}.woocommerce #template div{margin:0}.woocommerce #template div p .button{float:right;margin-left:10px;margin-top:-4px}.woocommerce #template div .editor textarea{margin-bottom:8px}.woocommerce textarea[disabled=disabled]{background:#DFDFDF!important}.woocommerce table.form-table{margin:0;position:relative}.woocommerce table.form-table .forminp-radio ul{margin:0}.woocommerce table.form-table .forminp-radio ul li{line-height:1.4em}.woocommerce table.form-table textarea.input-text{height:100%;min-width:150px;display:block}.woocommerce table.form-table input.regular-input{width:25em}.woocommerce table.form-table textarea.wide-input{width:100%}.woocommerce table.form-table .woocommerce-help-tip,.woocommerce table.form-table img.help_tip{padding:0;margin:-4px 0 0 5px;vertical-align:middle;cursor:help;line-height:1}.woocommerce table.form-table span.help_tip{cursor:help;color:#2ea2cc}.woocommerce table.form-table th{position:relative;padding-right:24px}.woocommerce table.form-table .select2-container{display:block;max-width:350px;vertical-align:top;margin-bottom:3px}.woocommerce table.form-table table.widefat th{padding-right:inherit}.woocommerce table.form-table th .woocommerce-help-tip,.woocommerce table.form-table th img.help_tip{margin:0 -24px 0 0;float:right}.woocommerce table.form-table .wp-list-table .woocommerce-help-tip{float:none}.woocommerce table.form-table fieldset{margin-top:4px}.woocommerce table.form-table fieldset .woocommerce-help-tip,.woocommerce table.form-table fieldset img.help_tip{margin:-3px 0 0 5px}.woocommerce table.form-table fieldset p.description{margin-bottom:8px}.woocommerce table.form-table fieldset:first-child{margin-top:0}.woocommerce table.form-table .iris-picker{z-index:100;display:none;position:absolute;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,.2)}.woocommerce table.form-table .iris-picker .ui-slider{border:0!important;margin:0!important;width:auto!important;height:auto!important;background:none!important}.woocommerce table.form-table .iris-picker .ui-slider .ui-slider-handle{margin-bottom:0!important}.woocommerce table.form-table .colorpickpreview{padding:3px 3px 3px 20px;border:1px solid #ddd;border-right:0}.woocommerce table.form-table .colorpick{border-left:0}.woocommerce table.form-table .image_width_settings{vertical-align:middle}.woocommerce table.form-table .image_width_settings label{margin-left:10px}.woocommerce table.form-table .wc_emails_wrapper{padding:0 15px 10px 0}.woocommerce #tabs-wrap table a.remove{margin-left:4px}.woocommerce #tabs-wrap table p{margin:0 0 4px!important;overflow:hidden;zoom:1}.woocommerce #tabs-wrap table p a.add{float:left}#wp-excerpt-editor-container{background:#fff}#product_variation-parent #parent_id{width:100%}#postimagediv img{border:1px solid #d5d5d5;max-width:100%}#woocommerce-product-images .inside{margin:0;padding:0}#woocommerce-product-images .inside .add_product_images{padding:0 12px 12px}#woocommerce-product-images .inside #product_images_container{padding:0 0 0 9px}#woocommerce-product-images .inside #product_images_container ul{margin:0;padding:0}#woocommerce-product-images .inside #product_images_container ul:after,#woocommerce-product-images .inside #product_images_container ul:before{content:" ";display:table}#woocommerce-product-images .inside #product_images_container ul:after{clear:both}#woocommerce-product-images .inside #product_images_container ul li.add,#woocommerce-product-images .inside #product_images_container ul li.image,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{width:80px;float:left;cursor:move;border:1px solid #d5d5d5;margin:9px 9px 0 0;background:#f7f7f7;border-radius:2px;position:relative;box-sizing:border-box}#woocommerce-product-images .inside #product_images_container ul li.add img,#woocommerce-product-images .inside #product_images_container ul li.image img,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder img{width:100%;height:auto;display:block}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{border:3px dashed #ddd;position:relative}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-size:2.618em;line-height:72px;color:#ddd}#woocommerce-product-images .inside #product_images_container ul ul.actions{position:absolute;top:-8px;right:-8px;padding:2px;display:none}#woocommerce-product-images .inside #product_images_container ul ul.actions li{float:right;margin:0 0 0 2px}#woocommerce-product-images .inside #product_images_container ul ul.actions li a{width:1em;margin:0;height:0;display:block;overflow:hidden}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.tips{cursor:pointer}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.4em}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:hover:before{color:#a00}#woocommerce-product-images .inside #product_images_container ul li:hover ul.actions{display:block}#woocommerce-product-data .hndle{padding:10px}#woocommerce-product-data .hndle span{display:block;vertical-align:middle;line-height:24px}#woocommerce-product-data .hndle span span{display:inline;line-height:inherit;vertical-align:baseline}#woocommerce-product-data .hndle label{padding-right:1em;font-size:12px;vertical-align:baseline}#woocommerce-product-data .hndle label:first-child{margin-right:1em;border-right:1px solid #dfdfdf}#woocommerce-product-data .hndle input,#woocommerce-product-data .hndle select{margin:-3px 0 0 .5em;vertical-align:middle}#woocommerce-product-data>.handlediv{margin-top:4px}#woocommerce-product-data .wrap{margin:0}#woocommerce-coupon-description{padding:3px 8px;font-size:1.7em;line-height:1.42em;height:auto;width:100%;outline:0;margin:10px 0;display:block}#woocommerce-coupon-description::-webkit-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description::-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-ms-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap{background:#fff}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{float:left;width:80%}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-product-data .woocommerce_options_panel .wc-radios{display:block;float:left;margin:0}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-product-data .woocommerce_options_panel .wc-radios li{display:block;padding:0 0 10px}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li input,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-product-data .woocommerce_options_panel .wc-radios li input{width:auto}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap,.woocommerce .panel-wrap{overflow:hidden}#woocommerce-coupon-data ul.wc-tabs,#woocommerce-product-data ul.wc-tabs,.woocommerce ul.wc-tabs{margin:0;width:20%;float:left;line-height:1em;padding:0 0 10px;position:relative;background-color:#fafafa;border-right:1px solid #eee;box-sizing:border-box}#woocommerce-coupon-data ul.wc-tabs:after,#woocommerce-product-data ul.wc-tabs:after,.woocommerce ul.wc-tabs:after{content:"";display:block;width:100%;height:9999em;position:absolute;bottom:-9999em;left:0;background-color:#fafafa;border-right:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li,#woocommerce-product-data ul.wc-tabs li,.woocommerce ul.wc-tabs li{margin:0;padding:0;display:block;position:relative}#woocommerce-coupon-data ul.wc-tabs li a,#woocommerce-product-data ul.wc-tabs li a,.woocommerce ul.wc-tabs li a{margin:0;padding:10px;display:block;box-shadow:none;text-decoration:none;line-height:20px!important;border-bottom:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li a:before,#woocommerce-product-data ul.wc-tabs li a:before,.woocommerce ul.wc-tabs li a:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}#woocommerce-coupon-data ul.wc-tabs li.general_options a:before,#woocommerce-product-data ul.wc-tabs li.general_options a:before,.woocommerce ul.wc-tabs li.general_options a:before{content:"\f107"}#woocommerce-coupon-data ul.wc-tabs li.inventory_options a:before,#woocommerce-product-data ul.wc-tabs li.inventory_options a:before,.woocommerce ul.wc-tabs li.inventory_options a:before{content:"\f481"}#woocommerce-coupon-data ul.wc-tabs li.shipping_options a:before,#woocommerce-product-data ul.wc-tabs li.shipping_options a:before,.woocommerce ul.wc-tabs li.shipping_options a:before{font-family:WooCommerce;content:"\e01a"}#woocommerce-coupon-data ul.wc-tabs li.linked_product_options a:before,#woocommerce-product-data ul.wc-tabs li.linked_product_options a:before,.woocommerce ul.wc-tabs li.linked_product_options a:before{content:"\f103"}#woocommerce-coupon-data ul.wc-tabs li.attribute_options a:before,#woocommerce-product-data ul.wc-tabs li.attribute_options a:before,.woocommerce ul.wc-tabs li.attribute_options a:before{content:"\f175"}#woocommerce-coupon-data ul.wc-tabs li.advanced_options a:before,#woocommerce-product-data ul.wc-tabs li.advanced_options a:before,.woocommerce ul.wc-tabs li.advanced_options a:before{font-family:Dashicons;content:"\f111"}#woocommerce-coupon-data ul.wc-tabs li.variations_options a:before,#woocommerce-product-data ul.wc-tabs li.variations_options a:before,.woocommerce ul.wc-tabs li.variations_options a:before{content:"\f509"}#woocommerce-coupon-data ul.wc-tabs li.usage_restriction_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_restriction_options a:before,.woocommerce ul.wc-tabs li.usage_restriction_options a:before{font-family:WooCommerce;content:"\e602"}#woocommerce-coupon-data ul.wc-tabs li.usage_limit_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_limit_options a:before,.woocommerce ul.wc-tabs li.usage_limit_options a:before{font-family:WooCommerce;content:"\e601"}#woocommerce-coupon-data ul.wc-tabs li.general_coupon_data a:before,#woocommerce-product-data ul.wc-tabs li.general_coupon_data a:before,.woocommerce ul.wc-tabs li.general_coupon_data a:before{font-family:WooCommerce;content:"\e600"}#woocommerce-coupon-data ul.wc-tabs li.active a,#woocommerce-product-data ul.wc-tabs li.active a,.woocommerce ul.wc-tabs li.active a{color:#555;position:relative;background-color:#eee}.woocommerce_page_wc-settings .shippingrows th.check-column{padding-top:20px}.woocommerce_page_wc-settings .shippingrows tfoot th{padding-left:10px}.woocommerce_page_wc-settings .shippingrows .add.button:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}.woocommerce_page_wc-settings h3.wc-settings-sub-title{font-size:1.2em}#woocommerce-coupon-data .inside,#woocommerce-order-data .inside,#woocommerce-order-downloads .inside,#woocommerce-product-data .inside,#woocommerce-product-type-options .inside{margin:0;padding:0}.panel,.woocommerce_options_panel{padding:9px;color:#555}.panel .form-field .woocommerce-help-tip,.woocommerce_options_panel .form-field .woocommerce-help-tip{font-size:1.4em}.panel,.woocommerce_page_settings .woocommerce_options_panel{padding:0}#woocommerce-product-specs .inside,#woocommerce-product-type-options .panel{margin:0;padding:9px}#woocommerce-product-type-options .panel p,.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p{margin:0 0 9px;font-size:12px;padding:5px 9px;line-height:24px}#woocommerce-product-type-options .panel p:after,.woocommerce_options_panel fieldset.form-field:after,.woocommerce_options_panel p:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce_options_panel .checkbox,.woocommerce_variable_attributes .checkbox{width:auto;margin:3px 0;vertical-align:middle}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{width:100%;padding:0!important}.woocommerce_options_panel .downloadable_files table th,.woocommerce_variations .downloadable_files table th{padding:7px 0 7px 7px!important}.woocommerce_options_panel .downloadable_files table th.sort,.woocommerce_variations .downloadable_files table th.sort{width:17px;padding:7px!important}.woocommerce_options_panel .downloadable_files table th .woocommerce-help-tip,.woocommerce_variations .downloadable_files table th .woocommerce-help-tip{font-size:1.1em;margin-left:0}.woocommerce_options_panel .downloadable_files table td,.woocommerce_variations .downloadable_files table td{vertical-align:middle!important;padding:4px 0 4px 7px!important;position:relative}.woocommerce_options_panel .downloadable_files table td:last-child,.woocommerce_variations .downloadable_files table td:last-child{padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td input.input_text,.woocommerce_variations .downloadable_files table td input.input_text{width:100%;float:none;min-width:0;margin:1px 0}.woocommerce_options_panel .downloadable_files table td .upload_file_button,.woocommerce_variations .downloadable_files table td .upload_file_button{width:auto;float:right;cursor:pointer}.woocommerce_options_panel .downloadable_files table td .delete,.woocommerce_variations .downloadable_files table td .delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.2em}.woocommerce_options_panel .downloadable_files table td .delete:before,.woocommerce_variations .downloadable_files table td .delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}.woocommerce_options_panel .downloadable_files table td .delete:hover:before,.woocommerce_variations .downloadable_files table td .delete:hover:before{color:#a00}.woocommerce_options_panel .downloadable_files table td.sort,.woocommerce_variations .downloadable_files table td.sort{width:17px;cursor:move;font-size:15px;text-align:center;background:#f9f9f9;padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td.sort:before,.woocommerce_variations .downloadable_files table td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_options_panel .downloadable_files table td.sort:hover:before,.woocommerce_variations .downloadable_files table td.sort:hover:before{color:#333}.woocommerce_variation h3 .sort{width:17px;height:26px;cursor:move;float:right;font-size:15px;font-weight:400;margin-right:.5em;visibility:hidden;text-align:center;vertical-align:middle}.woocommerce_variation h3 .sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:28px;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_variation h3 .sort:hover:before{color:#777}.woocommerce_variation h3:hover .sort,.woocommerce_variation.ui-sortable-helper .sort{visibility:visible}.woocommerce_options_panel{min-height:175px;box-sizing:border-box}.woocommerce_options_panel .downloadable_files{padding:0 9px 0 162px;position:relative;margin:9px 0}.woocommerce_options_panel .downloadable_files label{position:absolute;left:0;margin:0 0 0 12px;line-height:24px}.woocommerce_options_panel p{margin:9px 0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px 5px 162px!important}.woocommerce_options_panel .sale_price_dates_fields .short:first-of-type{margin-bottom:1em}.woocommerce_options_panel .sale_price_dates_fields .short:nth-of-type(2){clear:left}.woocommerce_options_panel label,.woocommerce_options_panel legend{float:left;width:150px;padding:0;margin:0 0 0 -150px}.woocommerce_options_panel label .req,.woocommerce_options_panel legend .req{font-weight:700;font-style:normal;color:#a00}.woocommerce_options_panel .description{padding:0;margin:0 0 0 7px;clear:none;display:inline}.woocommerce_options_panel .description-block{margin-left:0;display:block}.woocommerce_options_panel input,.woocommerce_options_panel select,.woocommerce_options_panel textarea{margin:0}.woocommerce_options_panel textarea{height:3.5em;line-height:1.5em;vertical-align:top}.woocommerce_options_panel input[type=text],.woocommerce_options_panel input[type=number],.woocommerce_options_panel input[type=email],.woocommerce_options_panel input[type=password]{width:50%;float:left}.woocommerce_options_panel input.button{width:auto;margin-left:8px}.woocommerce_options_panel select{float:left}.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:50%}.woocommerce_options_panel .sized{width:auto!important;margin-right:6px}.woocommerce_options_panel .options_group{border-top:1px solid #fff;border-bottom:1px solid #eee}.woocommerce_options_panel .options_group:first-child{border-top:0}.woocommerce_options_panel .options_group:last-child{border-bottom:0}.woocommerce_options_panel .options_group fieldset{margin:9px 0;font-size:12px;padding:5px 9px;line-height:24px}.woocommerce_options_panel .options_group fieldset label{width:auto;float:none}.woocommerce_options_panel .options_group fieldset ul{float:left;width:50%;margin:0;padding:0}.woocommerce_options_panel .options_group fieldset ul li{margin:0;width:auto}.woocommerce_options_panel .options_group fieldset ul li input{width:auto;float:none;margin-right:4px}.woocommerce_options_panel .options_group fieldset ul.wc-radios label{margin-left:0}.woocommerce_options_panel .dimensions_field .wrap{display:block;width:50%}.woocommerce_options_panel .dimensions_field .wrap input{width:30.75%;margin-right:3.8%}.woocommerce_options_panel .dimensions_field .wrap .last{margin-right:0}.woocommerce_options_panel.padded{padding:1em}#woocommerce-product-data input.dp-applied,.woocommerce_options_panel .select2-container{float:left}#grouped_product_options,#simple_product_options,#virtual_product_options{padding:12px;font-style:italic;color:#666}.wc-metaboxes-wrapper .toolbar{margin:0!important;border-top:1px solid #fff;border-bottom:1px solid #eee;padding:9px 12px!important}.wc-metaboxes-wrapper .toolbar:first-child{border-top:0}.wc-metaboxes-wrapper .toolbar:last-child{border-bottom:0}.wc-metaboxes-wrapper .toolbar .add_variation{float:right;margin-left:5px}.wc-metaboxes-wrapper .toolbar .cancel-variation-changes,.wc-metaboxes-wrapper .toolbar .save-variation-changes{float:left;margin-right:5px}.wc-metaboxes-wrapper p.toolbar{overflow:hidden;zoom:1}.wc-metaboxes-wrapper .expand-close{margin-right:2px;color:#777;font-size:12px;font-style:italic}.wc-metaboxes-wrapper .expand-close a{background:0 0;padding:0;font-size:12px;text-decoration:none}.wc-metaboxes-wrapper#product_attributes .expand-close{float:right;line-height:28px}.wc-metaboxes-wrapper .fr,.wc-metaboxes-wrapper button.add_variable_attribute{float:right;margin:0 0 0 6px}.wc-metaboxes-wrapper .wc-metaboxes{border-bottom:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox-sortable-placeholder{border-color:#bbb;background-color:#f5f5f5;margin-bottom:9px;border-width:1px;border-style:dashed}.wc-metaboxes-wrapper .wc-metabox{background:#fff;border-bottom:1px solid #eee;margin:0!important}.wc-metaboxes-wrapper .wc-metabox select{font-weight:400}.wc-metaboxes-wrapper .wc-metabox:last-of-type{border-bottom:0}.wc-metaboxes-wrapper .wc-metabox .handlediv{width:27px}.wc-metaboxes-wrapper .wc-metabox .handlediv:before{content:"\f142"!important;cursor:pointer;display:inline-block;font:400 20px/1 Dashicons;line-height:.5!important;padding:8px 10px;position:relative;right:12px;top:0}.wc-metaboxes-wrapper .wc-metabox.closed{border-radius:3px}.wc-metaboxes-wrapper .wc-metabox.closed .handlediv:before{content:"\f140"!important}.wc-metaboxes-wrapper .wc-metabox.closed h3{border:0}.wc-metaboxes-wrapper .wc-metabox h3{margin:0!important;padding:.75em .75em .75em 1em!important;font-size:1em!important;overflow:hidden;zoom:1;cursor:move}.wc-metaboxes-wrapper .wc-metabox h3 a.delete,.wc-metaboxes-wrapper .wc-metabox h3 button{float:right}.wc-metaboxes-wrapper .wc-metabox h3 a.delete{color:red;font-weight:400;line-height:26px;text-decoration:none;position:relative;visibility:hidden}.wc-metaboxes-wrapper .wc-metabox h3 strong{line-height:26px;font-weight:700}.wc-metaboxes-wrapper .wc-metabox h3 select{font-family:sans-serif;max-width:20%;margin:.25em .25em .25em 0}.wc-metaboxes-wrapper .wc-metabox h3 .handlediv{background-position:6px 5px!important;visibility:hidden;height:26px}.wc-metaboxes-wrapper .wc-metabox h3.fixed{cursor:pointer!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3{cursor:pointer;padding:.5em .75em .5em 1em!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .handlediv,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .sort,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 a.delete{margin-top:.25em}.wc-metaboxes-wrapper .wc-metabox h3:hover .handlediv,.wc-metaboxes-wrapper .wc-metabox h3:hover a.delete,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper .handlediv,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper a.delete{visibility:visible}.wc-metaboxes-wrapper .wc-metabox table{width:100%;position:relative;background-color:#fdfdfd;padding:1em;border-top:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox table td{text-align:left;padding:0 6px 1em 0;vertical-align:top;border:0}.wc-metaboxes-wrapper .wc-metabox table td label{text-align:left;display:block;line-height:21px}.wc-metaboxes-wrapper .wc-metabox table td input{float:left;min-width:200px}.wc-metaboxes-wrapper .wc-metabox table td input,.wc-metaboxes-wrapper .wc-metabox table td textarea{width:100%;margin:0;display:block;font-size:14px;padding:4px;color:#555}.wc-metaboxes-wrapper .wc-metabox table td .select2-container,.wc-metaboxes-wrapper .wc-metabox table td select{width:100%!important}.wc-metaboxes-wrapper .wc-metabox table td input.short{width:200px}.wc-metaboxes-wrapper .wc-metabox table td input.checkbox{width:16px;min-width:inherit;vertical-align:text-bottom;display:inline-block;float:none}.wc-metaboxes-wrapper .wc-metabox table td.attribute_name{width:200px}.wc-metaboxes-wrapper .wc-metabox table .minus,.wc-metaboxes-wrapper .wc-metabox table .plus{margin-top:6px}.wc-metaboxes-wrapper .wc-metabox table .fl{float:left}.wc-metaboxes-wrapper .wc-metabox table .fr{float:right}.variations-pagenav{float:right;line-height:24px}.variations-pagenav .displaying-num{color:#777;font-size:12px;font-style:italic}.variations-pagenav a{padding:0 10px 3px;background:rgba(0,0,0,.05);font-size:16px;font-weight:400;text-decoration:none}.variations-pagenav a.disabled,.variations-pagenav a.disabled:active,.variations-pagenav a.disabled:focus,.variations-pagenav a.disabled:hover{color:#A0A5AA;background:rgba(0,0,0,.05)}.variations-defaults{float:left}.variations-defaults select{margin:.25em .25em .25em 0}.woocommerce_variable_attributes{background-color:#fdfdfd;border-top:1px solid #eee}.woocommerce_variable_attributes .data{padding:1em 2em}.woocommerce_variable_attributes .data:after,.woocommerce_variable_attributes .data:before{content:" ";display:table}.woocommerce_variable_attributes .data:after{clear:both}.woocommerce_variable_attributes .upload_image_button{display:block;width:48px;height:48px;float:left;margin-right:20px;position:relative;cursor:pointer}.woocommerce_variable_attributes .upload_image_button img{width:100%;height:auto;display:none}.woocommerce_variable_attributes .upload_image_button:before{content:"\f128";font-family:Dashicons;position:absolute;top:0;left:0;right:0;bottom:0;text-align:center;line-height:48px;font-size:48px;font-weight:400;-webkit-font-smoothing:antialiased}.woocommerce_variable_attributes .upload_image_button.remove img{display:block}.woocommerce_variable_attributes .upload_image_button.remove:before{content:"\f335";display:none}.woocommerce_variable_attributes .upload_image_button.remove:hover:before{display:block}.woocommerce_variable_attributes .options{border:1px solid #eee;border-width:1px 0;padding:.25em 0}.woocommerce_variable_attributes .options label{display:inline-block;padding:4px 1em 2px 0}.woocommerce_variable_attributes .options input[type=checkbox]{margin-top:5px;margin-right:3px}.form-row label{display:block}.form-row input[type=number],.form-row input[type=text],.form-row select{width:100%}.form-row.dimensions_field input{width:25%;float:left;margin-right:1%}.form-row.dimensions_field input:last-of-type{margin-right:0}.form-row-first,.form-row-last{width:48%;float:right}.form-row-first{clear:both;float:left}.form-row-full{clear:both}.tips{cursor:help;text-decoration:none}img.tips{padding:5px 0 0}#tiptip_holder{display:none;position:absolute;top:0;left:0;z-index:9999999}#tiptip_holder.tip_top{padding-bottom:5px}#tiptip_holder.tip_top #tiptip_arrow_inner{margin-top:-7px;margin-left:-6px;border-top-color:#333}#tiptip_holder.tip_bottom{padding-top:5px}#tiptip_holder.tip_bottom #tiptip_arrow_inner{margin-top:-5px;margin-left:-6px;border-bottom-color:#333}#tiptip_holder.tip_right{padding-left:5px}#tiptip_holder.tip_right #tiptip_arrow_inner{margin-top:-6px;margin-left:-5px;border-right-color:#333}#tiptip_holder.tip_left{padding-right:5px}#tiptip_holder.tip_left #tiptip_arrow_inner{margin-top:-6px;margin-left:-7px;border-left-color:#333}#tiptip_content,.chart-tooltip,.wc_error_tip{color:#fff;font-size:.8em;max-width:150px;background:#333;text-align:center;border-radius:3px;padding:.618em 1em;box-shadow:0 1px 3px rgba(0,0,0,.2)}#tiptip_content code,.chart-tooltip code,.wc_error_tip code{padding:1px;background:#888}#tiptip_arrow,#tiptip_arrow_inner{position:absolute;border-color:transparent;border-style:solid;border-width:6px;height:0;width:0}.wc_error_tip{max-width:20em;line-height:1.8em;position:absolute;white-space:normal;background:#d82223;margin:1.5em 1px 0 -1em;z-index:9999999}.wc_error_tip:after{content:"";display:block;border:8px solid #d82223;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-3px;left:50%;margin:-1em 0 0 -3px}img.ui-datepicker-trigger{vertical-align:middle;margin-top:-1px;cursor:pointer}.wc-metabox-content img.ui-datepicker-trigger,.woocommerce_options_panel img.ui-datepicker-trigger{float:left;margin-right:8px;margin-top:4px;margin-left:4px}#ui-datepicker-div{display:none}.woocommerce-reports-wide.woocommerce-reports-wrap,.woocommerce-reports-wrap.woocommerce-reports-wrap{margin-left:300px;padding-top:18px}.woocommerce-reports-wide.halved,.woocommerce-reports-wrap.halved{margin:0;overflow:hidden;zoom:1}.woocommerce-reports-wide .widefat td,.woocommerce-reports-wrap .widefat td{vertical-align:top;padding:7px}.woocommerce-reports-wide .widefat td .description,.woocommerce-reports-wrap .widefat td .description{margin:4px 0 0}.woocommerce-reports-wide .postbox:after,.woocommerce-reports-wrap .postbox:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox h3,.woocommerce-reports-wrap .postbox h3{cursor:default!important}.woocommerce-reports-wide .postbox .inside,.woocommerce-reports-wrap .postbox .inside{padding:10px;margin:0!important}.woocommerce-reports-wide .postbox div.stats_range,.woocommerce-reports-wide .postbox h3.stats_range,.woocommerce-reports-wrap .postbox div.stats_range,.woocommerce-reports-wrap .postbox h3.stats_range{border-bottom-color:#dfdfdf;margin:0;padding:0!important}.woocommerce-reports-wide .postbox div.stats_range .export_csv,.woocommerce-reports-wide .postbox h3.stats_range .export_csv,.woocommerce-reports-wrap .postbox div.stats_range .export_csv,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv{float:right;line-height:26px;border-left:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range .export_csv:before,.woocommerce-reports-wide .postbox h3.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox div.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;content:"";text-decoration:none;margin-right:4px}.woocommerce-reports-wide .postbox div.stats_range ul,.woocommerce-reports-wide .postbox h3.stats_range ul,.woocommerce-reports-wrap .postbox div.stats_range ul,.woocommerce-reports-wrap .postbox h3.stats_range ul{list-style:none;margin:0;padding:0;zoom:1;background:#f5f5f5;border-bottom:1px solid #ccc}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox div.stats_range ul:before,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:before,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:before,.woocommerce-reports-wrap .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:before{content:" ";display:table}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:after{clear:both}.woocommerce-reports-wide .postbox div.stats_range ul li,.woocommerce-reports-wide .postbox h3.stats_range ul li,.woocommerce-reports-wrap .postbox div.stats_range ul li,.woocommerce-reports-wrap .postbox h3.stats_range ul li{float:left;margin:0;padding:0;line-height:26px;font-weight:700;font-size:14px}.woocommerce-reports-wide .postbox div.stats_range ul li a,.woocommerce-reports-wide .postbox h3.stats_range ul li a,.woocommerce-reports-wrap .postbox div.stats_range ul li a,.woocommerce-reports-wrap .postbox h3.stats_range ul li a{border-right:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range ul li.active,.woocommerce-reports-wide .postbox h3.stats_range ul li.active,.woocommerce-reports-wrap .postbox div.stats_range ul li.active,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active{background:#fff;-webkit-box-shadow:0 4px 0 0 #fff;box-shadow:0 4px 0 0 #fff}.woocommerce-reports-wide .postbox div.stats_range ul li.active a,.woocommerce-reports-wide .postbox h3.stats_range ul li.active a,.woocommerce-reports-wrap .postbox div.stats_range ul li.active a,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active a{color:#777}.woocommerce-reports-wide .postbox div.stats_range ul li.custom,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom{padding:9px 10px;vertical-align:middle}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form{display:inline;margin:0}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form input.range_datepicker{padding:0;margin:0 10px 0 0;background:0 0;border:0;color:#777;text-align:center;-webkit-box-shadow:none;box-shadow:none}.woocommerce-reports-wide .postbox .chart-with-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar{padding:12px 12px 12px 249px;margin:0!important}.woocommerce-reports-wide .postbox .chart-with-sidebar .chart-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar .chart-sidebar{width:225px;margin-left:-237px;float:left}.woocommerce-reports-wide .postbox .chart-widgets,.woocommerce-reports-wrap .postbox .chart-widgets{margin:0;padding:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget{margin:0 0 1em;background:#fafafa;border:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4{background:#fff;border:1px solid #dfdfdf;border-left-width:0;border-right-width:0;padding:10px;margin:0;color:#2ea2cc;border-top-width:0;background-image:-webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9));background-image:-webkit-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-moz-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-o-linear-gradient(bottom,#ececec,#f9f9f9);background-image:linear-gradient(to top,#ececec,#f9f9f9)}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr.active td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr.active td{background:#f5f5f5}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4.section_title:hover,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4.section_title:hover{color:#a00}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title{cursor:pointer}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span{display:block}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin-left:.618em;content:"";text-decoration:none;float:right;font-size:.9em;line-height:1.618}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open{color:#333}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open span:after{display:none}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section{border-bottom:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section .select2-container,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section .select2-container{width:100%!important}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section:last-of-type,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section:last-of-type{border-radius:0 0 3px 3px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td{padding:7px 10px;vertical-align:top;border-top:1px solid #e5e5e5;line-height:1.4em}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.sparkline,form.report_filters div,form.report_filters input,form.report_filters label,form.report_filters p{vertical-align:middle}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr:first-child td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr:first-child td{border-top:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name{max-width:175px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name a,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name a{word-wrap:break-word}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table .wc_sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table .wc_sparkline{width:32px;height:1em;display:block;float:right}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p{margin:0;padding:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p .submit{margin-top:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget #product_ids,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget #product_ids{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_none,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_none{float:right;color:#999;margin-left:4px;margin-top:10px}.woocommerce-reports-wide .postbox .chart-legend,.woocommerce-reports-wrap .postbox .chart-legend{list-style:none;margin:0 0 1em;padding:0;border:1px solid #dfdfdf;border-right-width:0;border-bottom-width:0;background:#fff}.woocommerce-reports-wide .postbox .chart-legend li,.woocommerce-reports-wrap .postbox .chart-legend li{border-right:5px solid #aaa;color:#aaa;padding:1em;display:block;margin:0;-webkit-transition:all ease .5s;box-shadow:inset 0 -1px 0 0 #dfdfdf}.woocommerce-reports-wide .postbox .chart-legend li strong,.woocommerce-reports-wrap .postbox .chart-legend li strong{font-size:1.618em;line-height:1.2em;color:#464646;font-weight:400;display:block;font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif}.woocommerce-reports-wide .postbox .chart-legend li strong del,.woocommerce-reports-wrap .postbox .chart-legend li strong del{color:#e74c3c;font-weight:400}.woocommerce-reports-wide .postbox .chart-legend li:hover,.woocommerce-reports-wrap .postbox .chart-legend li:hover{box-shadow:inset 0 -1px 0 0 #dfdfdf,inset 300px 0 0 rgba(156,93,144,.1);border-right:5px solid #9c5d90!important;padding-left:1.5em;color:#9c5d90}.woocommerce-reports-wide .postbox .pie-chart-legend,.woocommerce-reports-wrap .postbox .pie-chart-legend{margin:12px 0 0;overflow:hidden}.woocommerce-reports-wide .postbox .pie-chart-legend li,.woocommerce-reports-wrap .postbox .pie-chart-legend li{float:left;margin:0;padding:6px 0 0;border-top:4px solid #999;text-align:center;box-sizing:border-box;width:50%}.woocommerce-reports-wide .postbox .stat,.woocommerce-reports-wrap .postbox .stat{font-size:1.5em!important;font-weight:700;text-align:center}.woocommerce-reports-wide .postbox .chart-placeholder,.woocommerce-reports-wrap .postbox .chart-placeholder{width:100%;height:650px;overflow:hidden;position:relative}.woocommerce-reports-wide .postbox .chart-prompt,.woocommerce-reports-wrap .postbox .chart-prompt{line-height:650px;margin:0;color:#999;font-size:1.2em;font-style:italic;text-align:center}.woocommerce-reports-wide .postbox .chart-container,.woocommerce-reports-wrap .postbox .chart-container{background:#fff;padding:12px;position:relative;border:1px solid #dfdfdf;border-radius:3px}.woocommerce-reports-wide .postbox .main .chart-legend,.woocommerce-reports-wrap .postbox .main .chart-legend{margin-top:12px}.woocommerce-reports-wide .postbox .main .chart-legend li,.woocommerce-reports-wrap .postbox .main .chart-legend li{border-right:0;margin:0 8px 0 0;float:left;border-top:4px solid #aaa}.woocommerce-reports-wide .woocommerce-reports-main,.woocommerce-reports-wrap .woocommerce-reports-main{float:left;min-width:100%}.woocommerce-reports-wide .woocommerce-reports-main table td,.woocommerce-reports-wrap .woocommerce-reports-main table td{padding:9px}.woocommerce-reports-wide .woocommerce-reports-sidebar,.woocommerce-reports-wrap .woocommerce-reports-sidebar{display:inline;width:281px;margin-left:-300px;clear:both;float:left}.woocommerce-reports-wide .woocommerce-reports-left,.woocommerce-reports-wrap .woocommerce-reports-left{width:49.5%;float:left}.woocommerce-reports-wide .woocommerce-reports-right,.woocommerce-reports-wrap .woocommerce-reports-right{width:49.5%;float:right}.woocommerce-reports-wide .column-wc_actions a.edit,.woocommerce-reports-wide .column-wc_actions a.view,.woocommerce-reports-wrap .column-wc_actions a.edit,.woocommerce-reports-wrap .column-wc_actions a.view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;line-height:1.85}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after{content:"\f464"}.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{content:"\f177"}.woocommerce-wide-reports-wrap{padding-bottom:11px}.woocommerce-wide-reports-wrap .widefat .export-data{float:right}.woocommerce-wide-reports-wrap .widefat td,.woocommerce-wide-reports-wrap .widefat th{vertical-align:middle;padding:7px}.chart-tooltip{position:absolute;display:none;line-height:1}table.bar_chart{width:100%}table.bar_chart thead th{text-align:left;color:#ccc;padding:6px 0}table.bar_chart tbody th{padding:6px 0;width:25%;text-align:left!important;font-weight:400!important;border-bottom:1px solid #fee}table.bar_chart tbody td{text-align:right;line-height:24px;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td span{color:#8a4b75;display:block}table.bar_chart tbody td span.alt{color:#47a03e;margin-top:6px}table.bar_chart tbody td.bars{position:relative;text-align:left;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td.bars a,table.bar_chart tbody td.bars span{text-decoration:none;clear:both;background:#8a4b75;float:left;display:block;line-height:24px;height:24px;-moz-border-radius:3px;-webkit-border-radius:3px;-o-border-radius:3px;-khtml-border-radius:3px;border-radius:3px}.post-type-product .woocommerce-BlankState-message:before,.post-type-shop_coupon .woocommerce-BlankState-message:before,.post-type-shop_order .woocommerce-BlankState-message:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}table.bar_chart tbody td.bars span.alt{clear:both;background:#47a03e}table.bar_chart tbody td.bars span.alt span{margin:0;color:#c5dec2!important;text-shadow:0 1px 0 #47a03e;background:0 0}.post-type-shop_order .woocommerce-BlankState-message:before{content:""}.post-type-shop_coupon .woocommerce-BlankState-message:before{content:""}.post-type-product .woocommerce-BlankState-message:before{content:""}.woocommerce-BlankState{text-align:center;padding:5em 0 0}.woocommerce-BlankState .woocommerce-BlankState-message{color:#aaa;margin:0 auto 1.5em;line-height:1.5em;font-size:1.2em;max-width:500px}.woocommerce-BlankState .woocommerce-BlankState-message:before{color:#ddd;text-shadow:0 -1px 1px rgba(0,0,0,.2),0 1px 0 rgba(255,255,255,.8);font-size:8em;display:block;position:relative!important;top:auto;left:auto;line-height:1em;margin:0 0 .1875em}.woocommerce-BlankState .woocommerce-BlankState-cta{font-size:1.2em;padding:.75em 1.5em;height:auto}@media only screen and (max-width:1280px){#order_data .order_data_column{width:48%}#order_data .order_data_column:first-child{width:100%}.woocommerce_options_panel .description{display:block;clear:both;margin-left:0}.woocommerce_options_panel .dimensions_field .wrap,.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:80%}.woocommerce_options_panel .downloadable_files,.woocommerce_variations .downloadable_files{padding:0;clear:both}.woocommerce_options_panel .downloadable_files label,.woocommerce_variations .downloadable_files label{position:static}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{margin:0 12px 24px;width:94%}.woocommerce_options_panel .downloadable_files table .sort,.woocommerce_variations .downloadable_files table .sort{visibility:hidden}.woocommerce_options_panel .woocommerce_variable_attributes .downloadable_files table,.woocommerce_variations .woocommerce_variable_attributes .downloadable_files table{margin:0 0 1em;width:100%}}@media only screen and (max-width:900px){#woocommerce-coupon-data ul.coupon_data_tabs,#woocommerce-product-data .wc-tabs-back,#woocommerce-product-data ul.product_data_tabs{width:10%}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{width:90%}#woocommerce-coupon-data ul.coupon_data_tabs li a,#woocommerce-product-data ul.product_data_tabs li a{position:relative;text-indent:-999px;padding:10px}#woocommerce-coupon-data ul.coupon_data_tabs li a:before,#woocommerce-product-data ul.product_data_tabs li a:before{position:absolute;top:0;right:0;bottom:0;left:0;text-indent:0;text-align:center;line-height:40px;width:100%;height:40px}}@media only screen and (max-width:782px){#wp-excerpt-media-buttons a{font-size:16px;line-height:37px;height:39px;padding:0 20px 0 15px}#wp-excerpt-editor-tools{padding-top:20px;padding-right:15px;overflow:hidden;margin-bottom:-1px}.post-type-product .wp-list-table .is-expanded td:not(.hidden),.post-type-shop_order .wp-list-table .is-expanded td:not(.hidden){overflow:visible}#woocommerce-product-data .checkbox{width:25px}.variations-pagenav{float:none;text-align:center;font-size:18px}.variations-pagenav .displaying-num{font-size:16px}.variations-pagenav a{padding:8px 20px 11px;font-size:18px}.variations-pagenav select{padding:0 20px}.variations-defaults{float:none;text-align:center;margin-top:10px}.post-type-product .wp-list-table .column-thumb{display:none;text-align:left;padding-bottom:0}.post-type-product .wp-list-table .column-thumb:before{display:none!important}.post-type-product .wp-list-table .column-thumb img{max-width:32px}.post-type-product .wp-list-table .toggle-row{top:-28px}.post-type-shop_order .wp-list-table .column-order_status{display:none;text-align:left;padding-bottom:0}.post-type-shop_order .wp-list-table .column-order_status mark{margin:0}.post-type-shop_order .wp-list-table .column-order_status:before{display:none!important}.post-type-shop_order .wp-list-table .column-customer_message,.post-type-shop_order .wp-list-table .column-order_notes{text-align:inherit}.post-type-shop_order .wp-list-table .column-order_notes .note-on{font-size:1.3em;margin:0}.post-type-shop_order .wp-list-table .toggle-row{top:-15px}}@media only screen and (max-width:500px){.woocommerce_options_panel label,.woocommerce_options_panel legend{float:none;width:auto;display:block;margin:0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px!important}}.wc-backbone-modal *{box-sizing:border-box}.wc-backbone-modal .wc-backbone-modal-content{position:fixed;background:#fff;z-index:100000;left:50%;top:50%;transform:translate(-50%,-50%);width:500px}.wc-backbone-modal .wc-backbone-modal-content article{overflow:auto}.wc-backbone-modal.wc-backbone-modal-shipping-method-settings .wc-backbone-modal-content{width:75%;min-width:500px}.wc-backbone-modal-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;min-height:360px;background:#000;opacity:.7;z-index:99900}.wc-backbone-modal-main{padding-bottom:55px}.wc-backbone-modal-main article,.wc-backbone-modal-main header{display:block;position:relative}.wc-backbone-modal-main .wc-backbone-modal-header{height:auto;background:#fcfcfc;padding:1em 1.5em;border-bottom:1px solid #ddd}.wc-backbone-modal-main .wc-backbone-modal-header h1{margin:0;font-size:18px;font-weight:700;line-height:1.5em}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link{cursor:pointer;color:#777;height:54px;width:54px;padding:0;position:absolute;top:0;right:0;text-align:center;border:0;border-left:1px solid #ddd;background-color:transparent;-webkit-transition:color .1s ease-in-out,background .1s ease-in-out;transition:color .1s ease-in-out,background .1s ease-in-out}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:before{font:400 22px/50px dashicons!important;color:#666;display:block;content:'\f335';font-weight:300}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus,.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:hover{background:#ddd;border-color:#ccc;color:#000}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus{outline:0}.wc-backbone-modal-main article{padding:1.5em}.wc-backbone-modal-main article p{margin:1.5em 0}.wc-backbone-modal-main article p:last-child,.wc-backbone-modal-main footer .inner .button{margin-bottom:0}.wc-backbone-modal-main article p:first-child{margin-top:0}.wc-backbone-modal-main article .pagination{padding:10px 0 0;text-align:center}.wc-backbone-modal-main footer{position:absolute;left:0;right:0;bottom:0;z-index:100;padding:1em 1.5em;background:#fcfcfc;border-top:1px solid #dfdfdf;box-shadow:0 -4px 4px -4px rgba(0,0,0,.1)}.wc-backbone-modal-main footer .inner{float:right;line-height:23px}.select2-drop{z-index:999999!important}.select2-container-multi .select2-choices .select2-search-field input{font-family:inherit;font-size:inherit;font-weight:inherit;padding:3px 5px}.select2-container{line-height:1.85em;font-size:14px} \ No newline at end of file +@charset "UTF-8";.button.wc-reload:after,.woocommerce-help-tip:after{speak:none;text-transform:none;-webkit-font-smoothing:antialiased}@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg)}}@-moz-keyframes spin{100%{-moz-transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}.select2-container{margin:0;position:relative;display:block!important;zoom:1;vertical-align:middle}.select2-container,.select2-drop,.select2-search,.select2-search input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{display:block;padding:0 0 0 8px;overflow:hidden;position:relative;border:1px solid #ccc;white-space:nowrap;color:#444;text-decoration:none;border-radius:3px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;font-weight:400}html[dir=rtl] .select2-container .select2-choice{padding:0 8px 0 0}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#ccc;border-radius:0 0 4px 4px}.select2-container.select2-allowclear .select2-choice .select2-chosen{margin-right:42px}.select2-container .select2-choice>.select2-chosen{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:none;width:auto}html[dir=rtl] .select2-container .select2-choice>.select2-chosen{margin-left:26px;margin-right:0}.select2-container .select2-choice abbr{display:none;width:12px;height:12px;position:absolute;right:24px;top:5px;font-size:1px;text-decoration:none;border:0;background:url(../images/select2.png) right top no-repeat;cursor:pointer;outline:0}.select2-container.select2-allowclear .select2-choice abbr{display:inline-block}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop-mask{border:0;margin:0;padding:0;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:9998;background-color:#fff;filter:alpha(opacity=0)}.select2-drop{width:100%;margin-top:-1px;position:absolute;top:100%;background:#fff;color:#000;border:1px solid #ccc;border-top:0;border-radius:0 0 3px 3px}.select2-drop.select2-drop-above{margin-top:1px;border-top:1px solid #ccc;border-bottom:0;border-radius:3px 3px 0 0}.select2-drop-active{border:1px solid #666;border-top:none}.select2-drop.select2-drop-above.select2-drop-active{border-top:1px solid #666}.select2-drop-auto-width{border-top:1px solid #ccc;width:auto}.select2-drop-auto-width .select2-search{padding-top:4px}.select2-container .select2-choice .select2-arrow{display:inline-block;width:18px;height:100%;position:absolute;right:0;top:0;border-radius:0 3px 3px 0;background-clip:padding-box}html[dir=rtl] .select2-container .select2-choice .select2-arrow{left:0;right:auto;border-radius:3px 0 0 3px}.select2-container .select2-choice .select2-arrow b{display:block;width:100%;height:100%;position:relative}.select2-container .select2-choice .select2-arrow b:after{position:absolute;display:block;content:"";top:50%;left:50%;border:4px solid transparent;border-top-color:#666;margin-left:-7px;margin-top:-2px}.select2-search{display:inline-block;width:100%;margin:0;padding-left:4px;padding-right:4px;position:relative;z-index:10000;white-space:nowrap;padding-bottom:4px}.select2-search input{width:100%;height:auto!important;padding:4px 20px 4px 5px!important;margin:0;outline:0;font-family:sans-serif;font-size:1em;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none;background:url(../images/select2.png) 100% -22px no-repeat #fff}html[dir=rtl] .select2-search input{padding:4px 5px 4px 20px;background:url(../images/select2.png) -37px -22px no-repeat #fff}.select2-drop.select2-drop-above .select2-search input{margin-top:4px}.select2-search input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff}.select2-container-active .select2-choice,.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-dropdown-open .select2-choice{border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-dropdown-open .select2-choice .select2-arrow b:after{border-top-color:transparent;border-bottom-color:#666;margin-top:-6px}.select2-dropdown-open.select2-drop-above .select2-choice,.select2-dropdown-open.select2-drop-above .select2-choices{border:1px solid #666;border-top-color:transparent}.select2-dropdown-open .select2-choice .select2-arrow{background:0 0;border-left:none;filter:none}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow{border-right:none}.select2-dropdown-open .select2-choice .select2-arrow b{background-position:-18px 1px}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow b{background-position:-16px 1px}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.select2-results{max-height:200px;padding:4px;margin:0;position:relative;overflow-x:hidden;overflow-y:auto;-webkit-tap-highlight-color:transparent;background:#fafafa}html[dir=rtl] .select2-results{padding:0 4px 0 0;margin:4px 0 4px 4px}.select2-results ul.select2-result-sub{margin:0;padding-left:0}.select2-results li{list-style:none;display:list-item;background-image:none;margin:3px 0}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:700}.select2-results .select2-result-label{padding:5px 7px;margin:0;cursor:pointer;min-height:1em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select2-results-dept-1 .select2-result-label{padding-left:20px}.select2-results-dept-2 .select2-result-label{padding-left:40px}.select2-results-dept-3 .select2-result-label{padding-left:60px}.select2-results-dept-4 .select2-result-label{padding-left:80px}.select2-results-dept-5 .select2-result-label{padding-left:100px}.select2-results-dept-6 .select2-result-label{padding-left:110px}.select2-results-dept-7 .select2-result-label{padding-left:120px}.select2-results .select2-highlighted{background:#f1f1f1;color:#000;border-radius:3px}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:0 0}.select2-results .select2-highlighted ul{background:#fff;color:#000}.select2-results .select2-ajax-error,.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item;padding-left:5px}.select2-results .select2-disabled.select2-highlighted{color:#666;background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-disabled{background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-selected{display:none}.select2-more-results.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #f4f4f4}.select2-results .select2-ajax-error{background:rgba(255,50,50,.2)}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice .select2-arrow{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container.select2-container-disabled .select2-choice abbr{display:none}.select2-container-multi .select2-choices{height:auto!important;height:1%;margin:0;padding:0 5px 0 0;position:relative;border:1px solid #ccc;cursor:text;overflow:hidden;background-color:#fff;min-height:26px}html[dir=rtl] .select2-container-multi .select2-choices{padding:0 0 0 5px}.select2-locked{padding:3px 5px!important}.select2-container-multi.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-container-multi .select2-choices li{float:left;list-style:none}html[dir=rtl] .select2-container-multi .select2-choices li{float:right}.select2-container-multi .select2-choices .select2-search-field{margin:0;padding:0;white-space:nowrap}.select2-container-multi .select2-choices .select2-search-field:first-child{width:100%}.select2-container-multi .select2-choices .select2-search-field input{margin:1px 0;outline:0;border:0;-webkit-box-shadow:none;box-shadow:none;background:0 0!important}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff!important}.select2-default{color:#999!important}.select2-container-multi .select2-choices .select2-search-choice{padding:5px 8px 5px 24px;margin:3px 0 3px 5px;position:relative;line-height:15px;color:#333;cursor:default;border-radius:2px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#e4e4e4}html[dir=rtl] .select2-container-multi .select2-choices .select2-search-choice{margin:3px 5px 3px 0;padding:5px 24px 5px 8px}.select2-container-multi .select2-choices .select2-search-choice .select2-chosen{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;width:12px;height:13px;position:absolute;right:7px;top:6px;font-size:1px;outline:0;background:url(../images/select2.png) right top no-repeat}html[dir=rtl] .select2-search-choice-close{right:auto;left:7px}.select2-container-multi .select2-search-choice-close{left:7px}html[dir=rtl] .select2-container-multi .select2-search-choice-close{left:auto;right:7px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover,.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{padding:3px 5px;border:1px solid #ddd;background-image:none;background-color:#f4f4f4}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none;background:0 0}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-match{text-decoration:underline}.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.select2-display-none{display:none}.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:2dppx){.select2-search input{background-image:url(../images/select2x2.png)!important;background-repeat:no-repeat!important;background-size:60px 40px!important;background-position:100% -21px!important}}@font-face{font-family:star;src:url(../fonts/star.eot);src:url(../fonts/star.eot?#iefix) format("embedded-opentype"),url(../fonts/star.woff) format("woff"),url(../fonts/star.ttf) format("truetype"),url(../fonts/star.svg#star) format("svg");font-weight:400;font-style:normal}@font-face{font-family:WooCommerce;src:url(../fonts/WooCommerce.eot);src:url(../fonts/WooCommerce.eot?#iefix) format("embedded-opentype"),url(../fonts/WooCommerce.woff) format("woff"),url(../fonts/WooCommerce.ttf) format("truetype"),url(../fonts/WooCommerce.svg#WooCommerce) format("svg");font-weight:400;font-style:normal}.blockUI.blockOverlay:before{height:1em;width:1em;position:absolute;top:50%;left:50%;margin-left:-.5em;margin-top:-.5em;display:block;content:"";-webkit-animation:spin 1s ease-in-out infinite;-moz-animation:spin 1s ease-in-out infinite;animation:spin 1s ease-in-out infinite;background:url(../images/icons/loader.svg) center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75)}.wc_addons_wrap .products{overflow:hidden}.wc_addons_wrap .products li{float:left;margin:0 1em 1em 0!important;padding:0;vertical-align:top;width:300px}.wc_addons_wrap .products li a{text-decoration:none;color:inherit;border:1px solid #ddd;display:block;min-height:220px;overflow:hidden;background:#f5f5f5;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1)}.wc_addons_wrap .products li a img{max-width:258px;max-height:24px;padding:17px 20px;display:block;margin:0;background:#fff;border-right:260px solid #fff}.wc_addons_wrap .products li a .price,.wc_addons_wrap .products li a img.extension-thumb+h3{display:none}.wc_addons_wrap .products li a h2,.wc_addons_wrap .products li a h3{margin:0!important;padding:20px!important;background:#fff}.wc_addons_wrap .products li a p{padding:20px!important;margin:0!important;border-top:1px solid #f1f1f1}.wc_addons_wrap .products li a:focus,.wc_addons_wrap .products li a:hover{background-color:#fff}.wc_addons_wrap .storefront{background:url(../images/storefront-bg.jpg) bottom right #f6f6f6;border:1px solid #ddd;padding:20px;overflow:hidden;zoom:1}.wc_addons_wrap .storefront img{width:278px;height:auto;float:left;margin:0 20px 0 0;box-shadow:0 1px 6px rgba(0,0,0,.1)}.wc_addons_wrap .storefront p{max-width:750px}.woocommerce-BlankState a.button-primary,.woocommerce-BlankState button.button-primary,.woocommerce-message a.button-primary,.woocommerce-message button.button-primary{background:#bb77ae;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;color:#fff;text-shadow:0 -1px 1px #A36597,1px 0 1px #A36597,0 1px 1px #A36597,-1px 0 1px #A36597}.woocommerce-BlankState a.button-primary:active,.woocommerce-BlankState a.button-primary:focus,.woocommerce-BlankState a.button-primary:hover,.woocommerce-BlankState button.button-primary:active,.woocommerce-BlankState button.button-primary:focus,.woocommerce-BlankState button.button-primary:hover,.woocommerce-message a.button-primary:active,.woocommerce-message a.button-primary:focus,.woocommerce-message a.button-primary:hover,.woocommerce-message button.button-primary:active,.woocommerce-message button.button-primary:focus,.woocommerce-message button.button-primary:hover{background:#A36597;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597}.woocommerce-message{position:relative;border-left-color:#cc99c2!important;overflow:hidden}.woocommerce-message a.docs,.woocommerce-message a.skip{text-decoration:none!important}.woocommerce-message a.woocommerce-message-close{position:absolute;top:10px;right:10px;padding:10px 15px 10px 21px;font-size:13px;line-height:1.23076923;text-decoration:none}.woocommerce-message a.woocommerce-message-close:before{position:absolute;top:8px;left:0;-webkit-transition:all .1s ease-in-out;transition:all .1s ease-in-out}.woocommerce-message .twitter-share-button{margin-top:-3px;margin-left:3px;vertical-align:middle}#variable_product_options #message,#variable_product_options .notice{margin:10px}.clear{clear:both}#woocommerce-fields-bulk.inline-edit-col label,#woocommerce-fields.inline-edit-col{clear:left}.wrap.woocommerce div.error,.wrap.woocommerce div.updated{margin-top:10px}mark.amount{background:0 0;color:inherit}.postbox,.woocommerce{input:invalid;input-border:1px solid #cc010b;input-background:#ffebe8}.simplify-commerce-banner{overflow:hidden}.simplify-commerce-banner img{float:right;padding:15px 0;margin-left:1em;width:200px}.woocommerce-help-tip{color:#666;display:inline-block;font-size:1.1em;font-style:normal;height:16px;line-height:16px;position:relative;vertical-align:middle;width:16px}.woocommerce-help-tip:after{font-family:Dashicons;font-weight:400;font-variant:normal;line-height:1;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";cursor:help}h2 .woocommerce-help-tip{margin-top:-5px;margin-left:.25em}table.wc_status_table{margin-bottom:1em}table.wc_status_table h2{font-size:14px;margin:0}table.wc_status_table tr:nth-child(2n) td,table.wc_status_table tr:nth-child(2n) th{background:#fcfcfc}table.wc_status_table th{font-weight:700;padding:9px}table.wc_status_table td:first-child{width:33%}table.wc_status_table td.help{width:1em}table.wc_status_table td{padding:9px;font-size:1.1em}table.wc_status_table td mark{background:0 0}table.wc_status_table td mark.yes{color:#7ad03a}table.wc_status_table td mark.no{color:#999}table.wc_status_table td mark.error{color:#a00}table.wc_status_table td ul{margin:0}table.wc_status_table .help_tip{cursor:help}#debug-report{display:none;margin:10px 0;padding:0;position:relative}#debug-report textarea{font-family:monospace;width:100%;margin:0;height:300px;padding:20px;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;resize:none;font-size:12px;line-height:20px;outline:0}#log-viewer-select{padding:10px 0 8px;line-height:180%}#log-viewer textarea{width:100%;resize:vertical}.inline-edit-product.quick-edit-row .inline-edit-col-center,.inline-edit-product.quick-edit-row .inline-edit-col-right{float:right!important}#woocommerce-fields.inline-edit-col label.featured,#woocommerce-fields.inline-edit-col label.manage_stock{margin-left:10px}#woocommerce-fields.inline-edit-col .dimensions div{display:block;margin:.2em 0}#woocommerce-fields.inline-edit-col .dimensions div span.title{display:block;float:left;width:5em}#woocommerce-fields.inline-edit-col .dimensions div span.input-text-wrap{display:block;margin-left:5em}#woocommerce-fields.inline-edit-col .text{box-sizing:border-box;width:99%;float:left;margin:1px 1% 1px 1px}#woocommerce-fields.inline-edit-col .height,#woocommerce-fields.inline-edit-col .length,#woocommerce-fields.inline-edit-col .width{width:32.33%}#woocommerce-fields.inline-edit-col .height{margin-right:0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group label{clear:none;width:49%;margin:.2em 0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group.dimensions label{width:75%;max-width:75%}#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .regular_price,#woocommerce-fields-bulk.inline-edit-col .sale_price,#woocommerce-fields-bulk.inline-edit-col .stock,#woocommerce-fields-bulk.inline-edit-col .weight{box-sizing:border-box;width:100%;margin-left:4.4em}#woocommerce-fields-bulk.inline-edit-col .height,#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .width{box-sizing:border-box;width:25%}.column-coupon_code{line-height:2.25em}.column-coupon_code,ul.wc_coupon_list{margin:0;overflow:hidden;zoom:1;clear:both}ul.wc_coupon_list li{margin:0}ul.wc_coupon_list li.code{display:inline-block}ul.wc_coupon_list li.code:after{content:", "}ul.wc_coupon_list li.code:last-of-type:after{display:none}ul.wc_coupon_list li.code .tips{cursor:pointer}ul.wc_coupon_list_block{margin:0;padding-bottom:2px}ul.wc_coupon_list_block li{border-top:1px solid #fff;border-bottom:1px solid #ccc;line-height:2.5em;margin:0;padding:.5em 0}ul.wc_coupon_list_block li:first-child{border-top:0;padding-top:0}ul.wc_coupon_list_block li:last-child{border-bottom:0;padding-bottom:0}.button.wc-reload{text-indent:-9999px;position:relative;padding:0;height:28px;width:28px!important;display:inline-block}.button.wc-reload:after{font-family:Dashicons;font-weight:400;font-variant:normal;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:28px}#order_data h2,#order_data p.order_number{font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif;font-weight:400}.tablenav .actions{overflow:visible}.tablenav .select2-container{float:left;max-width:200px;font-size:14px;vertical-align:middle;margin:1px 6px 1px 1px}#woocommerce-order-data .handlediv,#woocommerce-order-data .hndle{display:none}#woocommerce-order-data .inside{display:block!important}#order_data{padding:23px 24px 12px}#order_data h2{margin:0;font-size:21px;line-height:1.2;text-shadow:1px 1px 1px #fff;padding:0}#order_data h3{font-size:14px}#order_data h3,#order_data h4{color:#333;margin:1.33em 0 0}#order_data p{color:#777}#order_data p.order_number{margin:0;line-height:1.6em;font-size:16px}#order_data .order_data_column_container{clear:both}#order_data .order_data_column{width:32%;padding:0 2% 0 0;float:left}#order_data .order_data_column:last-child{padding-right:0}#order_data .order_data_column p{padding:0!important}#order_data .order_data_column .address strong{display:block}#order_data .order_data_column .form-field{float:left;width:48%;padding:0;margin:9px 0 0}#order_data .order_data_column .form-field label{display:block;padding:0 0 3px}#order_data .order_data_column .form-field input,#order_data .order_data_column .form-field select,#order_data .order_data_column .form-field textarea{width:100%}#order_data .order_data_column .form-field .select2-container{width:100%!important}#order_data .order_data_column .form-field .date-picker{width:50%}#order_data .order_data_column .form-field .hour,#order_data .order_data_column .form-field .minute{width:3.5em}#order_data .order_data_column .form-field small{display:block;margin:5px 0 0;color:#999}#order_data .order_data_column .form-field.last{float:right}#order_data .order_data_column .form-field-wide{width:100%;clear:both}#order_data .order_data_column .form-field-wide .wc-customer-search,#order_data .order_data_column .form-field-wide .wc-enhanced-select,#order_data .order_data_column .form-field-wide input,#order_data .order_data_column .form-field-wide select,#order_data .order_data_column .form-field-wide textarea{width:100%}#order_data .order_data_column p.none_set{color:#999}#order_data .order_data_column ._billing_address_1_field,#order_data .order_data_column ._billing_city_field,#order_data .order_data_column ._billing_country_field,#order_data .order_data_column ._billing_email_field,#order_data .order_data_column ._billing_first_name_field,#order_data .order_data_column ._shipping_address_1_field,#order_data .order_data_column ._shipping_city_field,#order_data .order_data_column ._shipping_country_field,#order_data .order_data_column ._shipping_first_name_field{float:left}#order_data .order_data_column ._billing_address_2_field,#order_data .order_data_column ._billing_last_name_field,#order_data .order_data_column ._billing_phone_field,#order_data .order_data_column ._billing_postcode_field,#order_data .order_data_column ._billing_state_field,#order_data .order_data_column ._shipping_address_2_field,#order_data .order_data_column ._shipping_last_name_field,#order_data .order_data_column ._shipping_postcode_field,#order_data .order_data_column ._shipping_state_field,#order_data .order_data_column .wc-customer-user label a,#order_data .order_data_column .wc-order-status label a{float:right}#order_data .order_data_column ._billing_company_field,#order_data .order_data_column ._shipping_company_field,#order_data .order_data_column ._transaction_id_field{clear:both;width:100%}#order_data .order_data_column ._billing_email_field{clear:left}#order_data .order_data_column div.edit_address{display:none;zoom:1;padding-right:1px}#order_data .order_data_column .billing-same-as-shipping,#order_data .order_data_column .load_customer_billing,#order_data .order_data_column .load_customer_shipping,#order_data .order_data_column a.edit_address{width:14px;height:0;padding:14px 0 0;margin:0 0 0 6px;overflow:hidden;position:relative;color:#999;border:0;float:right}#order_data .order_data_column .billing-same-as-shipping:focus,#order_data .order_data_column .billing-same-as-shipping:hover,#order_data .order_data_column .load_customer_billing:focus,#order_data .order_data_column .load_customer_billing:hover,#order_data .order_data_column .load_customer_shipping:focus,#order_data .order_data_column .load_customer_shipping:hover,#order_data .order_data_column a.edit_address:focus,#order_data .order_data_column a.edit_address:hover{color:#000}#order_data .order_data_column .billing-same-as-shipping:after,#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after,#order_data .order_data_column a.edit_address: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}#order_data .order_data_column .billing-same-as-shipping:after{content:"\e008"}#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after{content:"\e03a"}#order_data .order_data_column a.edit_address:after{font-family:Dashicons;content:"\f464"}.order_actions{margin:0;overflow:hidden;zoom:1}.order_actions li{border-top:1px solid #fff;border-bottom:1px solid #ddd;padding:6px 0;margin:0;line-height:1.6em;float:left;width:50%;text-align:center}.order_actions li a{float:none;text-align:center;text-decoration:underline}.order_actions li.wide{width:auto;float:none;clear:both;padding:6px;text-align:left;overflow:hidden}.order_actions li #delete-action{line-height:25px;vertical-align:middle;text-align:left;float:left}.order_actions li .save_order{float:right}.order_actions li#actions{overflow:hidden}.order_actions li#actions .button{width:24px;box-sizing:border-box;float:right}.order_actions li#actions select{width:225px;box-sizing:border-box;float:left}#woocommerce-order-items .inside{margin:0;padding:0;background:#fefefe}#woocommerce-order-items .wc-order-data-row{border-bottom:1px solid #DFDFDF;padding:1.5em 2em;background:#f8f8f8;line-height:2em;text-align:right}#woocommerce-order-items .wc-order-data-row:after,#woocommerce-order-items .wc-order-data-row:before{content:" ";display:table}#woocommerce-order-items .wc-order-data-row:after{clear:both}#woocommerce-order-items .wc-order-data-row p{margin:0;line-height:2em}#woocommerce-order-items .wc-order-data-row .wc-used-coupons{text-align:left}#woocommerce-order-items .wc-order-data-row .wc-used-coupons .tips{display:inline-block}#woocommerce-order-items .wc-order-add-item{background:#fff;vertical-align:top;border-top:none}#woocommerce-order-items .wc-order-add-item .add_item_id,#woocommerce-order-items .wc-order-add-item .select2-container{vertical-align:top}#woocommerce-order-items .wc-order-add-item .add_item_id .search-field input,#woocommerce-order-items .wc-order-add-item .select2-container .search-field input{min-width:100px}#woocommerce-order-items .wc-order-add-item .select2-container{width:400px!important;text-align:left}#woocommerce-order-items .wc-order-add-item .calculate-action,#woocommerce-order-items .wc-order-add-item .cancel-action,#woocommerce-order-items .wc-order-add-item .save-action{float:left;margin-right:2px}#woocommerce-order-items .wc-used-coupons{float:left;width:50%}#woocommerce-order-items .wc-order-totals{float:right;width:50%;margin:0;padding:0;text-align:right}#woocommerce-order-items .wc-order-totals .amount{font-weight:700}#woocommerce-order-items .wc-order-totals .label{vertical-align:top}#woocommerce-order-items .wc-order-totals .total{font-size:1em!important;width:10em;margin:0 0 0 .5em;box-sizing:border-box}#woocommerce-order-items .wc-order-totals .total input[type=text]{width:96%;float:right}#woocommerce-order-items .wc-order-totals .refunded-total{color:#a00}#woocommerce-order-items .refund-actions{margin-top:5px;padding-top:12px;border-top:1px solid #DFDFDF}#woocommerce-order-items .refund-actions .button{float:right;margin-left:4px}#woocommerce-order-items .refund-actions .cancel-action,#woocommerce-order-items .wc-order-item-bulk-edit .cancel-action{float:left;margin-left:0}#woocommerce-order-items .add_meta{margin-left:0!important}#woocommerce-order-items h3 small{color:#999}#woocommerce-order-items .amount{white-space:nowrap}#woocommerce-order-items .add-items .description{margin-right:10px}#woocommerce-order-items .add-items .button{float:left;margin-right:.25em}#woocommerce-order-items .add-items .button-primary{float:none;margin-right:0}#woocommerce-order-items .inside{display:block!important}#woocommerce-order-items .handlediv,#woocommerce-order-items .hndle{display:none}#woocommerce-order-items .woocommerce_order_items_wrapper{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items{width:100%;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th{text-align:left;padding:1em;font-weight:400;color:#999;background:#f8f8f8;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th.sortable{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th .wc-arrow{float:right;position:relative;margin-right:-1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td{padding:1.5em 1em 1em;text-align:left;line-height:1.5em;vertical-align:top;border-bottom:1px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td select{width:50%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{font-size:14px;padding:4px;color:#555}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr td{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected{background:#F5EBF3}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected td{border-color:#E6CCE1;opacity:.8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:last-child td{border-bottom:1px solid #dfdfdf}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:first-child td{border-top:8px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody#order_line_items tr:first-child td{border-top:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb{text-align:left;width:38px;padding-bottom:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail{width:38px;height:38px;border:2px solid #e8e8e8;background:#f8f8f8;color:#ccc;position:relative;font-size:21px;display:block;text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;height:100%;text-align:center;content:"";width:38px;line-height:38px;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail img{width:100%;height:100%;margin:0;padding:0;position:relative}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-sku,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-variation{display:block;margin-top:.5em;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item{min-width:200px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .center,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .variation-id{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class{text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label{white-space:nowrap;color:#999;font-size:.833em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label input{display:inline}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class input{width:70px;vertical-align:middle;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class select{width:85px;height:26px;vertical-align:middle;font-size:1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input{display:inline-block;background:#fff;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);margin:1px 0;min-width:80px;overflow:hidden;line-height:1em;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input{width:100%;box-sizing:border-box}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input label{font-size:.75em;padding:4px 6px 0;color:#555;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input{width:100%;box-sizing:border-box;border:0;box-shadow:none;margin:0;padding:0 6px 4px;color:#555;background:0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input::-webkit-input-placeholder{color:#ddd}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child{border-bottom:1px dashed #ddd;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child label{color:#ccc}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .view{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .edit{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes label{display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount{display:block;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{margin-right:.25em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input{text-align:center;width:50px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items span.subtotal{opacity:.5}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.tax_class,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.tax_class{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .calculated{border-color:#ae8ca2;border-style:dotted}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{margin:.5em 0 0;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{color:#ccc;top:0;left:0;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-align:center;font-family:WooCommerce}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr th{border:0;padding:0 4px .5em 0;line-height:1.5em;width:20%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td{padding:0 4px .5em 0;border:0;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input{width:100%;margin:0;position:relative;border-bottom:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .refund_by,ul.order_notes li p.meta .exact-date{border-bottom:1px dotted #999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td textarea{width:100%;height:4em;margin:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input:focus+textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input:focus+textarea{border-top-color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p{margin:0 0 .5em;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p:last-child{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method_name{width:100%;margin:0 0 .5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;float:right;font-size:14px;visibility:hidden;margin:3px -18px 0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:hover:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:hover:before{color:#a00}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax:hover .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax:hover .delete-order-tax{visibility:visible}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded{display:block;color:#a00;white-space:nowrap;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;width:100%;height:100%;text-align:center;content:"";position:relative;top:auto;left:auto;margin:-1px 4px 0 0;vertical-align:middle;line-height:1em}#woocommerce-order-items .wc-order-edit-line-item{padding-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions{width:44px;text-align:right;padding-left:0;vertical-align:middle}#woocommerce-order-items .wc-order-edit-line-item-actions a{color:#ccc;display:inline-block;cursor:pointer;padding:0 0 .5em;margin:0 0 0 12px;vertical-align:middle;text-decoration:none;line-height:16px;width:16px;overflow:hidden}#woocommerce-order-items .wc-order-edit-line-item-actions a:before{margin:0;padding:0;font-size:16px;width:16px;height:16px}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before,#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{font-family:Dashicons;-webkit-font-smoothing:antialiased;text-indent:0;top:0;left:0;width:100%;height:100%;margin:0;text-align:center;position:relative;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1}#woocommerce-order-items .wc-order-edit-line-item-actions a:hover:before{color:#999}#woocommerce-order-items .wc-order-edit-line-item-actions a:first-child{margin-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:hover:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:hover:before{color:#a00}#woocommerce-order-items tbody tr .wc-order-edit-line-item-actions{visibility:hidden}#woocommerce-order-items tbody tr:hover .wc-order-edit-line-item-actions{visibility:visible}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions{width:1.5em;visibility:visible!important}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions a{padding:0}#woocommerce-order-downloads .buttons{float:left;padding:0;margin:0;vertical-align:top}#woocommerce-order-downloads .buttons .add_item_id,#woocommerce-order-downloads .buttons .select2-container{width:400px!important;margin-right:9px;vertical-align:top;float:left}#woocommerce-order-downloads .buttons button{margin:2px 0 0}#woocommerce-order-downloads h3 small{color:#999}#poststuff #woocommerce-order-actions .inside{margin:0;padding:0}#poststuff #woocommerce-order-actions .inside ul.order_actions li{padding:6px 10px;box-sizing:border-box}#poststuff #woocommerce-order-actions .inside ul.order_actions li:last-child{border-bottom:0}#poststuff #woocommerce-order-notes .inside{margin:0;padding:0}#poststuff #woocommerce-order-notes .inside ul.order_notes li{padding:0 10px}#woocommerce_customers p.search-box{margin:6px 0 4px;float:left}#woocommerce_customers .tablenav{float:right;clear:none}.widefat.customers td{vertical-align:middle;padding:4px 7px}.widefat .column-order_title{width:15%}.widefat .column-order_title time{display:block;color:#999;margin:3px 0}.widefat .column-orders,.widefat .column-paying,.widefat .column-spent{text-align:center;width:8%}.widefat .column-last_order{width:11%}.widefat .column-order_actions,.widefat .column-user_actions,.widefat .column-wc_actions{width:110px}.widefat .column-order_actions a.button,.widefat .column-user_actions a.button,.widefat .column-wc_actions a.button{float:left;margin:0 4px 2px 0;cursor:pointer;padding:3px 4px;height:auto}.widefat .column-order_actions a.button img,.widefat .column-user_actions a.button img,.widefat .column-wc_actions a.button img{display:block;width:12px;height:auto}.widefat small.meta{display:block;color:#999;font-size:inherit;margin:3px 0}.widefat .column-order_date,.widefat .column-order_total{width:9%}.widefat .column-order_status{width:45px;text-align:center}.widefat .column-order_status mark{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;background:0 0;font-size:1.4em;margin:0 auto}.widefat .column-order_status mark.cancelled:after,.widefat .column-order_status mark.completed:after,.widefat .column-order_status mark.failed:after,.widefat .column-order_status mark.on-hold:after,.widefat .column-order_status mark.pending:after,.widefat .column-order_status mark.processing:after,.widefat .column-order_status mark.refunded:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.column-customer_message .note-on:after,.column-order_notes .note-on:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;left:0;text-align:center;line-height:16px;font-family:WooCommerce}.widefat .column-order_status mark.pending:after{content:"\e012";color:#ffba00}.widefat .column-order_status mark.completed:after{content:"\e015";color:#2ea2cc}.widefat .column-order_status mark.on-hold:after{content:"\e033";color:#999}.widefat .column-order_status mark.failed:after{content:"\e016";color:#d0c21f}.widefat .column-order_status mark.cancelled:after{content:"\e013";color:#a00}.widefat .column-order_status mark.processing:after{content:"\e011";color:#73a724}.widefat .column-order_status mark.refunded:after{content:"\e014";color:#999}.widefat td.column-order_status{padding-top:9px}.column-customer_message .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-customer_message .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.column-order_notes .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-order_notes .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.order_actions .complete,.order_actions .processing,.order_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.order_actions .processing:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.order_actions .complete:after,.order_actions .view:after{font-family:Dashicons;text-indent:0;position:absolute;width:100%;height:100%;left:0;line-height:1.85;margin:0;text-align:center;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;font-weight:400}.order_actions .complete:after{content:""}.order_actions .view:after{content:""}.user_actions .edit,.user_actions .link,.user_actions .refresh,.user_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.user_actions .edit:after,.user_actions .link:after,.user_actions .refresh:after,.user_actions .view:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.user_actions .edit:after{font-family:Dashicons;content:"\f464"}.user_actions .link:after{content:"\e00d"}.user_actions .view:after{content:"\e010"}.user_actions .refresh:after{content:"\e031"}.attributes-table td,.attributes-table th{width:15%;vertical-align:top}.attributes-table .attribute-terms{width:32%}.attributes-table .attribute-actions{width:2em}.attributes-table .attribute-actions .configure-terms{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.attributes-table .attribute-actions .configure-terms:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}ul.order_notes{padding:2px 0 0}ul.order_notes li .note_content{padding:10px;background:#efefef;position:relative}ul.order_notes li .note_content p{margin:0;padding:0;word-wrap:break-word}ul.order_notes li p.meta{padding:10px;color:#999;margin:0;font-size:11px}ul.order_notes li a.delete_note{color:#a00}table.wp-list-table .row-actions,table.wp-list-table span.na{color:#999}ul.order_notes li .note_content:after{content:"";display:block;position:absolute;bottom:-10px;left:20px;width:0;height:0;border-width:10px 10px 0 0;border-style:solid;border-color:#efefef transparent}ul.order_notes li.customer-note .note_content{background:#A7CEDC}ul.order_notes li.customer-note .note_content:after{border-color:#A7CEDC transparent}ul.order_notes li.system-note .note_content{background:#d7cad2}ul.order_notes li.system-note .note_content:after{border-color:#d7cad2 transparent}.add_note{border-top:1px solid #ddd;padding:10px 10px 0}.add_note h4{margin-top:5px!important}.add_note #add_order_note{width:100%;height:50px}table.wp-list-table .column-thumb{width:52px;text-align:center;white-space:nowrap}table.wp-list-table .column-name{width:22%}table.wp-list-table .column-product_cat,table.wp-list-table .column-product_tag{width:11%!important}table.wp-list-table .column-featured,table.wp-list-table .column-product_type{width:48px;text-align:left!important}table.wp-list-table .column-customer_message,table.wp-list-table .column-order_notes{width:48px;text-align:center}table.wp-list-table .column-customer_message img,table.wp-list-table .column-order_notes img{margin:0 auto;padding-top:0!important}table.wp-list-table .manage-column.column-featured img,table.wp-list-table .manage-column.column-product_type img{padding-left:2px}table.wp-list-table .column-price .woocommerce-price-suffix{display:none}table.wp-list-table img{margin:1px 2px}table.wp-list-table td.column-thumb img{margin:0;width:auto;height:auto;max-width:40px;max-height:40px;vertical-align:middle}table.wp-list-table .column-is_in_stock{text-align:left!important}table.wp-list-table span.wc-featured,table.wp-list-table span.wc-image,table.wp-list-table span.wc-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table span.wc-featured:before,table.wp-list-table span.wc-image:before,table.wp-list-table span.wc-type:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:""}table.wp-list-table span.wc-featured{margin:0;cursor:pointer}table.wp-list-table span.wc-featured:before{content:"\f155"}table.wp-list-table span.wc-featured.not-featured:before{content:"\f154"}table.wp-list-table td.column-featured span.wc-featured{font-size:1.6em}table.wp-list-table span.wc-type{margin:0}table.wp-list-table span.wc-type:before{font-family:WooCommerce;content:"\e006"}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after,table.wp-list-table span.product-type:before{font-family:WooCommerce;text-align:center;line-height:1;top:0;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;left:0}table.wp-list-table span.product-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.6em}table.wp-list-table span.product-type:before{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}table.wp-list-table span.product-type.grouped:before{content:"\e002"}table.wp-list-table span.product-type.external:before{content:"\e034"}table.wp-list-table span.product-type.variable:before{content:"\e003"}table.wp-list-table span.product-type.downloadable:before{content:"\e001"}table.wp-list-table span.product-type.virtual:before{content:"\e000"}table.wp-list-table mark.instock{font-weight:700;color:#7ad03a;background:0 0;line-height:1}table.wp-list-table mark.outofstock{font-weight:700;color:#a44;background:0 0;line-height:1}table.wp-list-table .notes_head,table.wp-list-table .order-notes_head,table.wp-list-table .status_head{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%}table.wc_emails .wc-email-settings-table-name,table.wc_emails td.name,table.wc_gateways .wc-email-settings-table-name,table.wc_gateways td.name,table.wc_shipping .wc-email-settings-table-name,table.wc_shipping td.name{font-weight:700}table.wp-list-table .order-notes_head:after{content:"\e028"}table.wp-list-table .notes_head:after{content:"\e026"}table.wp-list-table .status_head:after{content:"\e011"}table.wp-list-table .column-order_items{width:12%}table.wp-list-table .column-order_items table.order_items{width:100%;margin:3px 0 0;padding:0;display:none}table.wp-list-table .column-order_items table.order_items td{border:0;margin:0;padding:0 0 3px}table.wp-list-table .column-order_items table.order_items td.qty{color:#999;padding-right:6px;text-align:left}mark.notice{background:#fff;color:#a00;margin:0 0 0 10px}a.export_rates,a.import_rates{float:right;margin-left:9px;margin-top:-2px;margin-bottom:0}#rates-search{float:right}#rates-search input.wc-tax-rates-search-field{padding:4px 8px;font-size:1.2em}#rates-pagination{float:right;margin-right:.5em}#rates-pagination .tablenav{margin:0}table.wc_input_table,table.wc_tax_rates{width:100%}table.wc_input_table span.tips,table.wc_tax_rates span.tips{color:#2ea2cc}table.wc_input_table td,table.wc_tax_rates td{padding:0;border-right:1px solid #DFDFDF;border-bottom:1px solid #DFDFDF;border-top:0;background:#fff}table.wc_input_table td input[type=text],table.wc_input_table td input[type=number],table.wc_tax_rates td input[type=text],table.wc_tax_rates td input[type=number]{width:100%;padding:5px 7px;margin:0;border:0;background:0 0}table.wc_input_table td.apply_to_shipping,table.wc_input_table td.compound,table.wc_tax_rates td.apply_to_shipping,table.wc_tax_rates td.compound{padding:5px 7px;vertical-align:middle}table.wc_input_table td.apply_to_shipping input,table.wc_input_table td.compound input,table.wc_tax_rates td.apply_to_shipping input,table.wc_tax_rates td.compound input{width:auto;padding:0}table.wc_input_table td:last-child,table.wc_tax_rates td:last-child{border-right:0}table.wc_input_table tr.current td,table.wc_tax_rates tr.current td{background-color:#fefbcc}table.wc_input_table .cost,table.wc_input_table .cost input,table.wc_input_table .item_cost,table.wc_input_table .item_cost input,table.wc_tax_rates .cost,table.wc_tax_rates .cost input,table.wc_tax_rates .item_cost,table.wc_tax_rates .item_cost input{text-align:right}table.wc_input_table th.sort,table.wc_tax_rates th.sort{width:17px;padding:0 4px}table.wc_input_table td.sort,table.wc_tax_rates td.sort{padding:0 4px}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort{cursor:move;font-size:15px;background:#f9f9f9;text-align:center;vertical-align:middle}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before{color:#333}table.wc_input_table .button,table.wc_tax_rates .button{float:left;margin-right:5px}table.wc_input_table .export,table.wc_input_table .import,table.wc_tax_rates .export,table.wc_tax_rates .import{float:right;margin-right:0;margin-left:5px}table.wc_input_table span.tips,table.wc_tax_rates span.tips{padding:0 3px}table.wc_input_table .pagination,table.wc_tax_rates .pagination{float:right}table.wc_input_table .pagination .button,table.wc_tax_rates .pagination .button{margin-left:5px;margin-right:0}table.wc_input_table .pagination .current,table.wc_tax_rates .pagination .current{background:#bbb;text-shadow:none}table.wc_input_table tfoot th,table.wc_tax_rates tfoot th{padding-left:20px;padding-right:20px}table.wc_input_table tr:last-child td,table.wc_tax_rates tr:last-child td{border-bottom:0}table.wc_emails,table.wc_gateways,table.wc_shipping{position:relative}table.wc_emails td,table.wc_gateways td,table.wc_shipping td{vertical-align:middle;padding:7px;line-height:2em}table.wc_emails tr:nth-child(odd) td,table.wc_gateways tr:nth-child(odd) td,table.wc_shipping tr:nth-child(odd) td{background:#f9f9f9}table.wc_emails th,table.wc_gateways th,table.wc_shipping th{padding:9px 7px!important;vertical-align:middle}table.wc_emails .settings,table.wc_gateways .settings,table.wc_shipping .settings{text-align:right}table.wc_emails .default,table.wc_emails .radio,table.wc_emails .status,table.wc_gateways .default,table.wc_gateways .radio,table.wc_gateways .status,table.wc_shipping .default,table.wc_shipping .radio,table.wc_shipping .status{text-align:center}table.wc_emails .default .tips,table.wc_emails .radio .tips,table.wc_emails .status .tips,table.wc_gateways .default .tips,table.wc_gateways .radio .tips,table.wc_gateways .status .tips,table.wc_shipping .default .tips,table.wc_shipping .radio .tips,table.wc_shipping .status .tips{margin:0 auto}table.wc_emails .default input,table.wc_emails .radio input,table.wc_emails .status input,table.wc_gateways .default input,table.wc_gateways .radio input,table.wc_gateways .status input,table.wc_shipping .default input,table.wc_shipping .radio input,table.wc_shipping .status input{margin:0}table.wc_emails th.sort,table.wc_gateways th.sort,table.wc_shipping th.sort{width:28px;padding:0}table.wc_emails td.sort,table.wc_gateways td.sort,table.wc_shipping td.sort{padding:0 7px;cursor:move;font-size:15px;text-align:center;vertical-align:middle}table.wc_emails td.sort:before,table.wc_gateways td.sort:before,table.wc_shipping td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_emails .wc-email-settings-table-name span,table.wc_gateways .wc-email-settings-table-name span,table.wc_shipping .wc-email-settings-table-name span{font-weight:400;color:#999;margin:0 0 0 4px!important}table.wc_emails .wc-email-settings-table-status,table.wc_gateways .wc-email-settings-table-status,table.wc_shipping .wc-email-settings-table-status{text-align:center;width:1em}table.wc_emails .wc-email-settings-table-status .tips,table.wc_gateways .wc-email-settings-table-status .tips,table.wc_shipping .wc-email-settings-table-status .tips{margin:0 auto}table.wc_emails .wc-email-settings-table-actions a,table.wc_gateways .wc-email-settings-table-actions a,table.wc_shipping .wc-email-settings-table-actions a{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}table.wc_emails .wc-email-settings-table-actions a:after,table.wc_gateways .wc-email-settings-table-actions a:after,table.wc_shipping .wc-email-settings-table-actions a:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}table.wc-shipping-classes td,table.wc-shipping-classes th,table.wc-shipping-zone-methods td,table.wc-shipping-zone-methods th,table.wc-shipping-zones td,table.wc-shipping-zones th{vertical-align:top;line-height:24px;padding:1em;font-size:14px;background:#fff}table.wc-shipping-classes td li,table.wc-shipping-classes th li,table.wc-shipping-zone-methods td li,table.wc-shipping-zone-methods th li,table.wc-shipping-zones td li,table.wc-shipping-zones th li{line-height:24px;font-size:14px}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state,table.wc-shipping-classes td.wc-shipping-zones-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state,table.wc-shipping-zones td.wc-shipping-zones-blank-state{background:#F7F1F6!important;overflow:hidden;position:relative;padding:7.5em 7.5%;border-bottom:2px solid #EEE2EC}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zones td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state p{color:#a46497;font-size:1.5em;line-height:1.5em;margin:0 0 1em;position:relative;z-index:1;text-shadow:1px 1px 1px #fff}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state p.main{font-size:2em}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state li{margin-left:1em;list-style:circle inside}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-classes td.wc-shipping-zones-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state:before,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zones td.wc-shipping-zones-blank-state:before{content:"\e01b";font-family:WooCommerce;text-align:center;line-height:1;color:#EEE2EC;display:block;width:1em;font-size:40em;top:50%;right:-3.75%;margin-top:-.1875em;position:absolute}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-classes td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zones-blank-state .button-primary{background-color:#804877;border-color:#804877;-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);margin:0;opacity:1;text-shadow:0 -1px 1px #8a4f7f,1px 0 1px #8a4f7f,0 1px 1px #8a4f7f,-1px 0 1px #8a4f7f;font-size:1.5em;padding:.75em 1em;height:auto;position:relative;z-index:1}table.wc-shipping-classes .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-classes .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-classes tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-classes tr.odd td,table.wc-shipping-zone-methods .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tr.odd td,table.wc-shipping-zones .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zones .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zones tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zones tr.odd td{background:#f9f9f9}table.wc-shipping-classes p,table.wc-shipping-classes ul,table.wc-shipping-zone-methods p,table.wc-shipping-zone-methods ul,table.wc-shipping-zones p,table.wc-shipping-zones ul{margin:0}table.wc-shipping-classes td.wc-shipping-zone-method-sort,table.wc-shipping-classes td.wc-shipping-zone-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-sort,table.wc-shipping-zones td.wc-shipping-zone-method-sort,table.wc-shipping-zones td.wc-shipping-zone-sort{cursor:move;font-size:15px;text-align:center}table.wc-shipping-classes td.wc-shipping-zone-method-sort:before,table.wc-shipping-classes td.wc-shipping-zone-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:before,table.wc-shipping-zones td.wc-shipping-zone-sort:before{content:"\f333";font-family:Dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-classes td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-sort:hover:before{color:#333}table.wc-shipping-classes td.wc-shipping-zone-worldwide,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide,table.wc-shipping-zones td.wc-shipping-zone-worldwide{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-worldwide:before,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide:before,table.wc-shipping-zones td.wc-shipping-zone-worldwide:before{content:"\f319";font-family:dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes .wc-shipping-zone-methods,table.wc-shipping-classes .wc-shipping-zone-name,table.wc-shipping-zone-methods .wc-shipping-zone-methods,table.wc-shipping-zone-methods .wc-shipping-zone-name,table.wc-shipping-zones .wc-shipping-zone-methods,table.wc-shipping-zones .wc-shipping-zone-name{width:25%}table.wc-shipping-classes .wc-shipping-class-description input,table.wc-shipping-classes .wc-shipping-class-description select,table.wc-shipping-classes .wc-shipping-class-description textarea,table.wc-shipping-classes .wc-shipping-class-name input,table.wc-shipping-classes .wc-shipping-class-name select,table.wc-shipping-classes .wc-shipping-class-name textarea,table.wc-shipping-classes .wc-shipping-class-slug input,table.wc-shipping-classes .wc-shipping-class-slug select,table.wc-shipping-classes .wc-shipping-class-slug textarea,table.wc-shipping-classes .wc-shipping-zone-name input,table.wc-shipping-classes .wc-shipping-zone-name select,table.wc-shipping-classes .wc-shipping-zone-name textarea,table.wc-shipping-classes .wc-shipping-zone-region input,table.wc-shipping-classes .wc-shipping-zone-region select,table.wc-shipping-classes .wc-shipping-zone-region textarea,table.wc-shipping-zone-methods .wc-shipping-class-description input,table.wc-shipping-zone-methods .wc-shipping-class-description select,table.wc-shipping-zone-methods .wc-shipping-class-description textarea,table.wc-shipping-zone-methods .wc-shipping-class-name input,table.wc-shipping-zone-methods .wc-shipping-class-name select,table.wc-shipping-zone-methods .wc-shipping-class-name textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug input,table.wc-shipping-zone-methods .wc-shipping-class-slug select,table.wc-shipping-zone-methods .wc-shipping-class-slug textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name input,table.wc-shipping-zone-methods .wc-shipping-zone-name select,table.wc-shipping-zone-methods .wc-shipping-zone-name textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region input,table.wc-shipping-zone-methods .wc-shipping-zone-region select,table.wc-shipping-zone-methods .wc-shipping-zone-region textarea,table.wc-shipping-zones .wc-shipping-class-description input,table.wc-shipping-zones .wc-shipping-class-description select,table.wc-shipping-zones .wc-shipping-class-description textarea,table.wc-shipping-zones .wc-shipping-class-name input,table.wc-shipping-zones .wc-shipping-class-name select,table.wc-shipping-zones .wc-shipping-class-name textarea,table.wc-shipping-zones .wc-shipping-class-slug input,table.wc-shipping-zones .wc-shipping-class-slug select,table.wc-shipping-zones .wc-shipping-class-slug textarea,table.wc-shipping-zones .wc-shipping-zone-name input,table.wc-shipping-zones .wc-shipping-zone-name select,table.wc-shipping-zones .wc-shipping-zone-name textarea,table.wc-shipping-zones .wc-shipping-zone-region input,table.wc-shipping-zones .wc-shipping-zone-region select,table.wc-shipping-zones .wc-shipping-zone-region textarea{width:100%}table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-zone-delete{color:red}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle{float:right;margin:0;font-size:.9em;text-decoration:underline}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes{display:none}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea{margin-top:1em}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes .description{font-size:.9em;color:#999}table.wc-shipping-classes .wc-shipping-class-count,table.wc-shipping-zone-methods .wc-shipping-class-count,table.wc-shipping-zones .wc-shipping-class-count{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-methods,table.wc-shipping-zone-methods td.wc-shipping-zone-methods,table.wc-shipping-zones td.wc-shipping-zone-methods{color:#999}table.wc-shipping-classes td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .method_disabled{text-decoration:line-through}table.wc-shipping-classes td.wc-shipping-zone-methods ul,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul,table.wc-shipping-zones td.wc-shipping-zone-methods ul{color:#999;position:relative;padding-right:32px}table.wc-shipping-classes td.wc-shipping-zone-methods ul li,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li,table.wc-shipping-zones td.wc-shipping-zone-methods ul li{display:inline;margin:0}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:before{content:", "}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-classes td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:nth-child(2):before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:nth-child(2):before{content:""}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child{display:block}table.wc-shipping-classes td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zones td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row{position:absolute;right:0;top:0}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method{display:block;width:24px;padding:24px 0 0;height:0;overflow:hidden;cursor:pointer}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method:before{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;font-family:Dashicons;content:"\f502";color:#999;vertical-align:middle;line-height:24px;font-size:16px;margin:0}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled:before{line-height:inherit}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled{margin-top:1px;display:inline-block}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled{cursor:not-allowed}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled:before{color:#ccc}table.wc-shipping-classes .wc-shipping-zone-method-title,table.wc-shipping-zone-methods .wc-shipping-zone-method-title,table.wc-shipping-zones .wc-shipping-zone-method-title{width:33%}table.wc-shipping-classes .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zone-methods .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zones .wc-shipping-zone-method-title .wc-shipping-zone-method-delete{color:red}table.wc-shipping-classes .wc-shipping-zone-method-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled{text-align:center}table.wc-shipping-classes tfoot input,table.wc-shipping-classes tfoot select,table.wc-shipping-zone-methods tfoot input,table.wc-shipping-zone-methods tfoot select,table.wc-shipping-zones tfoot input,table.wc-shipping-zones tfoot select{vertical-align:middle!important}table.wc-shipping-classes tfoot .button-secondary,table.wc-shipping-zone-methods tfoot .button-secondary,table.wc-shipping-zones tfoot .button-secondary{float:right}table.wc-shipping-classes .editing .wc-shipping-zone-edit,table.wc-shipping-classes .editing .wc-shipping-zone-view,table.wc-shipping-zone-methods .editing .wc-shipping-zone-edit,table.wc-shipping-zone-methods .editing .wc-shipping-zone-view,table.wc-shipping-zones .editing .wc-shipping-zone-edit,table.wc-shipping-zones .editing .wc-shipping-zone-view{display:none}.wc-modal-shipping-method-settings{background:#f8f8f8;padding:1em!important}.wc-modal-shipping-method-settings form .form-table{width:100%;background:#fff;margin:0 0 1.5em}.wc-modal-shipping-method-settings form .form-table tr th{width:30%;position:relative}.wc-modal-shipping-method-settings form .form-table tr th .woocommerce-help-tip{float:right;margin:-8px -.5em 0 0;vertical-align:middle;right:0;top:50%;position:absolute}.wc-modal-shipping-method-settings form .form-table tr td input,.wc-modal-shipping-method-settings form .form-table tr td select,.wc-modal-shipping-method-settings form .form-table tr td textarea{width:50%;min-width:250px}.wc-modal-shipping-method-settings form .form-table tr td input[type=checkbox]{width:auto;min-width:16px}.wc-modal-shipping-method-settings form .form-table tr td,.wc-modal-shipping-method-settings form .form-table tr th{vertical-align:middle;margin:0;line-height:24px;padding:1em;border-bottom:1px solid #f8f8f8}.wc-modal-shipping-method-settings form .form-table:last-of-type{margin-bottom:0}.wc-backbone-modal .wc-shipping-zone-method-selector p{margin-top:0}.wc-backbone-modal .wc-shipping-zone-method-selector .wc-shipping-zone-method-description{margin:.75em 1px 0;line-height:1.5em;color:#999;font-style:italic}.wc-backbone-modal .wc-shipping-zone-method-selector select{width:100%;cursor:pointer}img.help_tip{margin:0 0 0 9px;vertical-align:middle}.postbox img.help_tip{margin-top:0}.postbox .woocommerce-help-tip{margin:0 0 0 9px}.status-disabled,.status-enabled,.status-manual{font-size:1.4em;display:block;text-indent:-9999px;position:relative;height:1em;width:1em}.status-disabled:before,.status-enabled:before,.status-manual:before{font-family:WooCommerce;line-height:1;margin:0;position:absolute;width:100%;height:100%;text-indent:0;top:0;font-variant:normal;-webkit-font-smoothing:antialiased;font-weight:400;text-align:center;left:0;speak:none;text-transform:none}.status-manual:before{content:"";color:#999}.status-enabled:before{content:"";color:#a46497}.status-disabled:before{content:"";color:#ccc}.woocommerce h2.woo-nav-tab-wrapper{margin-bottom:1em}.woocommerce nav.woo-nav-tab-wrapper{margin:1.5em 0 1em;border-bottom:1px solid #ccc}.woocommerce .subsubsub{margin:-8px 0 0}.woocommerce .wc-admin-breadcrumb{margin-left:.5em}.woocommerce .wc-admin-breadcrumb a{color:#a46497}.woocommerce #template div{margin:0}.woocommerce #template div p .button{float:right;margin-left:10px;margin-top:-4px}.woocommerce #template div .editor textarea{margin-bottom:8px}.woocommerce textarea[disabled=disabled]{background:#DFDFDF!important}.woocommerce table.form-table{margin:0;position:relative}.woocommerce table.form-table .forminp-radio ul{margin:0}.woocommerce table.form-table .forminp-radio ul li{line-height:1.4em}.woocommerce table.form-table textarea.input-text{height:100%;min-width:150px;display:block}.woocommerce table.form-table input.regular-input{width:25em}.woocommerce table.form-table textarea.wide-input{width:100%}.woocommerce table.form-table .woocommerce-help-tip,.woocommerce table.form-table img.help_tip{padding:0;margin:-4px 0 0 5px;vertical-align:middle;cursor:help;line-height:1}.woocommerce table.form-table span.help_tip{cursor:help;color:#2ea2cc}.woocommerce table.form-table th{position:relative;padding-right:24px}.woocommerce table.form-table .select2-container{display:block;max-width:350px;vertical-align:top;margin-bottom:3px}.woocommerce table.form-table table.widefat th{padding-right:inherit}.woocommerce table.form-table th .woocommerce-help-tip,.woocommerce table.form-table th img.help_tip{margin:0 -24px 0 0;float:right}.woocommerce table.form-table .wp-list-table .woocommerce-help-tip{float:none}.woocommerce table.form-table fieldset{margin-top:4px}.woocommerce table.form-table fieldset .woocommerce-help-tip,.woocommerce table.form-table fieldset img.help_tip{margin:-3px 0 0 5px}.woocommerce table.form-table fieldset p.description{margin-bottom:8px}.woocommerce table.form-table fieldset:first-child{margin-top:0}.woocommerce table.form-table .iris-picker{z-index:100;display:none;position:absolute;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,.2)}.woocommerce table.form-table .iris-picker .ui-slider{border:0!important;margin:0!important;width:auto!important;height:auto!important;background:none!important}.woocommerce table.form-table .iris-picker .ui-slider .ui-slider-handle{margin-bottom:0!important}.woocommerce table.form-table .colorpickpreview{padding:3px 3px 3px 20px;border:1px solid #ddd;border-right:0}.woocommerce table.form-table .colorpick{border-left:0}.woocommerce table.form-table .image_width_settings{vertical-align:middle}.woocommerce table.form-table .image_width_settings label{margin-left:10px}.woocommerce table.form-table .wc_emails_wrapper{padding:0 15px 10px 0}.woocommerce #tabs-wrap table a.remove{margin-left:4px}.woocommerce #tabs-wrap table p{margin:0 0 4px!important;overflow:hidden;zoom:1}.woocommerce #tabs-wrap table p a.add{float:left}#wp-excerpt-editor-container{background:#fff}#product_variation-parent #parent_id{width:100%}#postimagediv img{border:1px solid #d5d5d5;max-width:100%}#woocommerce-product-images .inside{margin:0;padding:0}#woocommerce-product-images .inside .add_product_images{padding:0 12px 12px}#woocommerce-product-images .inside #product_images_container{padding:0 0 0 9px}#woocommerce-product-images .inside #product_images_container ul{margin:0;padding:0}#woocommerce-product-images .inside #product_images_container ul:after,#woocommerce-product-images .inside #product_images_container ul:before{content:" ";display:table}#woocommerce-product-images .inside #product_images_container ul:after{clear:both}#woocommerce-product-images .inside #product_images_container ul li.add,#woocommerce-product-images .inside #product_images_container ul li.image,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{width:80px;float:left;cursor:move;border:1px solid #d5d5d5;margin:9px 9px 0 0;background:#f7f7f7;border-radius:2px;position:relative;box-sizing:border-box}#woocommerce-product-images .inside #product_images_container ul li.add img,#woocommerce-product-images .inside #product_images_container ul li.image img,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder img{width:100%;height:auto;display:block}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{border:3px dashed #ddd;position:relative}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-size:2.618em;line-height:72px;color:#ddd}#woocommerce-product-images .inside #product_images_container ul ul.actions{position:absolute;top:-8px;right:-8px;padding:2px;display:none}#woocommerce-product-images .inside #product_images_container ul ul.actions li{float:right;margin:0 0 0 2px}#woocommerce-product-images .inside #product_images_container ul ul.actions li a{width:1em;margin:0;height:0;display:block;overflow:hidden}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.tips{cursor:pointer}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.4em}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:hover:before{color:#a00}#woocommerce-product-images .inside #product_images_container ul li:hover ul.actions{display:block}#woocommerce-product-data .hndle{padding:10px}#woocommerce-product-data .hndle span{display:block;vertical-align:middle;line-height:24px}#woocommerce-product-data .hndle span span{display:inline;line-height:inherit;vertical-align:baseline}#woocommerce-product-data .hndle label{padding-right:1em;font-size:12px;vertical-align:baseline}#woocommerce-product-data .hndle label:first-child{margin-right:1em;border-right:1px solid #dfdfdf}#woocommerce-product-data .hndle input,#woocommerce-product-data .hndle select{margin:-3px 0 0 .5em;vertical-align:middle}#woocommerce-product-data>.handlediv{margin-top:4px}#woocommerce-product-data .wrap{margin:0}#woocommerce-coupon-description{padding:3px 8px;font-size:1.7em;line-height:1.42em;height:auto;width:100%;outline:0;margin:10px 0;display:block}#woocommerce-coupon-description::-webkit-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description::-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-ms-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap{background:#fff}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{float:left;width:80%}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-product-data .woocommerce_options_panel .wc-radios{display:block;float:left;margin:0}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-product-data .woocommerce_options_panel .wc-radios li{display:block;padding:0 0 10px}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li input,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-product-data .woocommerce_options_panel .wc-radios li input{width:auto}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap,.woocommerce .panel-wrap{overflow:hidden}#woocommerce-coupon-data ul.wc-tabs,#woocommerce-product-data ul.wc-tabs,.woocommerce ul.wc-tabs{margin:0;width:20%;float:left;line-height:1em;padding:0 0 10px;position:relative;background-color:#fafafa;border-right:1px solid #eee;box-sizing:border-box}#woocommerce-coupon-data ul.wc-tabs:after,#woocommerce-product-data ul.wc-tabs:after,.woocommerce ul.wc-tabs:after{content:"";display:block;width:100%;height:9999em;position:absolute;bottom:-9999em;left:0;background-color:#fafafa;border-right:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li,#woocommerce-product-data ul.wc-tabs li,.woocommerce ul.wc-tabs li{margin:0;padding:0;display:block;position:relative}#woocommerce-coupon-data ul.wc-tabs li a,#woocommerce-product-data ul.wc-tabs li a,.woocommerce ul.wc-tabs li a{margin:0;padding:10px;display:block;box-shadow:none;text-decoration:none;line-height:20px!important;border-bottom:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li a:before,#woocommerce-product-data ul.wc-tabs li a:before,.woocommerce ul.wc-tabs li a:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}#woocommerce-coupon-data ul.wc-tabs li.general_options a:before,#woocommerce-product-data ul.wc-tabs li.general_options a:before,.woocommerce ul.wc-tabs li.general_options a:before{content:"\f107"}#woocommerce-coupon-data ul.wc-tabs li.inventory_options a:before,#woocommerce-product-data ul.wc-tabs li.inventory_options a:before,.woocommerce ul.wc-tabs li.inventory_options a:before{content:"\f481"}#woocommerce-coupon-data ul.wc-tabs li.shipping_options a:before,#woocommerce-product-data ul.wc-tabs li.shipping_options a:before,.woocommerce ul.wc-tabs li.shipping_options a:before{font-family:WooCommerce;content:"\e01a"}#woocommerce-coupon-data ul.wc-tabs li.linked_product_options a:before,#woocommerce-product-data ul.wc-tabs li.linked_product_options a:before,.woocommerce ul.wc-tabs li.linked_product_options a:before{content:"\f103"}#woocommerce-coupon-data ul.wc-tabs li.attribute_options a:before,#woocommerce-product-data ul.wc-tabs li.attribute_options a:before,.woocommerce ul.wc-tabs li.attribute_options a:before{content:"\f175"}#woocommerce-coupon-data ul.wc-tabs li.advanced_options a:before,#woocommerce-product-data ul.wc-tabs li.advanced_options a:before,.woocommerce ul.wc-tabs li.advanced_options a:before{font-family:Dashicons;content:"\f111"}#woocommerce-coupon-data ul.wc-tabs li.variations_options a:before,#woocommerce-product-data ul.wc-tabs li.variations_options a:before,.woocommerce ul.wc-tabs li.variations_options a:before{content:"\f509"}#woocommerce-coupon-data ul.wc-tabs li.usage_restriction_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_restriction_options a:before,.woocommerce ul.wc-tabs li.usage_restriction_options a:before{font-family:WooCommerce;content:"\e602"}#woocommerce-coupon-data ul.wc-tabs li.usage_limit_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_limit_options a:before,.woocommerce ul.wc-tabs li.usage_limit_options a:before{font-family:WooCommerce;content:"\e601"}#woocommerce-coupon-data ul.wc-tabs li.general_coupon_data a:before,#woocommerce-product-data ul.wc-tabs li.general_coupon_data a:before,.woocommerce ul.wc-tabs li.general_coupon_data a:before{font-family:WooCommerce;content:"\e600"}#woocommerce-coupon-data ul.wc-tabs li.active a,#woocommerce-product-data ul.wc-tabs li.active a,.woocommerce ul.wc-tabs li.active a{color:#555;position:relative;background-color:#eee}.woocommerce_page_wc-settings .shippingrows th.check-column{padding-top:20px}.woocommerce_page_wc-settings .shippingrows tfoot th{padding-left:10px}.woocommerce_page_wc-settings .shippingrows .add.button:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}.woocommerce_page_wc-settings h3.wc-settings-sub-title{font-size:1.2em}#woocommerce-coupon-data .inside,#woocommerce-order-data .inside,#woocommerce-order-downloads .inside,#woocommerce-product-data .inside,#woocommerce-product-type-options .inside{margin:0;padding:0}.panel,.woocommerce_options_panel{padding:9px;color:#555}.panel .form-field .woocommerce-help-tip,.woocommerce_options_panel .form-field .woocommerce-help-tip{font-size:1.4em}.panel,.woocommerce_page_settings .woocommerce_options_panel{padding:0}#woocommerce-product-specs .inside,#woocommerce-product-type-options .panel{margin:0;padding:9px}#woocommerce-product-type-options .panel p,.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p{margin:0 0 9px;font-size:12px;padding:5px 9px;line-height:24px}#woocommerce-product-type-options .panel p:after,.woocommerce_options_panel fieldset.form-field:after,.woocommerce_options_panel p:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce_options_panel .checkbox,.woocommerce_variable_attributes .checkbox{width:auto;margin:3px 0;vertical-align:middle}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{width:100%;padding:0!important}.woocommerce_options_panel .downloadable_files table th,.woocommerce_variations .downloadable_files table th{padding:7px 0 7px 7px!important}.woocommerce_options_panel .downloadable_files table th.sort,.woocommerce_variations .downloadable_files table th.sort{width:17px;padding:7px!important}.woocommerce_options_panel .downloadable_files table th .woocommerce-help-tip,.woocommerce_variations .downloadable_files table th .woocommerce-help-tip{font-size:1.1em;margin-left:0}.woocommerce_options_panel .downloadable_files table td,.woocommerce_variations .downloadable_files table td{vertical-align:middle!important;padding:4px 0 4px 7px!important;position:relative}.woocommerce_options_panel .downloadable_files table td:last-child,.woocommerce_variations .downloadable_files table td:last-child{padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td input.input_text,.woocommerce_variations .downloadable_files table td input.input_text{width:100%;float:none;min-width:0;margin:1px 0}.woocommerce_options_panel .downloadable_files table td .upload_file_button,.woocommerce_variations .downloadable_files table td .upload_file_button{width:auto;float:right;cursor:pointer}.woocommerce_options_panel .downloadable_files table td .delete,.woocommerce_variations .downloadable_files table td .delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.2em}.woocommerce_options_panel .downloadable_files table td .delete:before,.woocommerce_variations .downloadable_files table td .delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}.woocommerce_options_panel .downloadable_files table td .delete:hover:before,.woocommerce_variations .downloadable_files table td .delete:hover:before{color:#a00}.woocommerce_options_panel .downloadable_files table td.sort,.woocommerce_variations .downloadable_files table td.sort{width:17px;cursor:move;font-size:15px;text-align:center;background:#f9f9f9;padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td.sort:before,.woocommerce_variations .downloadable_files table td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_options_panel .downloadable_files table td.sort:hover:before,.woocommerce_variations .downloadable_files table td.sort:hover:before{color:#333}.woocommerce_variation h3 .sort{width:17px;height:26px;cursor:move;float:right;font-size:15px;font-weight:400;margin-right:.5em;visibility:hidden;text-align:center;vertical-align:middle}.woocommerce_variation h3 .sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:28px;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_variation h3 .sort:hover:before{color:#777}.woocommerce_variation h3:hover .sort,.woocommerce_variation.ui-sortable-helper .sort{visibility:visible}.woocommerce_options_panel{min-height:175px;box-sizing:border-box}.woocommerce_options_panel .downloadable_files{padding:0 9px 0 162px;position:relative;margin:9px 0}.woocommerce_options_panel .downloadable_files label{position:absolute;left:0;margin:0 0 0 12px;line-height:24px}.woocommerce_options_panel p{margin:9px 0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px 5px 162px!important}.woocommerce_options_panel .sale_price_dates_fields .short:first-of-type{margin-bottom:1em}.woocommerce_options_panel .sale_price_dates_fields .short:nth-of-type(2){clear:left}.woocommerce_options_panel label,.woocommerce_options_panel legend{float:left;width:150px;padding:0;margin:0 0 0 -150px}.woocommerce_options_panel label .req,.woocommerce_options_panel legend .req{font-weight:700;font-style:normal;color:#a00}.woocommerce_options_panel .description{padding:0;margin:0 0 0 7px;clear:none;display:inline}.woocommerce_options_panel .description-block{margin-left:0;display:block}.woocommerce_options_panel input,.woocommerce_options_panel select,.woocommerce_options_panel textarea{margin:0}.woocommerce_options_panel textarea{height:3.5em;line-height:1.5em;vertical-align:top}.woocommerce_options_panel input[type=text],.woocommerce_options_panel input[type=number],.woocommerce_options_panel input[type=email],.woocommerce_options_panel input[type=password]{width:50%;float:left}.woocommerce_options_panel input.button{width:auto;margin-left:8px}.woocommerce_options_panel select{float:left}.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:50%}.woocommerce_options_panel .sized{width:auto!important;margin-right:6px}.woocommerce_options_panel .options_group{border-top:1px solid #fff;border-bottom:1px solid #eee}.woocommerce_options_panel .options_group:first-child{border-top:0}.woocommerce_options_panel .options_group:last-child{border-bottom:0}.woocommerce_options_panel .options_group fieldset{margin:9px 0;font-size:12px;padding:5px 9px;line-height:24px}.woocommerce_options_panel .options_group fieldset label{width:auto;float:none}.woocommerce_options_panel .options_group fieldset ul{float:left;width:50%;margin:0;padding:0}.woocommerce_options_panel .options_group fieldset ul li{margin:0;width:auto}.woocommerce_options_panel .options_group fieldset ul li input{width:auto;float:none;margin-right:4px}.woocommerce_options_panel .options_group fieldset ul.wc-radios label{margin-left:0}.woocommerce_options_panel .dimensions_field .wrap{display:block;width:50%}.woocommerce_options_panel .dimensions_field .wrap input{width:30.75%;margin-right:3.8%}.woocommerce_options_panel .dimensions_field .wrap .last{margin-right:0}.woocommerce_options_panel.padded{padding:1em}#woocommerce-product-data input.dp-applied,.woocommerce_options_panel .select2-container{float:left}#grouped_product_options,#simple_product_options,#virtual_product_options{padding:12px;font-style:italic;color:#666}.wc-metaboxes-wrapper .toolbar{margin:0!important;border-top:1px solid #fff;border-bottom:1px solid #eee;padding:9px 12px!important}.wc-metaboxes-wrapper .toolbar:first-child{border-top:0}.wc-metaboxes-wrapper .toolbar:last-child{border-bottom:0}.wc-metaboxes-wrapper .toolbar .add_variation{float:right;margin-left:5px}.wc-metaboxes-wrapper .toolbar .cancel-variation-changes,.wc-metaboxes-wrapper .toolbar .save-variation-changes{float:left;margin-right:5px}.wc-metaboxes-wrapper p.toolbar{overflow:hidden;zoom:1}.wc-metaboxes-wrapper .expand-close{margin-right:2px;color:#777;font-size:12px;font-style:italic}.wc-metaboxes-wrapper .expand-close a{background:0 0;padding:0;font-size:12px;text-decoration:none}.wc-metaboxes-wrapper#product_attributes .expand-close{float:right;line-height:28px}.wc-metaboxes-wrapper .fr,.wc-metaboxes-wrapper button.add_variable_attribute{float:right;margin:0 0 0 6px}.wc-metaboxes-wrapper .wc-metaboxes{border-bottom:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox-sortable-placeholder{border-color:#bbb;background-color:#f5f5f5;margin-bottom:9px;border-width:1px;border-style:dashed}.wc-metaboxes-wrapper .wc-metabox{background:#fff;border-bottom:1px solid #eee;margin:0!important}.wc-metaboxes-wrapper .wc-metabox select{font-weight:400}.wc-metaboxes-wrapper .wc-metabox:last-of-type{border-bottom:0}.wc-metaboxes-wrapper .wc-metabox .handlediv{width:27px}.wc-metaboxes-wrapper .wc-metabox .handlediv:before{content:"\f142"!important;cursor:pointer;display:inline-block;font:400 20px/1 Dashicons;line-height:.5!important;padding:8px 10px;position:relative;right:12px;top:0}.wc-metaboxes-wrapper .wc-metabox.closed{border-radius:3px}.wc-metaboxes-wrapper .wc-metabox.closed .handlediv:before{content:"\f140"!important}.wc-metaboxes-wrapper .wc-metabox.closed h3{border:0}.wc-metaboxes-wrapper .wc-metabox h3{margin:0!important;padding:.75em .75em .75em 1em!important;font-size:1em!important;overflow:hidden;zoom:1;cursor:move}.wc-metaboxes-wrapper .wc-metabox h3 a.delete,.wc-metaboxes-wrapper .wc-metabox h3 button{float:right}.wc-metaboxes-wrapper .wc-metabox h3 a.delete{color:red;font-weight:400;line-height:26px;text-decoration:none;position:relative;visibility:hidden}.wc-metaboxes-wrapper .wc-metabox h3 strong{line-height:26px;font-weight:700}.wc-metaboxes-wrapper .wc-metabox h3 select{font-family:sans-serif;max-width:20%;margin:.25em .25em .25em 0}.wc-metaboxes-wrapper .wc-metabox h3 .handlediv{background-position:6px 5px!important;visibility:hidden;height:26px}.wc-metaboxes-wrapper .wc-metabox h3.fixed{cursor:pointer!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3{cursor:pointer;padding:.5em .75em .5em 1em!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .handlediv,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .sort,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 a.delete{margin-top:.25em}.wc-metaboxes-wrapper .wc-metabox h3:hover .handlediv,.wc-metaboxes-wrapper .wc-metabox h3:hover a.delete,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper .handlediv,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper a.delete{visibility:visible}.wc-metaboxes-wrapper .wc-metabox table{width:100%;position:relative;background-color:#fdfdfd;padding:1em;border-top:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox table td{text-align:left;padding:0 6px 1em 0;vertical-align:top;border:0}.wc-metaboxes-wrapper .wc-metabox table td label{text-align:left;display:block;line-height:21px}.wc-metaboxes-wrapper .wc-metabox table td input{float:left;min-width:200px}.wc-metaboxes-wrapper .wc-metabox table td input,.wc-metaboxes-wrapper .wc-metabox table td textarea{width:100%;margin:0;display:block;font-size:14px;padding:4px;color:#555}.wc-metaboxes-wrapper .wc-metabox table td .select2-container,.wc-metaboxes-wrapper .wc-metabox table td select{width:100%!important}.wc-metaboxes-wrapper .wc-metabox table td input.short{width:200px}.wc-metaboxes-wrapper .wc-metabox table td input.checkbox{width:16px;min-width:inherit;vertical-align:text-bottom;display:inline-block;float:none}.wc-metaboxes-wrapper .wc-metabox table td.attribute_name{width:200px}.wc-metaboxes-wrapper .wc-metabox table .minus,.wc-metaboxes-wrapper .wc-metabox table .plus{margin-top:6px}.wc-metaboxes-wrapper .wc-metabox table .fl{float:left}.wc-metaboxes-wrapper .wc-metabox table .fr{float:right}.variations-pagenav{float:right;line-height:24px}.variations-pagenav .displaying-num{color:#777;font-size:12px;font-style:italic}.variations-pagenav a{padding:0 10px 3px;background:rgba(0,0,0,.05);font-size:16px;font-weight:400;text-decoration:none}.variations-pagenav a.disabled,.variations-pagenav a.disabled:active,.variations-pagenav a.disabled:focus,.variations-pagenav a.disabled:hover{color:#A0A5AA;background:rgba(0,0,0,.05)}.variations-defaults{float:left}.variations-defaults select{margin:.25em .25em .25em 0}.woocommerce_variable_attributes{background-color:#fdfdfd;border-top:1px solid #eee}.woocommerce_variable_attributes .data{padding:1em 2em}.woocommerce_variable_attributes .data:after,.woocommerce_variable_attributes .data:before{content:" ";display:table}.woocommerce_variable_attributes .data:after{clear:both}.woocommerce_variable_attributes .upload_image_button{display:block;width:48px;height:48px;float:left;margin-right:20px;position:relative;cursor:pointer}.woocommerce_variable_attributes .upload_image_button img{width:100%;height:auto;display:none}.woocommerce_variable_attributes .upload_image_button:before{content:"\f128";font-family:Dashicons;position:absolute;top:0;left:0;right:0;bottom:0;text-align:center;line-height:48px;font-size:48px;font-weight:400;-webkit-font-smoothing:antialiased}.woocommerce_variable_attributes .upload_image_button.remove img{display:block}.woocommerce_variable_attributes .upload_image_button.remove:before{content:"\f335";display:none}.woocommerce_variable_attributes .upload_image_button.remove:hover:before{display:block}.woocommerce_variable_attributes .options{border:1px solid #eee;border-width:1px 0;padding:.25em 0}.woocommerce_variable_attributes .options label{display:inline-block;padding:4px 1em 2px 0}.woocommerce_variable_attributes .options input[type=checkbox]{margin-top:5px;margin-right:3px}.form-row label{display:block}.form-row input[type=number],.form-row input[type=text],.form-row select{width:100%}.form-row.dimensions_field input{width:25%;float:left;margin-right:1%}.form-row.dimensions_field input:last-of-type{margin-right:0}.form-row-first,.form-row-last{width:48%;float:right}.form-row-first{clear:both;float:left}.form-row-full{clear:both}.tips{cursor:help;text-decoration:none}img.tips{padding:5px 0 0}#tiptip_holder{display:none;position:absolute;top:0;left:0;z-index:9999999}#tiptip_holder.tip_top{padding-bottom:5px}#tiptip_holder.tip_top #tiptip_arrow_inner{margin-top:-7px;margin-left:-6px;border-top-color:#333}#tiptip_holder.tip_bottom{padding-top:5px}#tiptip_holder.tip_bottom #tiptip_arrow_inner{margin-top:-5px;margin-left:-6px;border-bottom-color:#333}#tiptip_holder.tip_right{padding-left:5px}#tiptip_holder.tip_right #tiptip_arrow_inner{margin-top:-6px;margin-left:-5px;border-right-color:#333}#tiptip_holder.tip_left{padding-right:5px}#tiptip_holder.tip_left #tiptip_arrow_inner{margin-top:-6px;margin-left:-7px;border-left-color:#333}#tiptip_content,.chart-tooltip,.wc_error_tip{color:#fff;font-size:.8em;max-width:150px;background:#333;text-align:center;border-radius:3px;padding:.618em 1em;box-shadow:0 1px 3px rgba(0,0,0,.2)}#tiptip_content code,.chart-tooltip code,.wc_error_tip code{padding:1px;background:#888}#tiptip_arrow,#tiptip_arrow_inner{position:absolute;border-color:transparent;border-style:solid;border-width:6px;height:0;width:0}.wc_error_tip{max-width:20em;line-height:1.8em;position:absolute;white-space:normal;background:#d82223;margin:1.5em 1px 0 -1em;z-index:9999999}.wc_error_tip:after{content:"";display:block;border:8px solid #d82223;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-3px;left:50%;margin:-1em 0 0 -3px}img.ui-datepicker-trigger{vertical-align:middle;margin-top:-1px;cursor:pointer}.wc-metabox-content img.ui-datepicker-trigger,.woocommerce_options_panel img.ui-datepicker-trigger{float:left;margin-right:8px;margin-top:4px;margin-left:4px}#ui-datepicker-div{display:none}.woocommerce-reports-wide.woocommerce-reports-wrap,.woocommerce-reports-wrap.woocommerce-reports-wrap{margin-left:300px;padding-top:18px}.woocommerce-reports-wide.halved,.woocommerce-reports-wrap.halved{margin:0;overflow:hidden;zoom:1}.woocommerce-reports-wide .widefat td,.woocommerce-reports-wrap .widefat td{vertical-align:top;padding:7px}.woocommerce-reports-wide .widefat td .description,.woocommerce-reports-wrap .widefat td .description{margin:4px 0 0}.woocommerce-reports-wide .postbox:after,.woocommerce-reports-wrap .postbox:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox h3,.woocommerce-reports-wrap .postbox h3{cursor:default!important}.woocommerce-reports-wide .postbox .inside,.woocommerce-reports-wrap .postbox .inside{padding:10px;margin:0!important}.woocommerce-reports-wide .postbox div.stats_range,.woocommerce-reports-wide .postbox h3.stats_range,.woocommerce-reports-wrap .postbox div.stats_range,.woocommerce-reports-wrap .postbox h3.stats_range{border-bottom-color:#dfdfdf;margin:0;padding:0!important}.woocommerce-reports-wide .postbox div.stats_range .export_csv,.woocommerce-reports-wide .postbox h3.stats_range .export_csv,.woocommerce-reports-wrap .postbox div.stats_range .export_csv,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv{float:right;line-height:26px;border-left:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range .export_csv:before,.woocommerce-reports-wide .postbox h3.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox div.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;content:"";text-decoration:none;margin-right:4px}.woocommerce-reports-wide .postbox div.stats_range ul,.woocommerce-reports-wide .postbox h3.stats_range ul,.woocommerce-reports-wrap .postbox div.stats_range ul,.woocommerce-reports-wrap .postbox h3.stats_range ul{list-style:none;margin:0;padding:0;zoom:1;background:#f5f5f5;border-bottom:1px solid #ccc}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox div.stats_range ul:before,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:before,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:before,.woocommerce-reports-wrap .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:before{content:" ";display:table}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:after{clear:both}.woocommerce-reports-wide .postbox div.stats_range ul li,.woocommerce-reports-wide .postbox h3.stats_range ul li,.woocommerce-reports-wrap .postbox div.stats_range ul li,.woocommerce-reports-wrap .postbox h3.stats_range ul li{float:left;margin:0;padding:0;line-height:26px;font-weight:700;font-size:14px}.woocommerce-reports-wide .postbox div.stats_range ul li a,.woocommerce-reports-wide .postbox h3.stats_range ul li a,.woocommerce-reports-wrap .postbox div.stats_range ul li a,.woocommerce-reports-wrap .postbox h3.stats_range ul li a{border-right:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range ul li.active,.woocommerce-reports-wide .postbox h3.stats_range ul li.active,.woocommerce-reports-wrap .postbox div.stats_range ul li.active,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active{background:#fff;-webkit-box-shadow:0 4px 0 0 #fff;box-shadow:0 4px 0 0 #fff}.woocommerce-reports-wide .postbox div.stats_range ul li.active a,.woocommerce-reports-wide .postbox h3.stats_range ul li.active a,.woocommerce-reports-wrap .postbox div.stats_range ul li.active a,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active a{color:#777}.woocommerce-reports-wide .postbox div.stats_range ul li.custom,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom{padding:9px 10px;vertical-align:middle}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form{display:inline;margin:0}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form input.range_datepicker{padding:0;margin:0 10px 0 0;background:0 0;border:0;color:#777;text-align:center;-webkit-box-shadow:none;box-shadow:none}.woocommerce-reports-wide .postbox .chart-with-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar{padding:12px 12px 12px 249px;margin:0!important}.woocommerce-reports-wide .postbox .chart-with-sidebar .chart-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar .chart-sidebar{width:225px;margin-left:-237px;float:left}.woocommerce-reports-wide .postbox .chart-widgets,.woocommerce-reports-wrap .postbox .chart-widgets{margin:0;padding:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget{margin:0 0 1em;background:#fafafa;border:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4{background:#fff;border:1px solid #dfdfdf;border-left-width:0;border-right-width:0;padding:10px;margin:0;color:#2ea2cc;border-top-width:0;background-image:-webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9));background-image:-webkit-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-moz-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-o-linear-gradient(bottom,#ececec,#f9f9f9);background-image:linear-gradient(to top,#ececec,#f9f9f9)}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr.active td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr.active td{background:#f5f5f5}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4.section_title:hover,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4.section_title:hover{color:#a00}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title{cursor:pointer}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span{display:block}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin-left:.618em;content:"";text-decoration:none;float:right;font-size:.9em;line-height:1.618}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open{color:#333}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open span:after{display:none}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section{border-bottom:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section .select2-container,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section .select2-container{width:100%!important}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section:last-of-type,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section:last-of-type{border-radius:0 0 3px 3px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td{padding:7px 10px;vertical-align:top;border-top:1px solid #e5e5e5;line-height:1.4em}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.sparkline,form.report_filters div,form.report_filters input,form.report_filters label,form.report_filters p{vertical-align:middle}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr:first-child td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr:first-child td{border-top:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name{max-width:175px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name a,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name a{word-wrap:break-word}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table .wc_sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table .wc_sparkline{width:32px;height:1em;display:block;float:right}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p{margin:0;padding:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p .submit{margin-top:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget #product_ids,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget #product_ids{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_none,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_none{float:right;color:#999;margin-left:4px;margin-top:10px}.woocommerce-reports-wide .postbox .chart-legend,.woocommerce-reports-wrap .postbox .chart-legend{list-style:none;margin:0 0 1em;padding:0;border:1px solid #dfdfdf;border-right-width:0;border-bottom-width:0;background:#fff}.woocommerce-reports-wide .postbox .chart-legend li,.woocommerce-reports-wrap .postbox .chart-legend li{border-right:5px solid #aaa;color:#aaa;padding:1em;display:block;margin:0;-webkit-transition:all ease .5s;box-shadow:inset 0 -1px 0 0 #dfdfdf}.woocommerce-reports-wide .postbox .chart-legend li strong,.woocommerce-reports-wrap .postbox .chart-legend li strong{font-size:1.618em;line-height:1.2em;color:#464646;font-weight:400;display:block;font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif}.woocommerce-reports-wide .postbox .chart-legend li strong del,.woocommerce-reports-wrap .postbox .chart-legend li strong del{color:#e74c3c;font-weight:400}.woocommerce-reports-wide .postbox .chart-legend li:hover,.woocommerce-reports-wrap .postbox .chart-legend li:hover{box-shadow:inset 0 -1px 0 0 #dfdfdf,inset 300px 0 0 rgba(156,93,144,.1);border-right:5px solid #9c5d90!important;padding-left:1.5em;color:#9c5d90}.woocommerce-reports-wide .postbox .pie-chart-legend,.woocommerce-reports-wrap .postbox .pie-chart-legend{margin:12px 0 0;overflow:hidden}.woocommerce-reports-wide .postbox .pie-chart-legend li,.woocommerce-reports-wrap .postbox .pie-chart-legend li{float:left;margin:0;padding:6px 0 0;border-top:4px solid #999;text-align:center;box-sizing:border-box;width:50%}.woocommerce-reports-wide .postbox .stat,.woocommerce-reports-wrap .postbox .stat{font-size:1.5em!important;font-weight:700;text-align:center}.woocommerce-reports-wide .postbox .chart-placeholder,.woocommerce-reports-wrap .postbox .chart-placeholder{width:100%;height:650px;overflow:hidden;position:relative}.woocommerce-reports-wide .postbox .chart-prompt,.woocommerce-reports-wrap .postbox .chart-prompt{line-height:650px;margin:0;color:#999;font-size:1.2em;font-style:italic;text-align:center}.woocommerce-reports-wide .postbox .chart-container,.woocommerce-reports-wrap .postbox .chart-container{background:#fff;padding:12px;position:relative;border:1px solid #dfdfdf;border-radius:3px}.woocommerce-reports-wide .postbox .main .chart-legend,.woocommerce-reports-wrap .postbox .main .chart-legend{margin-top:12px}.woocommerce-reports-wide .postbox .main .chart-legend li,.woocommerce-reports-wrap .postbox .main .chart-legend li{border-right:0;margin:0 8px 0 0;float:left;border-top:4px solid #aaa}.woocommerce-reports-wide .woocommerce-reports-main,.woocommerce-reports-wrap .woocommerce-reports-main{float:left;min-width:100%}.woocommerce-reports-wide .woocommerce-reports-main table td,.woocommerce-reports-wrap .woocommerce-reports-main table td{padding:9px}.woocommerce-reports-wide .woocommerce-reports-sidebar,.woocommerce-reports-wrap .woocommerce-reports-sidebar{display:inline;width:281px;margin-left:-300px;clear:both;float:left}.woocommerce-reports-wide .woocommerce-reports-left,.woocommerce-reports-wrap .woocommerce-reports-left{width:49.5%;float:left}.woocommerce-reports-wide .woocommerce-reports-right,.woocommerce-reports-wrap .woocommerce-reports-right{width:49.5%;float:right}.woocommerce-reports-wide .column-wc_actions a.edit,.woocommerce-reports-wide .column-wc_actions a.view,.woocommerce-reports-wrap .column-wc_actions a.edit,.woocommerce-reports-wrap .column-wc_actions a.view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;line-height:1.85}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after{content:"\f464"}.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{content:"\f177"}.woocommerce-wide-reports-wrap{padding-bottom:11px}.woocommerce-wide-reports-wrap .widefat .export-data{float:right}.woocommerce-wide-reports-wrap .widefat td,.woocommerce-wide-reports-wrap .widefat th{vertical-align:middle;padding:7px}.chart-tooltip{position:absolute;display:none;line-height:1}table.bar_chart{width:100%}table.bar_chart thead th{text-align:left;color:#ccc;padding:6px 0}table.bar_chart tbody th{padding:6px 0;width:25%;text-align:left!important;font-weight:400!important;border-bottom:1px solid #fee}table.bar_chart tbody td{text-align:right;line-height:24px;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td span{color:#8a4b75;display:block}table.bar_chart tbody td span.alt{color:#47a03e;margin-top:6px}table.bar_chart tbody td.bars{position:relative;text-align:left;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td.bars a,table.bar_chart tbody td.bars span{text-decoration:none;clear:both;background:#8a4b75;float:left;display:block;line-height:24px;height:24px;-moz-border-radius:3px;-webkit-border-radius:3px;-o-border-radius:3px;-khtml-border-radius:3px;border-radius:3px}.post-type-product .woocommerce-BlankState-message:before,.post-type-shop_coupon .woocommerce-BlankState-message:before,.post-type-shop_order .woocommerce-BlankState-message:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}table.bar_chart tbody td.bars span.alt{clear:both;background:#47a03e}table.bar_chart tbody td.bars span.alt span{margin:0;color:#c5dec2!important;text-shadow:0 1px 0 #47a03e;background:0 0}.post-type-shop_order .woocommerce-BlankState-message:before{content:""}.post-type-shop_coupon .woocommerce-BlankState-message:before{content:""}.post-type-product .woocommerce-BlankState-message:before{content:""}.woocommerce-BlankState{text-align:center;padding:5em 0 0}.woocommerce-BlankState .woocommerce-BlankState-message{color:#aaa;margin:0 auto 1.5em;line-height:1.5em;font-size:1.2em;max-width:500px}.woocommerce-BlankState .woocommerce-BlankState-message:before{color:#ddd;text-shadow:0 -1px 1px rgba(0,0,0,.2),0 1px 0 rgba(255,255,255,.8);font-size:8em;display:block;position:relative!important;top:auto;left:auto;line-height:1em;margin:0 0 .1875em}.woocommerce-BlankState .woocommerce-BlankState-cta{font-size:1.2em;padding:.75em 1.5em;height:auto}@media only screen and (max-width:1280px){#order_data .order_data_column{width:48%}#order_data .order_data_column:first-child{width:100%}.woocommerce_options_panel .description{display:block;clear:both;margin-left:0}.woocommerce_options_panel .dimensions_field .wrap,.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:80%}.woocommerce_options_panel .downloadable_files,.woocommerce_variations .downloadable_files{padding:0;clear:both}.woocommerce_options_panel .downloadable_files label,.woocommerce_variations .downloadable_files label{position:static}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{margin:0 12px 24px;width:94%}.woocommerce_options_panel .downloadable_files table .sort,.woocommerce_variations .downloadable_files table .sort{visibility:hidden}.woocommerce_options_panel .woocommerce_variable_attributes .downloadable_files table,.woocommerce_variations .woocommerce_variable_attributes .downloadable_files table{margin:0 0 1em;width:100%}}@media only screen and (max-width:900px){#woocommerce-coupon-data ul.coupon_data_tabs,#woocommerce-product-data .wc-tabs-back,#woocommerce-product-data ul.product_data_tabs{width:10%}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{width:90%}#woocommerce-coupon-data ul.coupon_data_tabs li a,#woocommerce-product-data ul.product_data_tabs li a{position:relative;text-indent:-999px;padding:10px}#woocommerce-coupon-data ul.coupon_data_tabs li a:before,#woocommerce-product-data ul.product_data_tabs li a:before{position:absolute;top:0;right:0;bottom:0;left:0;text-indent:0;text-align:center;line-height:40px;width:100%;height:40px}}@media only screen and (max-width:782px){#wp-excerpt-media-buttons a{font-size:16px;line-height:37px;height:39px;padding:0 20px 0 15px}#wp-excerpt-editor-tools{padding-top:20px;padding-right:15px;overflow:hidden;margin-bottom:-1px}.post-type-product .wp-list-table .is-expanded td:not(.hidden),.post-type-shop_order .wp-list-table .is-expanded td:not(.hidden){overflow:visible}#woocommerce-product-data .checkbox{width:25px}.variations-pagenav{float:none;text-align:center;font-size:18px}.variations-pagenav .displaying-num{font-size:16px}.variations-pagenav a{padding:8px 20px 11px;font-size:18px}.variations-pagenav select{padding:0 20px}.variations-defaults{float:none;text-align:center;margin-top:10px}.post-type-product .wp-list-table .column-thumb{display:none;text-align:left;padding-bottom:0}.post-type-product .wp-list-table .column-thumb:before{display:none!important}.post-type-product .wp-list-table .column-thumb img{max-width:32px}.post-type-product .wp-list-table .toggle-row{top:-28px}.post-type-shop_order .wp-list-table .column-order_status{display:none;text-align:left;padding-bottom:0}.post-type-shop_order .wp-list-table .column-order_status mark{margin:0}.post-type-shop_order .wp-list-table .column-order_status:before{display:none!important}.post-type-shop_order .wp-list-table .column-customer_message,.post-type-shop_order .wp-list-table .column-order_notes{text-align:inherit}.post-type-shop_order .wp-list-table .column-order_notes .note-on{font-size:1.3em;margin:0}.post-type-shop_order .wp-list-table .toggle-row{top:-15px}}@media only screen and (max-width:500px){.woocommerce_options_panel label,.woocommerce_options_panel legend{float:none;width:auto;display:block;margin:0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px!important}}.wc-backbone-modal *{box-sizing:border-box}.wc-backbone-modal .wc-backbone-modal-content{position:fixed;background:#fff;z-index:100000;left:50%;top:50%;transform:translate(-50%,-50%);width:500px}.wc-backbone-modal .wc-backbone-modal-content article{overflow:auto}.wc-backbone-modal.wc-backbone-modal-shipping-method-settings .wc-backbone-modal-content{width:75%;min-width:500px}.wc-backbone-modal-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;min-height:360px;background:#000;opacity:.7;z-index:99900}.wc-backbone-modal-main{padding-bottom:55px}.wc-backbone-modal-main article,.wc-backbone-modal-main header{display:block;position:relative}.wc-backbone-modal-main .wc-backbone-modal-header{height:auto;background:#fcfcfc;padding:1em 1.5em;border-bottom:1px solid #ddd}.wc-backbone-modal-main .wc-backbone-modal-header h1{margin:0;font-size:18px;font-weight:700;line-height:1.5em}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link{cursor:pointer;color:#777;height:54px;width:54px;padding:0;position:absolute;top:0;right:0;text-align:center;border:0;border-left:1px solid #ddd;background-color:transparent;-webkit-transition:color .1s ease-in-out,background .1s ease-in-out;transition:color .1s ease-in-out,background .1s ease-in-out}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:before{font:400 22px/50px dashicons!important;color:#666;display:block;content:'\f335';font-weight:300}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus,.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:hover{background:#ddd;border-color:#ccc;color:#000}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus{outline:0}.wc-backbone-modal-main article{padding:1.5em}.wc-backbone-modal-main article p{margin:1.5em 0}.wc-backbone-modal-main article p:last-child,.wc-backbone-modal-main footer .inner .button{margin-bottom:0}.wc-backbone-modal-main article p:first-child{margin-top:0}.wc-backbone-modal-main article .pagination{padding:10px 0 0;text-align:center}.wc-backbone-modal-main footer{position:absolute;left:0;right:0;bottom:0;z-index:100;padding:1em 1.5em;background:#fcfcfc;border-top:1px solid #dfdfdf;box-shadow:0 -4px 4px -4px rgba(0,0,0,.1)}.wc-backbone-modal-main footer .inner{float:right;line-height:23px}.select2-drop{z-index:999999!important}.select2-container-multi .select2-choices .select2-search-field input{font-family:inherit;font-size:inherit;font-weight:inherit;padding:3px 5px}.select2-container{line-height:1.85em;font-size:14px} \ No newline at end of file diff --git a/assets/css/admin.scss b/assets/css/admin.scss index c727dfa568e..db0bc7f7089 100644 --- a/assets/css/admin.scss +++ b/assets/css/admin.scss @@ -585,7 +585,7 @@ ul.wc_coupon_list_block { .hour, .minute { - width: 3em; + width: 3.5em; } small { From 1497075b9ea2c523dcbb8c62d4a9b8a13f1b5043 Mon Sep 17 00:00:00 2001 From: Fredrik Forsmo Date: Mon, 1 Aug 2016 13:21:55 +0200 Subject: [PATCH 192/298] Add tests for `wc_site_is_https` --- tests/unit-tests/util/conditional-functions.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/unit-tests/util/conditional-functions.php b/tests/unit-tests/util/conditional-functions.php index 5da4d4142fd..11ea4308f9f 100644 --- a/tests/unit-tests/util/conditional-functions.php +++ b/tests/unit-tests/util/conditional-functions.php @@ -97,6 +97,19 @@ class WC_Tests_Conditional_Functions extends WC_Unit_Test_Case { ); } + /** + * Test wc_site_is_https(). + */ + public function test_wc_site_is_https() { + $this->assertFalse( wc_site_is_https() ); + + add_filter( 'pre_option_home', function () { + return 'https://example.org'; + } ); + + $this->assertTrue( wc_site_is_https() ); + } + /** * Test wc_is_valid_url(). * From 7b01a965076634d7cfbcb482cafc4288c453a3c7 Mon Sep 17 00:00:00 2001 From: Fredrik Forsmo Date: Mon, 1 Aug 2016 14:31:12 +0200 Subject: [PATCH 193/298] Add callback url to `wc_site_is_https` test --- tests/unit-tests/util/conditional-functions.php | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/tests/unit-tests/util/conditional-functions.php b/tests/unit-tests/util/conditional-functions.php index 11ea4308f9f..07f093a77d0 100644 --- a/tests/unit-tests/util/conditional-functions.php +++ b/tests/unit-tests/util/conditional-functions.php @@ -103,13 +103,20 @@ class WC_Tests_Conditional_Functions extends WC_Unit_Test_Case { public function test_wc_site_is_https() { $this->assertFalse( wc_site_is_https() ); - add_filter( 'pre_option_home', function () { - return 'https://example.org'; - } ); + add_filter( 'pre_option_home', [$this, '_https_url'] ); $this->assertTrue( wc_site_is_https() ); } + /** + * Callback for chaning home url to https. + * + * @return string + */ + public function _https_url() { + return 'https://example.org'; + } + /** * Test wc_is_valid_url(). * From 88d81401101812a8406c7955f5310c584e331a46 Mon Sep 17 00:00:00 2001 From: Fredrik Forsmo Date: Mon, 1 Aug 2016 13:21:55 +0200 Subject: [PATCH 194/298] Add tests for `wc_site_is_https` Add callback url to `wc_site_is_https` test --- .../unit-tests/util/conditional-functions.php | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/unit-tests/util/conditional-functions.php b/tests/unit-tests/util/conditional-functions.php index 5da4d4142fd..07f093a77d0 100644 --- a/tests/unit-tests/util/conditional-functions.php +++ b/tests/unit-tests/util/conditional-functions.php @@ -97,6 +97,26 @@ class WC_Tests_Conditional_Functions extends WC_Unit_Test_Case { ); } + /** + * Test wc_site_is_https(). + */ + public function test_wc_site_is_https() { + $this->assertFalse( wc_site_is_https() ); + + add_filter( 'pre_option_home', [$this, '_https_url'] ); + + $this->assertTrue( wc_site_is_https() ); + } + + /** + * Callback for chaning home url to https. + * + * @return string + */ + public function _https_url() { + return 'https://example.org'; + } + /** * Test wc_is_valid_url(). * From 49e3275ad358ad1474fbdf5a2cebebf07b43d29b Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 14:42:14 +0100 Subject: [PATCH 195/298] Rewrite rule workarounds --- includes/wc-core-functions.php | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/includes/wc-core-functions.php b/includes/wc-core-functions.php index 93fba552936..42a2e65b93d 100644 --- a/includes/wc-core-functions.php +++ b/includes/wc-core-functions.php @@ -818,8 +818,41 @@ function wc_fix_rewrite_rules( $rules ) { unset( $rules[ $rule ] ); } } + + /** + * When the product base is set to %product_cat% (category base), this conflicts + * with posts (using /%postname%/ structure) and pages. To prevent this, unset + * the (.+?)/?$ rule which maps something like /product-cat-name/ to a product + * incorrectly. + * @since 2.7.0 + */ + } elseif ( '/%product_cat%' === $product_permalink ) { + unset( $rules[ '(.+?)/?$' ] ); + unset( $rules[ '(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$' ] ); + unset( $rules[ '(.+?)/(feed|rdf|rss|rss2|atom)/?$' ] ); } + echo '
    ';
    +	var_dump($rules);
    +	echo '
    '; + exit; + /* + string(43) "index.php?attachment=$matches[1]&embed=true" + ["(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$"]=> + string(50) "index.php?product_cat=$matches[1]&feed=$matches[2]" + ["(.+?)/(feed|rdf|rss|rss2|atom)/?$"]=> + string(50) "index.php?product_cat=$matches[1]&feed=$matches[2]" + ["(.+?)/embed/?$"]=> + string(44) "index.php?product_cat=$matches[1]&embed=true" + ["(.+?)/page/?([0-9]{1,})/?$"]=> + string(51) "index.php?product_cat=$matches[1]&paged=$matches[2]" + ["(.+?)/comment-page-([0-9]{1,})/?$"]=> + string(51) "index.php?product_cat=$matches[1]&cpage=$matches[2]" + ["(.+?)/wc-api(/(.*))?/?$"]=> + string(52) "index.php?product_cat=$matches[1]&wc-api=$matches[3]" + ["product_variation/[^/]+/attachment/([^/]+)/?$"]=> + */ + // If the shop page is used as the base, we need to handle shop page subpages to avoid 404s. if ( ! empty( $permalinks['use_verbose_page_rules'] ) && ( $shop_page_id = wc_get_page_id( 'shop' ) ) ) { $page_rewrite_rules = array(); From 569f2f55c46fa424ea9fabd516b15d98dc83c26d Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 15:48:24 +0100 Subject: [PATCH 196/298] Revert "Rewrite rule workarounds" This reverts commit 49e3275ad358ad1474fbdf5a2cebebf07b43d29b. --- includes/wc-core-functions.php | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/includes/wc-core-functions.php b/includes/wc-core-functions.php index 42a2e65b93d..93fba552936 100644 --- a/includes/wc-core-functions.php +++ b/includes/wc-core-functions.php @@ -818,41 +818,8 @@ function wc_fix_rewrite_rules( $rules ) { unset( $rules[ $rule ] ); } } - - /** - * When the product base is set to %product_cat% (category base), this conflicts - * with posts (using /%postname%/ structure) and pages. To prevent this, unset - * the (.+?)/?$ rule which maps something like /product-cat-name/ to a product - * incorrectly. - * @since 2.7.0 - */ - } elseif ( '/%product_cat%' === $product_permalink ) { - unset( $rules[ '(.+?)/?$' ] ); - unset( $rules[ '(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$' ] ); - unset( $rules[ '(.+?)/(feed|rdf|rss|rss2|atom)/?$' ] ); } - echo '
    ';
    -	var_dump($rules);
    -	echo '
    '; - exit; - /* - string(43) "index.php?attachment=$matches[1]&embed=true" - ["(.+?)/feed/(feed|rdf|rss|rss2|atom)/?$"]=> - string(50) "index.php?product_cat=$matches[1]&feed=$matches[2]" - ["(.+?)/(feed|rdf|rss|rss2|atom)/?$"]=> - string(50) "index.php?product_cat=$matches[1]&feed=$matches[2]" - ["(.+?)/embed/?$"]=> - string(44) "index.php?product_cat=$matches[1]&embed=true" - ["(.+?)/page/?([0-9]{1,})/?$"]=> - string(51) "index.php?product_cat=$matches[1]&paged=$matches[2]" - ["(.+?)/comment-page-([0-9]{1,})/?$"]=> - string(51) "index.php?product_cat=$matches[1]&cpage=$matches[2]" - ["(.+?)/wc-api(/(.*))?/?$"]=> - string(52) "index.php?product_cat=$matches[1]&wc-api=$matches[3]" - ["product_variation/[^/]+/attachment/([^/]+)/?$"]=> - */ - // If the shop page is used as the base, we need to handle shop page subpages to avoid 404s. if ( ! empty( $permalinks['use_verbose_page_rules'] ) && ( $shop_page_id = wc_get_page_id( 'shop' ) ) ) { $page_rewrite_rules = array(); From 3f8af04a4e028b01be5a7d865031c1761fcb576a Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 15:50:04 +0100 Subject: [PATCH 197/298] This should be disallowed Closes #11570 --- includes/admin/class-wc-admin-permalink-settings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/admin/class-wc-admin-permalink-settings.php b/includes/admin/class-wc-admin-permalink-settings.php index 01192eff1a4..8df1649d776 100644 --- a/includes/admin/class-wc-admin-permalink-settings.php +++ b/includes/admin/class-wc-admin-permalink-settings.php @@ -190,8 +190,8 @@ class WC_Admin_Permalink_Settings { } // This is an invalid base structure and breaks pages. - if ( '%product_cat%' == $product_permalink ) { - $product_permalink = '/' . _x( 'product', 'slug', 'woocommerce' ) . '/' . $product_permalink; + if ( '/%product_cat%' === $product_permalink ) { + $product_permalink = '/' . _x( 'product', 'slug', 'woocommerce' ) . $product_permalink; } } elseif ( empty( $product_permalink ) ) { $product_permalink = false; From 0bfaaa62c45640fd36de72ae9f79e8dc6f962881 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 16:19:30 +0100 Subject: [PATCH 198/298] Don't prevent submission when table is not found Fixes #11579 --- assets/js/frontend/cart.js | 3 ++- assets/js/frontend/cart.min.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/assets/js/frontend/cart.js b/assets/js/frontend/cart.js index bdd5cd608f6..bd9fca4ef6b 100644 --- a/assets/js/frontend/cart.js +++ b/assets/js/frontend/cart.js @@ -354,8 +354,9 @@ jQuery( function( $ ) { var $clicked = $( 'input[type=submit][clicked=true]' ); if ( 0 === $form.find( '.shop_table.cart' ).length ) { - return false; + return; } + if ( is_blocked( $form ) ) { return false; } diff --git a/assets/js/frontend/cart.min.js b/assets/js/frontend/cart.min.js index 9d3bf18662b..724d0b5bf88 100644 --- a/assets/js/frontend/cart.min.js +++ b/assets/js/frontend/cart.min.js @@ -1 +1 @@ -jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")||a.parents(".processing").length},d=function(a){c(a)||a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a(".shop_table.cart",c).closest("form"),e=a(".cart_totals",c),f=a(".woocommerce-error",c),i=a(".woocommerce-message",c);if(a(".woocommerce-error, .woocommerce-message").remove(),0===d.length){if(a(".woocommerce-checkout").length)return void window.location.reload();var j=a(".cart-empty",c).closest(".woocommerce");a(".shop_table.cart").closest(".woocommerce").replaceWith(j),f.length>0?h(f,a(".cart-empty").closest(".woocommerce")):i.length>0&&h(i,a(".cart-empty").closest(".woocommerce"))}else a(".woocommerce-checkout").length&&a(document.body).trigger("update_checkout"),a(".shop_table.cart").closest("form").replaceWith(d),a(".shop_table.cart").closest("form").find('input[name="update_cart"]').prop("disabled",!0),f.length>0?h(f):i.length>0&&h(i),g(e);a(document.body).trigger("updated_wc_div")},g=function(b){a(".cart_totals").replaceWith(b),a(document.body).trigger("updated_cart_totals")},h=function(b,c){c||(c=a(".shop_table.cart").closest("form")),a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)},i={init:function(b){this.cart=b,this.toggle_shipping=this.toggle_shipping.bind(this),this.shipping_method_selected=this.shipping_method_selected.bind(this),this.shipping_calculator_submit=this.shipping_calculator_submit.bind(this),a(document).on("click",".shipping-calculator-button",this.toggle_shipping),a(document).on("change","select.shipping_method, input[name^=shipping_method]",this.shipping_method_selected),a(document).on("submit","form.woocommerce-shipping-calculator",this.shipping_calculator_submit),a(".shipping-calculator-form").hide()},toggle_shipping:function(){return a(".shipping-calculator-form").slideToggle("slow"),!1},shipping_method_selected:function(c){var f=c.currentTarget,h={};a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){h[a(f).data("index")]=a(f).val()}),d(a("div.cart_totals"));var i={security:wc_cart_params.update_shipping_method_nonce,shipping_method:h};a.ajax({type:"post",url:b("update_shipping_method"),data:i,dataType:"html",success:function(a){g(a)},complete:function(){e(a("div.cart_totals")),a(document.body).trigger("updated_shipping_method")}})},shipping_calculator_submit:function(b){b.preventDefault();var c=a(b.currentTarget);d(a("div.cart_totals")),d(c),a("").attr("type","hidden").attr("name","calc_shipping").attr("value","x").appendTo(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:function(a){f(a)},complete:function(){e(c),e(a("div.cart_totals"))}})}},j={init:function(){this.update_cart_totals=this.update_cart_totals.bind(this),this.cart_submit=this.cart_submit.bind(this),this.submit_click=this.submit_click.bind(this),this.apply_coupon=this.apply_coupon.bind(this),this.remove_coupon_clicked=this.remove_coupon_clicked.bind(this),this.quantity_update=this.quantity_update.bind(this),this.item_remove_clicked=this.item_remove_clicked.bind(this),this.update_cart=this.update_cart.bind(this),a(document).on("wc_update_cart",this.update_cart),a(document).on("click","div.woocommerce > form input[type=submit]",this.submit_click),a(document).on("submit","div.woocommerce:not(.widget_product_search) > form",this.cart_submit),a(document).on("click","a.woocommerce-remove-coupon",this.remove_coupon_clicked),a(document).on("click","td.product-remove > a",this.item_remove_clicked),a(document).on("change input","div.woocommerce > form .cart_item :input",this.input_changed),a('div.woocommerce > form input[name="update_cart"]').prop("disabled",!0)},input_changed:function(){a('div.woocommerce > form input[name="update_cart"]').prop("disabled",!1)},update_cart:function(){var b=a(".shop_table.cart").closest("form");d(b),d(a("div.cart_totals")),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:function(a){f(a)},complete:function(){e(b),e(a("div.cart_totals"))}})},update_cart_totals:function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(a){g(a)},complete:function(){e(a("div.cart_totals"))}})},cart_submit:function(b){var d=a(b.currentTarget),e=a(document.activeElement),f=a("input[type=submit][clicked=true]");return 0!==d.find(".shop_table.cart").length&&(!c(d)&&void(f.is('[name="update_cart"]')||e.is("input.qty")?(b.preventDefault(),this.quantity_update(d)):(f.is('[name="apply_coupon"]')||e.is("#coupon_code"))&&(b.preventDefault(),this.apply_coupon(d))))},submit_click:function(b){a("input[type=submit]",a(b.target).parents("form")).removeAttr("clicked"),a(b.target).attr("clicked","true")},apply_coupon:function(c){d(c);var f=this,g=a("#coupon_code"),i=g.val(),j={security:wc_cart_params.apply_coupon_nonce,coupon_code:i};a.ajax({type:"POST",url:b("apply_coupon"),data:j,dataType:"html",success:function(b){h(b),a(document.body).trigger("applied_coupon")},complete:function(){e(c),g.val(""),f.update_cart_totals()}})},remove_coupon_clicked:function(c){c.preventDefault();var f=this,g=a(c.currentTarget).parents("tr"),i=a(c.currentTarget).attr("data-coupon");d(g.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(b){h(b),a(document.body).trigger("removed_coupon"),e(g.parents("table"))},complete:function(){f.update_cart_totals()}})},quantity_update:function(b){a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(b),d(b),d(a("div.cart_totals")),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:f,complete:function(){e(b),e(a("div.cart_totals"))}})},item_remove_clicked:function(b){b.preventDefault();var c=a(b.currentTarget),g=c.parents("form");d(g),d(a("div.cart_totals")),a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f,complete:function(){e(g),e(a("div.cart_totals"))}})}};i.init(j),j.init()}); \ No newline at end of file +jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")||a.parents(".processing").length},d=function(a){c(a)||a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a(".shop_table.cart",c).closest("form"),e=a(".cart_totals",c),f=a(".woocommerce-error",c),i=a(".woocommerce-message",c);if(a(".woocommerce-error, .woocommerce-message").remove(),0===d.length){if(a(".woocommerce-checkout").length)return void window.location.reload();var j=a(".cart-empty",c).closest(".woocommerce");a(".shop_table.cart").closest(".woocommerce").replaceWith(j),f.length>0?h(f,a(".cart-empty").closest(".woocommerce")):i.length>0&&h(i,a(".cart-empty").closest(".woocommerce"))}else a(".woocommerce-checkout").length&&a(document.body).trigger("update_checkout"),a(".shop_table.cart").closest("form").replaceWith(d),a(".shop_table.cart").closest("form").find('input[name="update_cart"]').prop("disabled",!0),f.length>0?h(f):i.length>0&&h(i),g(e);a(document.body).trigger("updated_wc_div")},g=function(b){a(".cart_totals").replaceWith(b),a(document.body).trigger("updated_cart_totals")},h=function(b,c){c||(c=a(".shop_table.cart").closest("form")),a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)},i={init:function(b){this.cart=b,this.toggle_shipping=this.toggle_shipping.bind(this),this.shipping_method_selected=this.shipping_method_selected.bind(this),this.shipping_calculator_submit=this.shipping_calculator_submit.bind(this),a(document).on("click",".shipping-calculator-button",this.toggle_shipping),a(document).on("change","select.shipping_method, input[name^=shipping_method]",this.shipping_method_selected),a(document).on("submit","form.woocommerce-shipping-calculator",this.shipping_calculator_submit),a(".shipping-calculator-form").hide()},toggle_shipping:function(){return a(".shipping-calculator-form").slideToggle("slow"),!1},shipping_method_selected:function(c){var f=c.currentTarget,h={};a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){h[a(f).data("index")]=a(f).val()}),d(a("div.cart_totals"));var i={security:wc_cart_params.update_shipping_method_nonce,shipping_method:h};a.ajax({type:"post",url:b("update_shipping_method"),data:i,dataType:"html",success:function(a){g(a)},complete:function(){e(a("div.cart_totals")),a(document.body).trigger("updated_shipping_method")}})},shipping_calculator_submit:function(b){b.preventDefault();var c=a(b.currentTarget);d(a("div.cart_totals")),d(c),a("").attr("type","hidden").attr("name","calc_shipping").attr("value","x").appendTo(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:function(a){f(a)},complete:function(){e(c),e(a("div.cart_totals"))}})}},j={init:function(){this.update_cart_totals=this.update_cart_totals.bind(this),this.cart_submit=this.cart_submit.bind(this),this.submit_click=this.submit_click.bind(this),this.apply_coupon=this.apply_coupon.bind(this),this.remove_coupon_clicked=this.remove_coupon_clicked.bind(this),this.quantity_update=this.quantity_update.bind(this),this.item_remove_clicked=this.item_remove_clicked.bind(this),this.update_cart=this.update_cart.bind(this),a(document).on("wc_update_cart",this.update_cart),a(document).on("click","div.woocommerce > form input[type=submit]",this.submit_click),a(document).on("submit","div.woocommerce:not(.widget_product_search) > form",this.cart_submit),a(document).on("click","a.woocommerce-remove-coupon",this.remove_coupon_clicked),a(document).on("click","td.product-remove > a",this.item_remove_clicked),a(document).on("change input","div.woocommerce > form .cart_item :input",this.input_changed),a('div.woocommerce > form input[name="update_cart"]').prop("disabled",!0)},input_changed:function(){a('div.woocommerce > form input[name="update_cart"]').prop("disabled",!1)},update_cart:function(){var b=a(".shop_table.cart").closest("form");d(b),d(a("div.cart_totals")),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:function(a){f(a)},complete:function(){e(b),e(a("div.cart_totals"))}})},update_cart_totals:function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(a){g(a)},complete:function(){e(a("div.cart_totals"))}})},cart_submit:function(b){var d=a(b.currentTarget),e=a(document.activeElement),f=a("input[type=submit][clicked=true]");if(0!==d.find(".shop_table.cart").length)return!c(d)&&void(f.is('[name="update_cart"]')||e.is("input.qty")?(b.preventDefault(),this.quantity_update(d)):(f.is('[name="apply_coupon"]')||e.is("#coupon_code"))&&(b.preventDefault(),this.apply_coupon(d)))},submit_click:function(b){a("input[type=submit]",a(b.target).parents("form")).removeAttr("clicked"),a(b.target).attr("clicked","true")},apply_coupon:function(c){d(c);var f=this,g=a("#coupon_code"),i=g.val(),j={security:wc_cart_params.apply_coupon_nonce,coupon_code:i};a.ajax({type:"POST",url:b("apply_coupon"),data:j,dataType:"html",success:function(b){h(b),a(document.body).trigger("applied_coupon")},complete:function(){e(c),g.val(""),f.update_cart_totals()}})},remove_coupon_clicked:function(c){c.preventDefault();var f=this,g=a(c.currentTarget).parents("tr"),i=a(c.currentTarget).attr("data-coupon");d(g.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(b){h(b),a(document.body).trigger("removed_coupon"),e(g.parents("table"))},complete:function(){f.update_cart_totals()}})},quantity_update:function(b){a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(b),d(b),d(a("div.cart_totals")),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:f,complete:function(){e(b),e(a("div.cart_totals"))}})},item_remove_clicked:function(b){b.preventDefault();var c=a(b.currentTarget),g=c.parents("form");d(g),d(a("div.cart_totals")),a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f,complete:function(){e(g),e(a("div.cart_totals"))}})}};i.init(j),j.init()}); \ No newline at end of file From 22133a92db35f27e5bec430fbfd4324da979c3e0 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 16:19:41 +0100 Subject: [PATCH 199/298] Avoid redirect if cart/checkout are the same --- includes/wc-template-functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 72c621f001f..461b590ebb4 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -27,7 +27,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' ) ) && WC()->cart->is_empty() && empty( $wp->query_vars['order-pay'] ) && ! isset( $wp->query_vars['order-received'] ) ) { + elseif ( is_page( wc_get_page_id( 'checkout' ) ) && wc_get_page_id( 'checkout' ) !== wc_get_page_id( 'cart' ) && WC()->cart->is_empty() && empty( $wp->query_vars['order-pay'] ) && ! isset( $wp->query_vars['order-received'] ) ) { wc_add_notice( __( 'Checkout is not available whilst your cart is empty.', 'woocommerce' ), 'notice' ); wp_redirect( wc_get_page_permalink( 'cart' ) ); exit; From 2ef55327b88347ca923ed334a1d15c3d4cd3a08c Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 1 Aug 2016 16:24:31 +0100 Subject: [PATCH 200/298] Don't allow variations to exist with invalid parents Closes #11567 --- includes/class-wc-product-variation.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/includes/class-wc-product-variation.php b/includes/class-wc-product-variation.php index 45adbbea4c3..5b67b67aeda 100644 --- a/includes/class-wc-product-variation.php +++ b/includes/class-wc-product-variation.php @@ -88,6 +88,11 @@ class WC_Product_Variation extends WC_Product { $this->product_type = 'variation'; $this->parent = ! empty( $args['parent'] ) ? $args['parent'] : wc_get_product( $this->id ); $this->post = ! empty( $this->parent->post ) ? $this->parent->post : array(); + + // The post parent is not a valid variable product so we should prevent this being created. + if ( ! is_a( $this->parent, 'WC_Product' ) ) { + throw new Exception( sprintf( 'Invalid parent for variation #%d', $this->variation_id ), 422 ); + } } /** From 9d07cf59b1b95f3c70e05f59acb228f754a3085c Mon Sep 17 00:00:00 2001 From: Fredrik Forsmo Date: Mon, 1 Aug 2016 18:08:42 +0200 Subject: [PATCH 201/298] Use long array syntax instead of short array syntax --- tests/unit-tests/util/conditional-functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit-tests/util/conditional-functions.php b/tests/unit-tests/util/conditional-functions.php index 07f093a77d0..2c347d25f8d 100644 --- a/tests/unit-tests/util/conditional-functions.php +++ b/tests/unit-tests/util/conditional-functions.php @@ -103,7 +103,7 @@ class WC_Tests_Conditional_Functions extends WC_Unit_Test_Case { public function test_wc_site_is_https() { $this->assertFalse( wc_site_is_https() ); - add_filter( 'pre_option_home', [$this, '_https_url'] ); + add_filter( 'pre_option_home', array( $this, '_https_url' ) ); $this->assertTrue( wc_site_is_https() ); } From e97acc82b5690a58694bcf915bd41d0e65da5836 Mon Sep 17 00:00:00 2001 From: Matias Saggiorato Date: Mon, 1 Aug 2016 15:22:39 -0300 Subject: [PATCH 202/298] Fixed emails not properly encoded in download URLs --- includes/wc-user-functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/wc-user-functions.php b/includes/wc-user-functions.php index 43ce6b7505e..40b611ba200 100644 --- a/includes/wc-user-functions.php +++ b/includes/wc-user-functions.php @@ -446,7 +446,7 @@ function wc_get_customer_available_downloads( $customer_id ) { array( 'download_file' => $product_id, 'order' => $result->order_key, - 'email' => $result->user_email, + 'email' => urlencode( $result->user_email ), 'key' => $result->download_id ), home_url( '/' ) From 1caa1e09f4938498aaefaaa2534a19dab9c0ed58 Mon Sep 17 00:00:00 2001 From: opportus Date: Tue, 2 Aug 2016 02:20:50 +0200 Subject: [PATCH 203/298] fixes #11588 --- includes/class-wc-breadcrumb.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-breadcrumb.php b/includes/class-wc-breadcrumb.php index 0b324c41f3c..018276f60bb 100644 --- a/includes/class-wc-breadcrumb.php +++ b/includes/class-wc-breadcrumb.php @@ -74,7 +74,7 @@ class WC_Breadcrumb { 'is_tax' ); - if ( ( ! is_front_page() && ! ( is_post_type_archive() && get_option( 'page_on_front' ) == wc_get_page_id( 'shop' ) ) ) || is_paged() ) { + if ( ( ! is_front_page() && ! ( is_post_type_archive() && get_option( 'page_on_front' ) === wc_get_page_id( 'shop' ) ) ) || is_paged() ) { foreach ( $conditionals as $conditional ) { if ( call_user_func( $conditional ) ) { call_user_func( array( $this, 'add_crumbs_' . substr( $conditional, 3 ) ) ); From 43af0aae869b9b907aaaed23178922214c51dece Mon Sep 17 00:00:00 2001 From: opportus Date: Tue, 2 Aug 2016 05:27:30 +0200 Subject: [PATCH 204/298] fixes #11588 - revision1 --- includes/class-wc-breadcrumb.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-breadcrumb.php b/includes/class-wc-breadcrumb.php index 018276f60bb..aba3d2f19cc 100644 --- a/includes/class-wc-breadcrumb.php +++ b/includes/class-wc-breadcrumb.php @@ -74,7 +74,7 @@ class WC_Breadcrumb { 'is_tax' ); - if ( ( ! is_front_page() && ! ( is_post_type_archive() && get_option( 'page_on_front' ) === wc_get_page_id( 'shop' ) ) ) || is_paged() ) { + if ( ( ! is_front_page() && ! ( is_post_type_archive() && intval( get_option( 'page_on_front' ) ) === wc_get_page_id( 'shop' ) ) ) || is_paged() ) { foreach ( $conditionals as $conditional ) { if ( call_user_func( $conditional ) ) { call_user_func( array( $this, 'add_crumbs_' . substr( $conditional, 3 ) ) ); From 0fbb38c03455433e9493ceab2dfc344c0b0e587a Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 2 Aug 2016 11:24:31 +0100 Subject: [PATCH 205/298] Fix instance link in zones screen --- assets/js/admin/wc-shipping-zones.js | 4 ++-- assets/js/admin/wc-shipping-zones.min.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/js/admin/wc-shipping-zones.js b/assets/js/admin/wc-shipping-zones.js index f32404941f9..2b98cb9da8b 100644 --- a/assets/js/admin/wc-shipping-zones.js +++ b/assets/js/admin/wc-shipping-zones.js @@ -213,14 +213,14 @@ return parseInt( method.method_order, 10 ); } ); - _.each( shipping_methods, function( shipping_method, instance_id ) { + _.each( shipping_methods, function( shipping_method ) { var class_name = 'method_disabled'; if ( 'yes' === shipping_method.enabled ) { class_name = 'method_enabled'; } - $method_list.append( '
  • ' + shipping_method.title + '
  • ' ); + $method_list.append( '
  • ' + shipping_method.title + '
  • ' ); } ); } else { $method_list.append( '
  • ' + data.strings.no_shipping_methods_offered + '
  • ' ); diff --git a/assets/js/admin/wc-shipping-zones.min.js b/assets/js/admin/wc-shipping-zones.min.js index 21506e4556b..53e3c280932 100644 --- a/assets/js/admin/wc-shipping-zones.min.js +++ b/assets/js/admin/wc-shipping-zones.min.js @@ -1 +1 @@ -!function(a,b,c,d){a(function(){function e(){var a={formatMatches:function(a){return 1===a?wc_enhanced_select_params.i18n_matches_1:wc_enhanced_select_params.i18n_matches_n.replace("%qty%",a)},formatNoMatches:function(){return wc_enhanced_select_params.i18n_no_matches},formatAjaxError:function(){return wc_enhanced_select_params.i18n_ajax_error},formatInputTooShort:function(a,b){var c=b-a.length;return 1===c?wc_enhanced_select_params.i18n_input_too_short_1:wc_enhanced_select_params.i18n_input_too_short_n.replace("%qty%",c)},formatInputTooLong:function(a,b){var c=a.length-b;return 1===c?wc_enhanced_select_params.i18n_input_too_long_1:wc_enhanced_select_params.i18n_input_too_long_n.replace("%qty%",c)},formatSelectionTooBig:function(a){return 1===a?wc_enhanced_select_params.i18n_selection_too_long_1:wc_enhanced_select_params.i18n_selection_too_long_n.replace("%qty%",a)},formatLoadMore:function(){return wc_enhanced_select_params.i18n_load_more},formatSearching:function(){return wc_enhanced_select_params.i18n_searching}};return a}var f=a(".wc-shipping-zones"),g=a(".wc-shipping-zone-rows"),h=a(".wc-shipping-zone-save"),i=c.template("wc-shipping-zone-row"),j=c.template("wc-shipping-zone-row-blank"),k=a.extend({minimumResultsForSearch:10,allowClear:!!a(this).data("allow_clear"),placeholder:a(this).data("placeholder"),matcher:function(a,b,c){return b.toUpperCase().indexOf(a.toUpperCase())>=0||c.attr("alt").toUpperCase().indexOf(a.toUpperCase())>=0}},e()),l=Backbone.Model.extend({changes:{},logChanges:function(a){var b=this.changes||{};_.each(a,function(a,c){b[c]=_.extend(b[c]||{zone_id:c},a)}),this.changes=b,this.trigger("change:zones")},discardChanges:function(a){var b=this.changes||{},c=null,d=_.indexBy(this.get("zones"),"zone_id");b[a]&&void 0!==b[a].zone_order&&(c=b[a].zone_order),delete b[a],null!==c&&d[a]&&d[a].zone_order!==c&&(b[a]=_.extend(b[a]||{},{zone_id:a,zone_order:c})),this.changes=b,0===_.size(this.changes)&&o.clearUnloadConfirmation()},save:function(){_.size(this.changes)?a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zones_save_changes",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,changes:this.changes},this.onSaveResponse,"json"):n.trigger("saved:zones")},onSaveResponse:function(a,c){"success"===c&&(a.success?(n.set("zones",a.data.zones),n.trigger("change:zones"),n.changes={},n.trigger("saved:zones")):window.alert(b.strings.save_failed))}}),m=Backbone.View.extend({rowTemplate:i,initialize:function(){this.listenTo(this.model,"change:zones",this.setUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.clearUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.render),g.on("change",{view:this},this.updateModelOnChange),g.on("sortupdate",{view:this},this.updateModelOnSort),a(window).on("beforeunload",{view:this},this.unloadConfirmation),h.on("click",{view:this},this.onSubmit),a(document.body).on("click",".add_shipping_method:not(.disabled)",{view:this},this.onAddShippingMethod),a(document.body).on("click",".wc-shipping-zone-add",{view:this},this.onAddNewRow),a(document.body).on("wc_backbone_modal_response",this.onAddShippingMethodSubmitted),a(document.body).on("change",".wc-shipping-zone-method-selector select",this.onChangeShippingMethodSelector)},block:function(){a(this.el).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a(this.el).unblock()},render:function(){var b=_.indexBy(this.model.get("zones"),"zone_id"),c=this;c.$el.empty(),c.unblock(),_.size(b)?(b=_.sortBy(b,function(a){return parseInt(a.zone_order,10)}),a.each(b,function(a,b){c.renderRow(b)})):c.$el.append(j),c.initRows()},renderRow:function(a){var b=this;b.$el.append(b.rowTemplate(a)),b.initRow(a)},initRow:function(a){var b=this,c=b.$el.find('tr[data-id="'+a.zone_id+'"]');_.each(a.zone_locations,function(a){if("string"===jQuery.type(a))c.find('option[value="'+a+'"]').prop("selected",!0);else if("postcode"===a.type){var b=c.find(".wc-shipping-zone-postcodes :input");b.val()?b.val(b.val()+"\n"+a.code):b.val(a.code),c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()}else c.find('option[value="'+a.type+":"+a.code+'"]').prop("selected",!0)}),a.zone_postcodes&&_.each(a.zone_postcodes,function(a){var b=c.find(".wc-shipping-zone-postcodes :input");b.val()?b.val(b.val()+"\n"+a.code):b.val(a.code),c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()}),b.renderShippingMethods(a.zone_id,a.shipping_methods),c.find(".view").show(),c.find(".edit").hide(),c.find(".wc-shipping-zone-edit").on("click",{view:this},this.onEditRow),c.find(".wc-shipping-zone-cancel-edit").on("click",{view:this},this.onCancelEditRow),c.find(".wc-shipping-zone-delete").on("click",{view:this},this.onDeleteRow),c.find(".wc-shipping-zone-postcodes-toggle").on("click",{view:this},this.onTogglePostcodes),!0===a.editing&&(c.addClass("editing"),c.find(".wc-shipping-zone-edit").trigger("click"))},initRows:function(){0===a("tbody.wc-shipping-zone-rows tr").length%2?f.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").addClass("odd"):f.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").removeClass("odd"),a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:50})},renderShippingMethods:function(c,d){var e=a('.wc-shipping-zones tr[data-id="'+c+'"]'),f=e.find(".wc-shipping-zone-methods ul");f.find(".wc-shipping-zone-method").remove(),_.size(d)?(d=_.sortBy(d,function(a){return parseInt(a.method_order,10)}),_.each(d,function(a,b){var c="method_disabled";"yes"===a.enabled&&(c="method_enabled"),f.append('
  • '+a.title+"
  • ")})):f.append('
  • '+b.strings.no_shipping_methods_offered+"
  • ")},onSubmit:function(a){a.data.view.block(),a.data.view.model.save(),a.preventDefault()},onAddNewRow:function(c){c.preventDefault();var d=c.data.view,e=d.model,f=_.indexBy(e.get("zones"),"zone_id"),g={},h=_.size(f),i=_.extend({},b.default_zone,{zone_id:"new-"+h+"-"+Date.now(),editing:!0});a(".wc-shipping-zones-blank-state").closest("tr").remove(),i.zone_order=1+_.max(_.pluck(f,"zone_order"),function(a){return parseInt(a,10)}),g[i.zone_id]=i,e.logChanges(g),d.renderRow(i),d.initRows()},onTogglePostcodes:function(b){b.preventDefault();var c=a(this).closest("tr");c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()},onEditRow:function(b){b.preventDefault(),b.data.view.model.trigger("change:zones"),a(this).closest("tr").addClass("editing"),a(this).closest("tr").find(".view").hide(),a(this).closest("tr").find(".edit").show(),a(".wc-shipping-zone-region-select:not(.enhanced)").select2(k),a(".wc-shipping-zone-region-select:not(.enhanced)").addClass("enhanced");var c=a(this).closest("tr").find(".add_shipping_method");c.addClass("disabled"),c.tipTip({attribute:"data-disabled-tip",fadeIn:50,fadeOut:50,delay:50})},onCancelEditRow:function(b){var c=b.data.view,d=c.model,e=a(this).closest("tr"),f=e.data("id"),g=_.indexBy(d.get("zones"),"zone_id");b.preventDefault(),d.discardChanges(f),g[f]&&(g[f].editing=!1,e.after(c.rowTemplate(g[f])),c.initRow(g[f])),e.remove(),c.initRows()},onDeleteRow:function(b){var c=b.data.view,d=c.model,e=_.indexBy(d.get("zones"),"zone_id"),f={},g=a(this).closest("tr"),h=a(this).closest("tr").data("id");b.preventDefault(),e[h]&&(delete e[h],f[h]=_.extend(f[h]||{},{deleted:"deleted"}),d.set("zones",e),d.logChanges(f)),g.remove(),c.initRows()},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,h.prop("disabled",!1)},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,h.prop("disabled",!0)},unloadConfirmation:function(a){if(a.data.view.needsUnloadConfirm)return a.returnValue=b.strings.unload_confirmation_msg,window.event.returnValue=b.strings.unload_confirmation_msg,b.strings.unload_confirmation_msg},updateModelOnChange:function(b){var c=b.data.view.model,d=a(b.target),e=d.closest("tr").data("id"),f=d.data("attribute"),g=d.val(),h=_.indexBy(c.get("zones"),"zone_id"),i={};h[e]&&h[e][f]===g||(i[e]={},i[e][f]=g),c.logChanges(i)},updateModelOnSort:function(b){var c=b.data.view,d=c.model,e=_.indexBy(d.get("zones"),"zone_id"),f=a("tbody.wc-shipping-zone-rows tr"),g={};_.each(f,function(b){var c=a(b).data("id"),d=null,f=parseInt(a(b).index(),10);e[c]&&(d=parseInt(e[c].zone_order,10)),d!==f&&(g[c]=_.extend(g[c]||{},{zone_order:f}))}),_.size(g)&&d.logChanges(g)},onAddShippingMethod:function(b){var c=a(this).closest("tr").data("id");b.preventDefault(),a(this).WCBackboneModal({template:"wc-modal-add-shipping-method",variable:{zone_id:c}}),a(".wc-shipping-zone-method-selector select").change()},onAddShippingMethodSubmitted:function(c,e,f){"wc-modal-add-shipping-method"===e&&(o.block(),a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zone_add_method",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,method_id:f.add_method_id,zone_id:f.zone_id},function(a,b){"success"===b&&a.success&&o.renderShippingMethods(f.zone_id,a.data.methods),o.unblock()},"json"))},onChangeShippingMethodSelector:function(){var b=a(this).find("option:selected").data("description");a(this).parent().find(".wc-shipping-zone-method-description").remove(),a(this).after('

    '+b+"

    "),a(this).closest("article").height(a(this).parent().height())}}),n=new l({zones:b.zones}),o=new m({model:n,el:g});o.render(),g.sortable({items:"tr",cursor:"move",axis:"y",handle:"td.wc-shipping-zone-sort",scrollSensitivity:40})})}(jQuery,shippingZonesLocalizeScript,wp,ajaxurl); \ No newline at end of file +!function(a,b,c,d){a(function(){function e(){var a={formatMatches:function(a){return 1===a?wc_enhanced_select_params.i18n_matches_1:wc_enhanced_select_params.i18n_matches_n.replace("%qty%",a)},formatNoMatches:function(){return wc_enhanced_select_params.i18n_no_matches},formatAjaxError:function(){return wc_enhanced_select_params.i18n_ajax_error},formatInputTooShort:function(a,b){var c=b-a.length;return 1===c?wc_enhanced_select_params.i18n_input_too_short_1:wc_enhanced_select_params.i18n_input_too_short_n.replace("%qty%",c)},formatInputTooLong:function(a,b){var c=a.length-b;return 1===c?wc_enhanced_select_params.i18n_input_too_long_1:wc_enhanced_select_params.i18n_input_too_long_n.replace("%qty%",c)},formatSelectionTooBig:function(a){return 1===a?wc_enhanced_select_params.i18n_selection_too_long_1:wc_enhanced_select_params.i18n_selection_too_long_n.replace("%qty%",a)},formatLoadMore:function(){return wc_enhanced_select_params.i18n_load_more},formatSearching:function(){return wc_enhanced_select_params.i18n_searching}};return a}var f=a(".wc-shipping-zones"),g=a(".wc-shipping-zone-rows"),h=a(".wc-shipping-zone-save"),i=c.template("wc-shipping-zone-row"),j=c.template("wc-shipping-zone-row-blank"),k=a.extend({minimumResultsForSearch:10,allowClear:!!a(this).data("allow_clear"),placeholder:a(this).data("placeholder"),matcher:function(a,b,c){return b.toUpperCase().indexOf(a.toUpperCase())>=0||c.attr("alt").toUpperCase().indexOf(a.toUpperCase())>=0}},e()),l=Backbone.Model.extend({changes:{},logChanges:function(a){var b=this.changes||{};_.each(a,function(a,c){b[c]=_.extend(b[c]||{zone_id:c},a)}),this.changes=b,this.trigger("change:zones")},discardChanges:function(a){var b=this.changes||{},c=null,d=_.indexBy(this.get("zones"),"zone_id");b[a]&&void 0!==b[a].zone_order&&(c=b[a].zone_order),delete b[a],null!==c&&d[a]&&d[a].zone_order!==c&&(b[a]=_.extend(b[a]||{},{zone_id:a,zone_order:c})),this.changes=b,0===_.size(this.changes)&&o.clearUnloadConfirmation()},save:function(){_.size(this.changes)?a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zones_save_changes",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,changes:this.changes},this.onSaveResponse,"json"):n.trigger("saved:zones")},onSaveResponse:function(a,c){"success"===c&&(a.success?(n.set("zones",a.data.zones),n.trigger("change:zones"),n.changes={},n.trigger("saved:zones")):window.alert(b.strings.save_failed))}}),m=Backbone.View.extend({rowTemplate:i,initialize:function(){this.listenTo(this.model,"change:zones",this.setUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.clearUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.render),g.on("change",{view:this},this.updateModelOnChange),g.on("sortupdate",{view:this},this.updateModelOnSort),a(window).on("beforeunload",{view:this},this.unloadConfirmation),h.on("click",{view:this},this.onSubmit),a(document.body).on("click",".add_shipping_method:not(.disabled)",{view:this},this.onAddShippingMethod),a(document.body).on("click",".wc-shipping-zone-add",{view:this},this.onAddNewRow),a(document.body).on("wc_backbone_modal_response",this.onAddShippingMethodSubmitted),a(document.body).on("change",".wc-shipping-zone-method-selector select",this.onChangeShippingMethodSelector)},block:function(){a(this.el).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a(this.el).unblock()},render:function(){var b=_.indexBy(this.model.get("zones"),"zone_id"),c=this;c.$el.empty(),c.unblock(),_.size(b)?(b=_.sortBy(b,function(a){return parseInt(a.zone_order,10)}),a.each(b,function(a,b){c.renderRow(b)})):c.$el.append(j),c.initRows()},renderRow:function(a){var b=this;b.$el.append(b.rowTemplate(a)),b.initRow(a)},initRow:function(a){var b=this,c=b.$el.find('tr[data-id="'+a.zone_id+'"]');_.each(a.zone_locations,function(a){if("string"===jQuery.type(a))c.find('option[value="'+a+'"]').prop("selected",!0);else if("postcode"===a.type){var b=c.find(".wc-shipping-zone-postcodes :input");b.val()?b.val(b.val()+"\n"+a.code):b.val(a.code),c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()}else c.find('option[value="'+a.type+":"+a.code+'"]').prop("selected",!0)}),a.zone_postcodes&&_.each(a.zone_postcodes,function(a){var b=c.find(".wc-shipping-zone-postcodes :input");b.val()?b.val(b.val()+"\n"+a.code):b.val(a.code),c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()}),b.renderShippingMethods(a.zone_id,a.shipping_methods),c.find(".view").show(),c.find(".edit").hide(),c.find(".wc-shipping-zone-edit").on("click",{view:this},this.onEditRow),c.find(".wc-shipping-zone-cancel-edit").on("click",{view:this},this.onCancelEditRow),c.find(".wc-shipping-zone-delete").on("click",{view:this},this.onDeleteRow),c.find(".wc-shipping-zone-postcodes-toggle").on("click",{view:this},this.onTogglePostcodes),!0===a.editing&&(c.addClass("editing"),c.find(".wc-shipping-zone-edit").trigger("click"))},initRows:function(){0===a("tbody.wc-shipping-zone-rows tr").length%2?f.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").addClass("odd"):f.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").removeClass("odd"),a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:50})},renderShippingMethods:function(c,d){var e=a('.wc-shipping-zones tr[data-id="'+c+'"]'),f=e.find(".wc-shipping-zone-methods ul");f.find(".wc-shipping-zone-method").remove(),_.size(d)?(d=_.sortBy(d,function(a){return parseInt(a.method_order,10)}),_.each(d,function(a){var b="method_disabled";"yes"===a.enabled&&(b="method_enabled"),f.append('
  • '+a.title+"
  • ")})):f.append('
  • '+b.strings.no_shipping_methods_offered+"
  • ")},onSubmit:function(a){a.data.view.block(),a.data.view.model.save(),a.preventDefault()},onAddNewRow:function(c){c.preventDefault();var d=c.data.view,e=d.model,f=_.indexBy(e.get("zones"),"zone_id"),g={},h=_.size(f),i=_.extend({},b.default_zone,{zone_id:"new-"+h+"-"+Date.now(),editing:!0});a(".wc-shipping-zones-blank-state").closest("tr").remove(),i.zone_order=1+_.max(_.pluck(f,"zone_order"),function(a){return parseInt(a,10)}),g[i.zone_id]=i,e.logChanges(g),d.renderRow(i),d.initRows()},onTogglePostcodes:function(b){b.preventDefault();var c=a(this).closest("tr");c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()},onEditRow:function(b){b.preventDefault(),b.data.view.model.trigger("change:zones"),a(this).closest("tr").addClass("editing"),a(this).closest("tr").find(".view").hide(),a(this).closest("tr").find(".edit").show(),a(".wc-shipping-zone-region-select:not(.enhanced)").select2(k),a(".wc-shipping-zone-region-select:not(.enhanced)").addClass("enhanced");var c=a(this).closest("tr").find(".add_shipping_method");c.addClass("disabled"),c.tipTip({attribute:"data-disabled-tip",fadeIn:50,fadeOut:50,delay:50})},onCancelEditRow:function(b){var c=b.data.view,d=c.model,e=a(this).closest("tr"),f=e.data("id"),g=_.indexBy(d.get("zones"),"zone_id");b.preventDefault(),d.discardChanges(f),g[f]&&(g[f].editing=!1,e.after(c.rowTemplate(g[f])),c.initRow(g[f])),e.remove(),c.initRows()},onDeleteRow:function(b){var c=b.data.view,d=c.model,e=_.indexBy(d.get("zones"),"zone_id"),f={},g=a(this).closest("tr"),h=a(this).closest("tr").data("id");b.preventDefault(),e[h]&&(delete e[h],f[h]=_.extend(f[h]||{},{deleted:"deleted"}),d.set("zones",e),d.logChanges(f)),g.remove(),c.initRows()},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,h.prop("disabled",!1)},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,h.prop("disabled",!0)},unloadConfirmation:function(a){if(a.data.view.needsUnloadConfirm)return a.returnValue=b.strings.unload_confirmation_msg,window.event.returnValue=b.strings.unload_confirmation_msg,b.strings.unload_confirmation_msg},updateModelOnChange:function(b){var c=b.data.view.model,d=a(b.target),e=d.closest("tr").data("id"),f=d.data("attribute"),g=d.val(),h=_.indexBy(c.get("zones"),"zone_id"),i={};h[e]&&h[e][f]===g||(i[e]={},i[e][f]=g),c.logChanges(i)},updateModelOnSort:function(b){var c=b.data.view,d=c.model,e=_.indexBy(d.get("zones"),"zone_id"),f=a("tbody.wc-shipping-zone-rows tr"),g={};_.each(f,function(b){var c=a(b).data("id"),d=null,f=parseInt(a(b).index(),10);e[c]&&(d=parseInt(e[c].zone_order,10)),d!==f&&(g[c]=_.extend(g[c]||{},{zone_order:f}))}),_.size(g)&&d.logChanges(g)},onAddShippingMethod:function(b){var c=a(this).closest("tr").data("id");b.preventDefault(),a(this).WCBackboneModal({template:"wc-modal-add-shipping-method",variable:{zone_id:c}}),a(".wc-shipping-zone-method-selector select").change()},onAddShippingMethodSubmitted:function(c,e,f){"wc-modal-add-shipping-method"===e&&(o.block(),a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zone_add_method",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,method_id:f.add_method_id,zone_id:f.zone_id},function(a,b){"success"===b&&a.success&&o.renderShippingMethods(f.zone_id,a.data.methods),o.unblock()},"json"))},onChangeShippingMethodSelector:function(){var b=a(this).find("option:selected").data("description");a(this).parent().find(".wc-shipping-zone-method-description").remove(),a(this).after('

    '+b+"

    "),a(this).closest("article").height(a(this).parent().height())}}),n=new l({zones:b.zones}),o=new m({model:n,el:g});o.render(),g.sortable({items:"tr",cursor:"move",axis:"y",handle:"td.wc-shipping-zone-sort",scrollSensitivity:40})})}(jQuery,shippingZonesLocalizeScript,wp,ajaxurl); \ No newline at end of file From 3c1f5e5e4679836f3625b5384b747af3f3f3376d Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 2 Aug 2016 14:06:46 +0100 Subject: [PATCH 206/298] Tweak geoip instruction Closes #11587 --- includes/admin/views/html-admin-page-status-report.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/admin/views/html-admin-page-status-report.php b/includes/admin/views/html-admin-page-status-report.php index 20c88d6763e..7c5ad8471c6 100644 --- a/includes/admin/views/html-admin-page-status-report.php +++ b/includes/admin/views/html-admin-page-status-report.php @@ -399,7 +399,7 @@ global $wpdb; if ( file_exists( WC_Geolocation::get_local_database_path() ) ) { echo ' ' . esc_html( WC_Geolocation::get_local_database_path() ) . ' '; } else { - printf( ' ' . sprintf( __( 'The MaxMind GeoIP Database does not exist - Geolocation will not function. You can download and install it manually from %1$s to the path: %2$s. Scroll down to \"Downloads\" and download the \"Binary / gzip\" file next to \"GeoLite Country\"', 'woocommerce' ), make_clickable( 'http://dev.maxmind.com/geoip/legacy/geolite/' ), '' . WC_Geolocation::get_local_database_path() . '' ) . '', WC_LOG_DIR ); + printf( ' ' . sprintf( __( 'The MaxMind GeoIP Database does not exist - Geolocation will not function. You can download and install it manually from %1$s to the path: %2$s. Scroll down to \"Downloads\" and download the \"Binary / gzip\" file next to \"GeoLite Country\". Please remember to uncompress GeoIP.dat.gz and upload the GeoIP.dat file only.', 'woocommerce' ), make_clickable( 'http://dev.maxmind.com/geoip/legacy/geolite/' ), '' . WC_Geolocation::get_local_database_path() . '' ) . '', WC_LOG_DIR ); } ?> From 674e00ea55f01ad201ee1f7f68dea0575255cba9 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 2 Aug 2016 14:09:56 +0100 Subject: [PATCH 207/298] [2.6] Prevent notice in wpdb_table_fix if termmeta table is not used --- woocommerce.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/woocommerce.php b/woocommerce.php index e34c518c717..d9ac569d708 100644 --- a/woocommerce.php +++ b/woocommerce.php @@ -481,11 +481,14 @@ final class WooCommerce { public function wpdb_table_fix() { global $wpdb; $wpdb->payment_tokenmeta = $wpdb->prefix . 'woocommerce_payment_tokenmeta'; - $wpdb->woocommerce_termmeta = $wpdb->prefix . 'woocommerce_termmeta'; $wpdb->order_itemmeta = $wpdb->prefix . 'woocommerce_order_itemmeta'; $wpdb->tables[] = 'woocommerce_payment_tokenmeta'; - $wpdb->tables[] = 'woocommerce_termmeta'; $wpdb->tables[] = 'woocommerce_order_itemmeta'; + + if ( get_option( 'db_version' ) < 34370 ) { + $wpdb->woocommerce_termmeta = $wpdb->prefix . 'woocommerce_termmeta'; + $wpdb->tables[] = 'woocommerce_termmeta'; + } } /** From 922ba0337f6c9ac6710ad65d76234f6ab2105611 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 2 Aug 2016 14:42:27 +0100 Subject: [PATCH 208/298] Fix removal and tweak buttons --- assets/css/admin.css | 2 +- assets/css/admin.scss | 7 ++++++- assets/js/accounting/accounting.min.js | 2 +- assets/js/admin/meta-boxes-order.min.js | 2 +- assets/js/admin/meta-boxes-product-variation.min.js | 2 +- assets/js/admin/meta-boxes-product.min.js | 2 +- assets/js/admin/meta-boxes.min.js | 2 +- assets/js/admin/reports.min.js | 2 +- .../js/admin/settings-views-html-settings-tax.min.js | 2 +- assets/js/admin/wc-shipping-classes.min.js | 2 +- assets/js/admin/wc-shipping-zone-methods.min.js | 2 +- assets/js/admin/wc-shipping-zones.min.js | 2 +- assets/js/admin/woocommerce_admin.min.js | 2 +- assets/js/frontend/add-payment-method.min.js | 2 +- assets/js/frontend/add-to-cart.min.js | 2 +- assets/js/frontend/cart-fragments.min.js | 2 +- assets/js/frontend/cart.min.js | 2 +- assets/js/frontend/checkout.min.js | 2 +- assets/js/frontend/single-product.min.js | 2 +- assets/js/jquery-blockui/jquery.blockUI.min.js | 2 +- assets/js/jquery-cookie/jquery.cookie.min.js | 2 +- assets/js/jquery-flot/jquery.flot.min.js | 4 ++-- assets/js/jquery-flot/jquery.flot.pie.min.js | 2 +- assets/js/jquery-flot/jquery.flot.stack.min.js | 2 +- assets/js/jquery-flot/jquery.flot.time.min.js | 2 +- assets/js/jquery-payment/jquery.payment.min.js | 2 +- assets/js/jquery-qrcode/jquery.qrcode.min.js | 2 +- .../jquery-serializejson/jquery.serializejson.min.js | 2 +- assets/js/jquery-tiptip/jquery.tipTip.min.js | 2 +- assets/js/prettyPhoto/jquery.prettyPhoto.min.js | 2 +- assets/js/round/round.min.js | 2 +- assets/js/select2/select2.min.js | 6 +++--- assets/js/zeroclipboard/jquery.zeroclipboard.min.js | 2 +- includes/admin/class-wc-admin-status.php | 7 +------ includes/admin/views/html-admin-page-status-logs.php | 12 +++++++----- includes/class-wc-logger.php | 6 ++++-- .../assets/js/simplify-commerce.min.js | 2 +- 37 files changed, 54 insertions(+), 50 deletions(-) diff --git a/assets/css/admin.css b/assets/css/admin.css index 3caf1811ce4..59b74e5cc2e 100644 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -1 +1 @@ -@charset "UTF-8";.button.wc-reload:after,.woocommerce-help-tip:after{speak:none;text-transform:none;-webkit-font-smoothing:antialiased}@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg)}}@-moz-keyframes spin{100%{-moz-transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}.select2-container{margin:0;position:relative;display:block!important;zoom:1;vertical-align:middle}.select2-container,.select2-drop,.select2-search,.select2-search input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{display:block;padding:0 0 0 8px;overflow:hidden;position:relative;border:1px solid #ccc;white-space:nowrap;color:#444;text-decoration:none;border-radius:3px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;font-weight:400}html[dir=rtl] .select2-container .select2-choice{padding:0 8px 0 0}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#ccc;border-radius:0 0 4px 4px}.select2-container.select2-allowclear .select2-choice .select2-chosen{margin-right:42px}.select2-container .select2-choice>.select2-chosen{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:none;width:auto}html[dir=rtl] .select2-container .select2-choice>.select2-chosen{margin-left:26px;margin-right:0}.select2-container .select2-choice abbr{display:none;width:12px;height:12px;position:absolute;right:24px;top:5px;font-size:1px;text-decoration:none;border:0;background:url(../images/select2.png) right top no-repeat;cursor:pointer;outline:0}.select2-container.select2-allowclear .select2-choice abbr{display:inline-block}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop-mask{border:0;margin:0;padding:0;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:9998;background-color:#fff;filter:alpha(opacity=0)}.select2-drop{width:100%;margin-top:-1px;position:absolute;top:100%;background:#fff;color:#000;border:1px solid #ccc;border-top:0;border-radius:0 0 3px 3px}.select2-drop.select2-drop-above{margin-top:1px;border-top:1px solid #ccc;border-bottom:0;border-radius:3px 3px 0 0}.select2-drop-active{border:1px solid #666;border-top:none}.select2-drop.select2-drop-above.select2-drop-active{border-top:1px solid #666}.select2-drop-auto-width{border-top:1px solid #ccc;width:auto}.select2-drop-auto-width .select2-search{padding-top:4px}.select2-container .select2-choice .select2-arrow{display:inline-block;width:18px;height:100%;position:absolute;right:0;top:0;border-radius:0 3px 3px 0;background-clip:padding-box}html[dir=rtl] .select2-container .select2-choice .select2-arrow{left:0;right:auto;border-radius:3px 0 0 3px}.select2-container .select2-choice .select2-arrow b{display:block;width:100%;height:100%;position:relative}.select2-container .select2-choice .select2-arrow b:after{position:absolute;display:block;content:"";top:50%;left:50%;border:4px solid transparent;border-top-color:#666;margin-left:-7px;margin-top:-2px}.select2-search{display:inline-block;width:100%;margin:0;padding-left:4px;padding-right:4px;position:relative;z-index:10000;white-space:nowrap;padding-bottom:4px}.select2-search input{width:100%;height:auto!important;padding:4px 20px 4px 5px!important;margin:0;outline:0;font-family:sans-serif;font-size:1em;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none;background:url(../images/select2.png) 100% -22px no-repeat #fff}html[dir=rtl] .select2-search input{padding:4px 5px 4px 20px;background:url(../images/select2.png) -37px -22px no-repeat #fff}.select2-drop.select2-drop-above .select2-search input{margin-top:4px}.select2-search input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff}.select2-container-active .select2-choice,.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-dropdown-open .select2-choice{border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-dropdown-open .select2-choice .select2-arrow b:after{border-top-color:transparent;border-bottom-color:#666;margin-top:-6px}.select2-dropdown-open.select2-drop-above .select2-choice,.select2-dropdown-open.select2-drop-above .select2-choices{border:1px solid #666;border-top-color:transparent}.select2-dropdown-open .select2-choice .select2-arrow{background:0 0;border-left:none;filter:none}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow{border-right:none}.select2-dropdown-open .select2-choice .select2-arrow b{background-position:-18px 1px}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow b{background-position:-16px 1px}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.select2-results{max-height:200px;padding:4px;margin:0;position:relative;overflow-x:hidden;overflow-y:auto;-webkit-tap-highlight-color:transparent;background:#fafafa}html[dir=rtl] .select2-results{padding:0 4px 0 0;margin:4px 0 4px 4px}.select2-results ul.select2-result-sub{margin:0;padding-left:0}.select2-results li{list-style:none;display:list-item;background-image:none;margin:3px 0}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:700}.select2-results .select2-result-label{padding:5px 7px;margin:0;cursor:pointer;min-height:1em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select2-results-dept-1 .select2-result-label{padding-left:20px}.select2-results-dept-2 .select2-result-label{padding-left:40px}.select2-results-dept-3 .select2-result-label{padding-left:60px}.select2-results-dept-4 .select2-result-label{padding-left:80px}.select2-results-dept-5 .select2-result-label{padding-left:100px}.select2-results-dept-6 .select2-result-label{padding-left:110px}.select2-results-dept-7 .select2-result-label{padding-left:120px}.select2-results .select2-highlighted{background:#f1f1f1;color:#000;border-radius:3px}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:0 0}.select2-results .select2-highlighted ul{background:#fff;color:#000}.select2-results .select2-ajax-error,.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item;padding-left:5px}.select2-results .select2-disabled.select2-highlighted{color:#666;background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-disabled{background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-selected{display:none}.select2-more-results.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #f4f4f4}.select2-results .select2-ajax-error{background:rgba(255,50,50,.2)}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice .select2-arrow{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container.select2-container-disabled .select2-choice abbr{display:none}.select2-container-multi .select2-choices{height:auto!important;height:1%;margin:0;padding:0 5px 0 0;position:relative;border:1px solid #ccc;cursor:text;overflow:hidden;background-color:#fff;min-height:26px}html[dir=rtl] .select2-container-multi .select2-choices{padding:0 0 0 5px}.select2-locked{padding:3px 5px!important}.select2-container-multi.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-container-multi .select2-choices li{float:left;list-style:none}html[dir=rtl] .select2-container-multi .select2-choices li{float:right}.select2-container-multi .select2-choices .select2-search-field{margin:0;padding:0;white-space:nowrap}.select2-container-multi .select2-choices .select2-search-field:first-child{width:100%}.select2-container-multi .select2-choices .select2-search-field input{margin:1px 0;outline:0;border:0;-webkit-box-shadow:none;box-shadow:none;background:0 0!important}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff!important}.select2-default{color:#999!important}.select2-container-multi .select2-choices .select2-search-choice{padding:5px 8px 5px 24px;margin:3px 0 3px 5px;position:relative;line-height:15px;color:#333;cursor:default;border-radius:2px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#e4e4e4}html[dir=rtl] .select2-container-multi .select2-choices .select2-search-choice{margin:3px 5px 3px 0;padding:5px 24px 5px 8px}.select2-container-multi .select2-choices .select2-search-choice .select2-chosen{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;width:12px;height:13px;position:absolute;right:7px;top:6px;font-size:1px;outline:0;background:url(../images/select2.png) right top no-repeat}html[dir=rtl] .select2-search-choice-close{right:auto;left:7px}.select2-container-multi .select2-search-choice-close{left:7px}html[dir=rtl] .select2-container-multi .select2-search-choice-close{left:auto;right:7px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover,.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{padding:3px 5px;border:1px solid #ddd;background-image:none;background-color:#f4f4f4}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none;background:0 0}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-match{text-decoration:underline}.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.select2-display-none{display:none}.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:2dppx){.select2-search input{background-image:url(../images/select2x2.png)!important;background-repeat:no-repeat!important;background-size:60px 40px!important;background-position:100% -21px!important}}@font-face{font-family:star;src:url(../fonts/star.eot);src:url(../fonts/star.eot?#iefix) format("embedded-opentype"),url(../fonts/star.woff) format("woff"),url(../fonts/star.ttf) format("truetype"),url(../fonts/star.svg#star) format("svg");font-weight:400;font-style:normal}@font-face{font-family:WooCommerce;src:url(../fonts/WooCommerce.eot);src:url(../fonts/WooCommerce.eot?#iefix) format("embedded-opentype"),url(../fonts/WooCommerce.woff) format("woff"),url(../fonts/WooCommerce.ttf) format("truetype"),url(../fonts/WooCommerce.svg#WooCommerce) format("svg");font-weight:400;font-style:normal}.blockUI.blockOverlay:before{height:1em;width:1em;position:absolute;top:50%;left:50%;margin-left:-.5em;margin-top:-.5em;display:block;content:"";-webkit-animation:spin 1s ease-in-out infinite;-moz-animation:spin 1s ease-in-out infinite;animation:spin 1s ease-in-out infinite;background:url(../images/icons/loader.svg) center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75)}.wc_addons_wrap .products{overflow:hidden}.wc_addons_wrap .products li{float:left;margin:0 1em 1em 0!important;padding:0;vertical-align:top;width:300px}.wc_addons_wrap .products li a{text-decoration:none;color:inherit;border:1px solid #ddd;display:block;min-height:220px;overflow:hidden;background:#f5f5f5;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1)}.wc_addons_wrap .products li a img{max-width:258px;max-height:24px;padding:17px 20px;display:block;margin:0;background:#fff;border-right:260px solid #fff}.wc_addons_wrap .products li a .price,.wc_addons_wrap .products li a img.extension-thumb+h3{display:none}.wc_addons_wrap .products li a h2,.wc_addons_wrap .products li a h3{margin:0!important;padding:20px!important;background:#fff}.wc_addons_wrap .products li a p{padding:20px!important;margin:0!important;border-top:1px solid #f1f1f1}.wc_addons_wrap .products li a:focus,.wc_addons_wrap .products li a:hover{background-color:#fff}.wc_addons_wrap .storefront{background:url(../images/storefront-bg.jpg) bottom right #f6f6f6;border:1px solid #ddd;padding:20px;overflow:hidden;zoom:1}.wc_addons_wrap .storefront img{width:278px;height:auto;float:left;margin:0 20px 0 0;box-shadow:0 1px 6px rgba(0,0,0,.1)}.wc_addons_wrap .storefront p{max-width:750px}.woocommerce-BlankState a.button-primary,.woocommerce-BlankState button.button-primary,.woocommerce-message a.button-primary,.woocommerce-message button.button-primary{background:#bb77ae;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;color:#fff;text-shadow:0 -1px 1px #A36597,1px 0 1px #A36597,0 1px 1px #A36597,-1px 0 1px #A36597}.woocommerce-BlankState a.button-primary:active,.woocommerce-BlankState a.button-primary:focus,.woocommerce-BlankState a.button-primary:hover,.woocommerce-BlankState button.button-primary:active,.woocommerce-BlankState button.button-primary:focus,.woocommerce-BlankState button.button-primary:hover,.woocommerce-message a.button-primary:active,.woocommerce-message a.button-primary:focus,.woocommerce-message a.button-primary:hover,.woocommerce-message button.button-primary:active,.woocommerce-message button.button-primary:focus,.woocommerce-message button.button-primary:hover{background:#A36597;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597}.woocommerce-message{position:relative;border-left-color:#cc99c2!important;overflow:hidden}.woocommerce-message a.docs,.woocommerce-message a.skip{text-decoration:none!important}.woocommerce-message a.woocommerce-message-close{position:absolute;top:10px;right:10px;padding:10px 15px 10px 21px;font-size:13px;line-height:1.23076923;text-decoration:none}.woocommerce-message a.woocommerce-message-close:before{position:absolute;top:8px;left:0;-webkit-transition:all .1s ease-in-out;transition:all .1s ease-in-out}.woocommerce-message .twitter-share-button{margin-top:-3px;margin-left:3px;vertical-align:middle}#variable_product_options #message,#variable_product_options .notice{margin:10px}.clear{clear:both}#woocommerce-fields-bulk.inline-edit-col label,#woocommerce-fields.inline-edit-col{clear:left}.wrap.woocommerce div.error,.wrap.woocommerce div.updated{margin-top:10px}mark.amount{background:0 0;color:inherit}.postbox,.woocommerce{input:invalid;input-border:1px solid #cc010b;input-background:#ffebe8}.simplify-commerce-banner{overflow:hidden}.simplify-commerce-banner img{float:right;padding:15px 0;margin-left:1em;width:200px}.woocommerce-help-tip{color:#666;display:inline-block;font-size:1.1em;font-style:normal;height:16px;line-height:16px;position:relative;vertical-align:middle;width:16px}.woocommerce-help-tip:after{font-family:Dashicons;font-weight:400;font-variant:normal;line-height:1;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";cursor:help}h2 .woocommerce-help-tip{margin-top:-5px;margin-left:.25em}table.wc_status_table{margin-bottom:1em}table.wc_status_table h2{font-size:14px;margin:0}table.wc_status_table tr:nth-child(2n) td,table.wc_status_table tr:nth-child(2n) th{background:#fcfcfc}table.wc_status_table th{font-weight:700;padding:9px}table.wc_status_table td:first-child{width:33%}table.wc_status_table td.help{width:1em}table.wc_status_table td{padding:9px;font-size:1.1em}table.wc_status_table td mark{background:0 0}table.wc_status_table td mark.yes{color:#7ad03a}table.wc_status_table td mark.no{color:#999}table.wc_status_table td mark.error{color:#a00}table.wc_status_table td ul{margin:0}table.wc_status_table .help_tip{cursor:help}#debug-report{display:none;margin:10px 0;padding:0;position:relative}#debug-report textarea{font-family:monospace;width:100%;margin:0;height:300px;padding:20px;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;resize:none;font-size:12px;line-height:20px;outline:0}#log-viewer-select{padding:10px 0 8px;line-height:180%}#log-viewer textarea{width:100%;resize:vertical}.inline-edit-product.quick-edit-row .inline-edit-col-center,.inline-edit-product.quick-edit-row .inline-edit-col-right{float:right!important}#woocommerce-fields.inline-edit-col label.featured,#woocommerce-fields.inline-edit-col label.manage_stock{margin-left:10px}#woocommerce-fields.inline-edit-col .dimensions div{display:block;margin:.2em 0}#woocommerce-fields.inline-edit-col .dimensions div span.title{display:block;float:left;width:5em}#woocommerce-fields.inline-edit-col .dimensions div span.input-text-wrap{display:block;margin-left:5em}#woocommerce-fields.inline-edit-col .text{box-sizing:border-box;width:99%;float:left;margin:1px 1% 1px 1px}#woocommerce-fields.inline-edit-col .height,#woocommerce-fields.inline-edit-col .length,#woocommerce-fields.inline-edit-col .width{width:32.33%}#woocommerce-fields.inline-edit-col .height{margin-right:0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group label{clear:none;width:49%;margin:.2em 0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group.dimensions label{width:75%;max-width:75%}#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .regular_price,#woocommerce-fields-bulk.inline-edit-col .sale_price,#woocommerce-fields-bulk.inline-edit-col .stock,#woocommerce-fields-bulk.inline-edit-col .weight{box-sizing:border-box;width:100%;margin-left:4.4em}#woocommerce-fields-bulk.inline-edit-col .height,#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .width{box-sizing:border-box;width:25%}.column-coupon_code{line-height:2.25em}.column-coupon_code,ul.wc_coupon_list{margin:0;overflow:hidden;zoom:1;clear:both}ul.wc_coupon_list li{margin:0}ul.wc_coupon_list li.code{display:inline-block}ul.wc_coupon_list li.code:after{content:", "}ul.wc_coupon_list li.code:last-of-type:after{display:none}ul.wc_coupon_list li.code .tips{cursor:pointer}ul.wc_coupon_list_block{margin:0;padding-bottom:2px}ul.wc_coupon_list_block li{border-top:1px solid #fff;border-bottom:1px solid #ccc;line-height:2.5em;margin:0;padding:.5em 0}ul.wc_coupon_list_block li:first-child{border-top:0;padding-top:0}ul.wc_coupon_list_block li:last-child{border-bottom:0;padding-bottom:0}.button.wc-reload{text-indent:-9999px;position:relative;padding:0;height:28px;width:28px!important;display:inline-block}.button.wc-reload:after{font-family:Dashicons;font-weight:400;font-variant:normal;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:28px}#order_data h2,#order_data p.order_number{font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif;font-weight:400}.tablenav .actions{overflow:visible}.tablenav .select2-container{float:left;max-width:200px;font-size:14px;vertical-align:middle;margin:1px 6px 1px 1px}#woocommerce-order-data .handlediv,#woocommerce-order-data .hndle{display:none}#woocommerce-order-data .inside{display:block!important}#order_data{padding:23px 24px 12px}#order_data h2{margin:0;font-size:21px;line-height:1.2;text-shadow:1px 1px 1px #fff;padding:0}#order_data h3{font-size:14px}#order_data h3,#order_data h4{color:#333;margin:1.33em 0 0}#order_data p{color:#777}#order_data p.order_number{margin:0;line-height:1.6em;font-size:16px}#order_data .order_data_column_container{clear:both}#order_data .order_data_column{width:32%;padding:0 2% 0 0;float:left}#order_data .order_data_column:last-child{padding-right:0}#order_data .order_data_column p{padding:0!important}#order_data .order_data_column .address strong{display:block}#order_data .order_data_column .form-field{float:left;width:48%;padding:0;margin:9px 0 0}#order_data .order_data_column .form-field label{display:block;padding:0 0 3px}#order_data .order_data_column .form-field input,#order_data .order_data_column .form-field select,#order_data .order_data_column .form-field textarea{width:100%}#order_data .order_data_column .form-field .select2-container{width:100%!important}#order_data .order_data_column .form-field .date-picker{width:50%}#order_data .order_data_column .form-field .hour,#order_data .order_data_column .form-field .minute{width:2.5em}#order_data .order_data_column .form-field small{display:block;margin:5px 0 0;color:#999}#order_data .order_data_column .form-field.last{float:right}#order_data .order_data_column .form-field-wide{width:100%;clear:both}#order_data .order_data_column .form-field-wide .wc-customer-search,#order_data .order_data_column .form-field-wide .wc-enhanced-select,#order_data .order_data_column .form-field-wide input,#order_data .order_data_column .form-field-wide select,#order_data .order_data_column .form-field-wide textarea{width:100%}#order_data .order_data_column p.none_set{color:#999}#order_data .order_data_column ._billing_address_1_field,#order_data .order_data_column ._billing_city_field,#order_data .order_data_column ._billing_country_field,#order_data .order_data_column ._billing_email_field,#order_data .order_data_column ._billing_first_name_field,#order_data .order_data_column ._shipping_address_1_field,#order_data .order_data_column ._shipping_city_field,#order_data .order_data_column ._shipping_country_field,#order_data .order_data_column ._shipping_first_name_field{float:left}#order_data .order_data_column ._billing_address_2_field,#order_data .order_data_column ._billing_last_name_field,#order_data .order_data_column ._billing_phone_field,#order_data .order_data_column ._billing_postcode_field,#order_data .order_data_column ._billing_state_field,#order_data .order_data_column ._shipping_address_2_field,#order_data .order_data_column ._shipping_last_name_field,#order_data .order_data_column ._shipping_postcode_field,#order_data .order_data_column ._shipping_state_field,#order_data .order_data_column .wc-customer-user label a,#order_data .order_data_column .wc-order-status label a{float:right}#order_data .order_data_column ._billing_company_field,#order_data .order_data_column ._shipping_company_field,#order_data .order_data_column ._transaction_id_field{clear:both;width:100%}#order_data .order_data_column ._billing_email_field{clear:left}#order_data .order_data_column div.edit_address{display:none;zoom:1;padding-right:1px}#order_data .order_data_column .billing-same-as-shipping,#order_data .order_data_column .load_customer_billing,#order_data .order_data_column .load_customer_shipping,#order_data .order_data_column a.edit_address{width:14px;height:0;padding:14px 0 0;margin:0 0 0 6px;overflow:hidden;position:relative;color:#999;border:0;float:right}#order_data .order_data_column .billing-same-as-shipping:focus,#order_data .order_data_column .billing-same-as-shipping:hover,#order_data .order_data_column .load_customer_billing:focus,#order_data .order_data_column .load_customer_billing:hover,#order_data .order_data_column .load_customer_shipping:focus,#order_data .order_data_column .load_customer_shipping:hover,#order_data .order_data_column a.edit_address:focus,#order_data .order_data_column a.edit_address:hover{color:#000}#order_data .order_data_column .billing-same-as-shipping:after,#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after,#order_data .order_data_column a.edit_address: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}#order_data .order_data_column .billing-same-as-shipping:after{content:"\e008"}#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after{content:"\e03a"}#order_data .order_data_column a.edit_address:after{font-family:Dashicons;content:"\f464"}.order_actions{margin:0;overflow:hidden;zoom:1}.order_actions li{border-top:1px solid #fff;border-bottom:1px solid #ddd;padding:6px 0;margin:0;line-height:1.6em;float:left;width:50%;text-align:center}.order_actions li a{float:none;text-align:center;text-decoration:underline}.order_actions li.wide{width:auto;float:none;clear:both;padding:6px;text-align:left;overflow:hidden}.order_actions li #delete-action{line-height:25px;vertical-align:middle;text-align:left;float:left}.order_actions li .save_order{float:right}.order_actions li#actions{overflow:hidden}.order_actions li#actions .button{width:24px;box-sizing:border-box;float:right}.order_actions li#actions select{width:225px;box-sizing:border-box;float:left}#woocommerce-order-items .inside{margin:0;padding:0;background:#fefefe}#woocommerce-order-items .wc-order-data-row{border-bottom:1px solid #DFDFDF;padding:1.5em 2em;background:#f8f8f8;line-height:2em;text-align:right}#woocommerce-order-items .wc-order-data-row:after,#woocommerce-order-items .wc-order-data-row:before{content:" ";display:table}#woocommerce-order-items .wc-order-data-row:after{clear:both}#woocommerce-order-items .wc-order-data-row p{margin:0;line-height:2em}#woocommerce-order-items .wc-order-data-row .wc-used-coupons{text-align:left}#woocommerce-order-items .wc-order-data-row .wc-used-coupons .tips{display:inline-block}#woocommerce-order-items .wc-order-add-item{background:#fff;vertical-align:top;border-top:none}#woocommerce-order-items .wc-order-add-item .add_item_id,#woocommerce-order-items .wc-order-add-item .select2-container{vertical-align:top}#woocommerce-order-items .wc-order-add-item .add_item_id .search-field input,#woocommerce-order-items .wc-order-add-item .select2-container .search-field input{min-width:100px}#woocommerce-order-items .wc-order-add-item .select2-container{width:400px!important;text-align:left}#woocommerce-order-items .wc-order-add-item .calculate-action,#woocommerce-order-items .wc-order-add-item .cancel-action,#woocommerce-order-items .wc-order-add-item .save-action{float:left;margin-right:2px}#woocommerce-order-items .wc-used-coupons{float:left;width:50%}#woocommerce-order-items .wc-order-totals{float:right;width:50%;margin:0;padding:0;text-align:right}#woocommerce-order-items .wc-order-totals .amount{font-weight:700}#woocommerce-order-items .wc-order-totals .label{vertical-align:top}#woocommerce-order-items .wc-order-totals .total{font-size:1em!important;width:10em;margin:0 0 0 .5em;box-sizing:border-box}#woocommerce-order-items .wc-order-totals .total input[type=text]{width:96%;float:right}#woocommerce-order-items .wc-order-totals .refunded-total{color:#a00}#woocommerce-order-items .refund-actions{margin-top:5px;padding-top:12px;border-top:1px solid #DFDFDF}#woocommerce-order-items .refund-actions .button{float:right;margin-left:4px}#woocommerce-order-items .refund-actions .cancel-action,#woocommerce-order-items .wc-order-item-bulk-edit .cancel-action{float:left;margin-left:0}#woocommerce-order-items .add_meta{margin-left:0!important}#woocommerce-order-items h3 small{color:#999}#woocommerce-order-items .amount{white-space:nowrap}#woocommerce-order-items .add-items .description{margin-right:10px}#woocommerce-order-items .add-items .button{float:left;margin-right:.25em}#woocommerce-order-items .add-items .button-primary{float:none;margin-right:0}#woocommerce-order-items .inside{display:block!important}#woocommerce-order-items .handlediv,#woocommerce-order-items .hndle{display:none}#woocommerce-order-items .woocommerce_order_items_wrapper{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items{width:100%;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th{text-align:left;padding:1em;font-weight:400;color:#999;background:#f8f8f8;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th.sortable{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th .wc-arrow{float:right;position:relative;margin-right:-1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td{padding:1.5em 1em 1em;text-align:left;line-height:1.5em;vertical-align:top;border-bottom:1px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td select{width:50%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{font-size:14px;padding:4px;color:#555}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr td{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected{background:#F5EBF3}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected td{border-color:#E6CCE1;opacity:.8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:last-child td{border-bottom:1px solid #dfdfdf}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:first-child td{border-top:8px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody#order_line_items tr:first-child td{border-top:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb{text-align:left;width:38px;padding-bottom:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail{width:38px;height:38px;border:2px solid #e8e8e8;background:#f8f8f8;color:#ccc;position:relative;font-size:21px;display:block;text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;height:100%;text-align:center;content:"";width:38px;line-height:38px;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail img{width:100%;height:100%;margin:0;padding:0;position:relative}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-sku,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-variation{display:block;margin-top:.5em;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item{min-width:200px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .center,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .variation-id{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class{text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label{white-space:nowrap;color:#999;font-size:.833em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label input{display:inline}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class input{width:70px;vertical-align:middle;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class select{width:85px;height:26px;vertical-align:middle;font-size:1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input{display:inline-block;background:#fff;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);margin:1px 0;min-width:80px;overflow:hidden;line-height:1em;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input{width:100%;box-sizing:border-box}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input label{font-size:.75em;padding:4px 6px 0;color:#555;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input{width:100%;box-sizing:border-box;border:0;box-shadow:none;margin:0;padding:0 6px 4px;color:#555;background:0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input::-webkit-input-placeholder{color:#ddd}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child{border-bottom:1px dashed #ddd;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child label{color:#ccc}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .view{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .edit{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes label{display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount{display:block;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{margin-right:.25em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input{text-align:center;width:50px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items span.subtotal{opacity:.5}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.tax_class,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.tax_class{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .calculated{border-color:#ae8ca2;border-style:dotted}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{margin:.5em 0 0;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{color:#ccc;top:0;left:0;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-align:center;font-family:WooCommerce}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr th{border:0;padding:0 4px .5em 0;line-height:1.5em;width:20%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td{padding:0 4px .5em 0;border:0;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input{width:100%;margin:0;position:relative;border-bottom:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .refund_by,ul.order_notes li p.meta .exact-date{border-bottom:1px dotted #999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td textarea{width:100%;height:4em;margin:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input:focus+textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input:focus+textarea{border-top-color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p{margin:0 0 .5em;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p:last-child{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method_name{width:100%;margin:0 0 .5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;float:right;font-size:14px;visibility:hidden;margin:3px -18px 0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:hover:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:hover:before{color:#a00}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax:hover .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax:hover .delete-order-tax{visibility:visible}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded{display:block;color:#a00;white-space:nowrap;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;width:100%;height:100%;text-align:center;content:"";position:relative;top:auto;left:auto;margin:-1px 4px 0 0;vertical-align:middle;line-height:1em}#woocommerce-order-items .wc-order-edit-line-item{padding-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions{width:44px;text-align:right;padding-left:0;vertical-align:middle}#woocommerce-order-items .wc-order-edit-line-item-actions a{color:#ccc;display:inline-block;cursor:pointer;padding:0 0 .5em;margin:0 0 0 12px;vertical-align:middle;text-decoration:none;line-height:16px;width:16px;overflow:hidden}#woocommerce-order-items .wc-order-edit-line-item-actions a:before{margin:0;padding:0;font-size:16px;width:16px;height:16px}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before,#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{font-family:Dashicons;-webkit-font-smoothing:antialiased;text-indent:0;top:0;left:0;width:100%;height:100%;margin:0;text-align:center;position:relative;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1}#woocommerce-order-items .wc-order-edit-line-item-actions a:hover:before{color:#999}#woocommerce-order-items .wc-order-edit-line-item-actions a:first-child{margin-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:hover:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:hover:before{color:#a00}#woocommerce-order-items tbody tr .wc-order-edit-line-item-actions{visibility:hidden}#woocommerce-order-items tbody tr:hover .wc-order-edit-line-item-actions{visibility:visible}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions{width:1.5em;visibility:visible!important}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions a{padding:0}#woocommerce-order-downloads .buttons{float:left;padding:0;margin:0;vertical-align:top}#woocommerce-order-downloads .buttons .add_item_id,#woocommerce-order-downloads .buttons .select2-container{width:400px!important;margin-right:9px;vertical-align:top;float:left}#woocommerce-order-downloads .buttons button{margin:2px 0 0}#woocommerce-order-downloads h3 small{color:#999}#poststuff #woocommerce-order-actions .inside{margin:0;padding:0}#poststuff #woocommerce-order-actions .inside ul.order_actions li{padding:6px 10px;box-sizing:border-box}#poststuff #woocommerce-order-actions .inside ul.order_actions li:last-child{border-bottom:0}#poststuff #woocommerce-order-notes .inside{margin:0;padding:0}#poststuff #woocommerce-order-notes .inside ul.order_notes li{padding:0 10px}#woocommerce_customers p.search-box{margin:6px 0 4px;float:left}#woocommerce_customers .tablenav{float:right;clear:none}.widefat.customers td{vertical-align:middle;padding:4px 7px}.widefat .column-order_title{width:15%}.widefat .column-order_title time{display:block;color:#999;margin:3px 0}.widefat .column-orders,.widefat .column-paying,.widefat .column-spent{text-align:center;width:8%}.widefat .column-last_order{width:11%}.widefat .column-order_actions,.widefat .column-user_actions,.widefat .column-wc_actions{width:110px}.widefat .column-order_actions a.button,.widefat .column-user_actions a.button,.widefat .column-wc_actions a.button{float:left;margin:0 4px 2px 0;cursor:pointer;padding:3px 4px;height:auto}.widefat .column-order_actions a.button img,.widefat .column-user_actions a.button img,.widefat .column-wc_actions a.button img{display:block;width:12px;height:auto}.widefat small.meta{display:block;color:#999;font-size:inherit;margin:3px 0}.widefat .column-order_date,.widefat .column-order_total{width:9%}.widefat .column-order_status{width:45px;text-align:center}.widefat .column-order_status mark{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;background:0 0;font-size:1.4em;margin:0 auto}.widefat .column-order_status mark.cancelled:after,.widefat .column-order_status mark.completed:after,.widefat .column-order_status mark.failed:after,.widefat .column-order_status mark.on-hold:after,.widefat .column-order_status mark.pending:after,.widefat .column-order_status mark.processing:after,.widefat .column-order_status mark.refunded:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.column-customer_message .note-on:after,.column-order_notes .note-on:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;left:0;text-align:center;line-height:16px;font-family:WooCommerce}.widefat .column-order_status mark.pending:after{content:"\e012";color:#ffba00}.widefat .column-order_status mark.completed:after{content:"\e015";color:#2ea2cc}.widefat .column-order_status mark.on-hold:after{content:"\e033";color:#999}.widefat .column-order_status mark.failed:after{content:"\e016";color:#d0c21f}.widefat .column-order_status mark.cancelled:after{content:"\e013";color:#a00}.widefat .column-order_status mark.processing:after{content:"\e011";color:#73a724}.widefat .column-order_status mark.refunded:after{content:"\e014";color:#999}.widefat td.column-order_status{padding-top:9px}.column-customer_message .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-customer_message .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.column-order_notes .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-order_notes .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.order_actions .complete,.order_actions .processing,.order_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.order_actions .processing:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.order_actions .complete:after,.order_actions .view:after{font-family:Dashicons;text-indent:0;position:absolute;width:100%;height:100%;left:0;line-height:1.85;margin:0;text-align:center;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;font-weight:400}.order_actions .complete:after{content:""}.order_actions .view:after{content:""}.user_actions .edit,.user_actions .link,.user_actions .refresh,.user_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.user_actions .edit:after,.user_actions .link:after,.user_actions .refresh:after,.user_actions .view:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.user_actions .edit:after{font-family:Dashicons;content:"\f464"}.user_actions .link:after{content:"\e00d"}.user_actions .view:after{content:"\e010"}.user_actions .refresh:after{content:"\e031"}.attributes-table td,.attributes-table th{width:15%;vertical-align:top}.attributes-table .attribute-terms{width:32%}.attributes-table .attribute-actions{width:2em}.attributes-table .attribute-actions .configure-terms{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.attributes-table .attribute-actions .configure-terms:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}ul.order_notes{padding:2px 0 0}ul.order_notes li .note_content{padding:10px;background:#efefef;position:relative}ul.order_notes li .note_content p{margin:0;padding:0;word-wrap:break-word}ul.order_notes li p.meta{padding:10px;color:#999;margin:0;font-size:11px}ul.order_notes li a.delete_note{color:#a00}table.wp-list-table .row-actions,table.wp-list-table span.na{color:#999}ul.order_notes li .note_content:after{content:"";display:block;position:absolute;bottom:-10px;left:20px;width:0;height:0;border-width:10px 10px 0 0;border-style:solid;border-color:#efefef transparent}ul.order_notes li.customer-note .note_content{background:#A7CEDC}ul.order_notes li.customer-note .note_content:after{border-color:#A7CEDC transparent}ul.order_notes li.system-note .note_content{background:#d7cad2}ul.order_notes li.system-note .note_content:after{border-color:#d7cad2 transparent}.add_note{border-top:1px solid #ddd;padding:10px 10px 0}.add_note h4{margin-top:5px!important}.add_note #add_order_note{width:100%;height:50px}table.wp-list-table .column-thumb{width:52px;text-align:center;white-space:nowrap}table.wp-list-table .column-name{width:22%}table.wp-list-table .column-product_cat,table.wp-list-table .column-product_tag{width:11%!important}table.wp-list-table .column-featured,table.wp-list-table .column-product_type{width:48px;text-align:left!important}table.wp-list-table .column-customer_message,table.wp-list-table .column-order_notes{width:48px;text-align:center}table.wp-list-table .column-customer_message img,table.wp-list-table .column-order_notes img{margin:0 auto;padding-top:0!important}table.wp-list-table .manage-column.column-featured img,table.wp-list-table .manage-column.column-product_type img{padding-left:2px}table.wp-list-table .column-price .woocommerce-price-suffix{display:none}table.wp-list-table img{margin:1px 2px}table.wp-list-table td.column-thumb img{margin:0;width:auto;height:auto;max-width:40px;max-height:40px;vertical-align:middle}table.wp-list-table .column-is_in_stock{text-align:left!important}table.wp-list-table span.wc-featured,table.wp-list-table span.wc-image,table.wp-list-table span.wc-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table span.wc-featured:before,table.wp-list-table span.wc-image:before,table.wp-list-table span.wc-type:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:""}table.wp-list-table span.wc-featured{margin:0;cursor:pointer}table.wp-list-table span.wc-featured:before{content:"\f155"}table.wp-list-table span.wc-featured.not-featured:before{content:"\f154"}table.wp-list-table td.column-featured span.wc-featured{font-size:1.6em}table.wp-list-table span.wc-type{margin:0}table.wp-list-table span.wc-type:before{font-family:WooCommerce;content:"\e006"}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after,table.wp-list-table span.product-type:before{font-family:WooCommerce;text-align:center;line-height:1;top:0;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;left:0}table.wp-list-table span.product-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.6em}table.wp-list-table span.product-type:before{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}table.wp-list-table span.product-type.grouped:before{content:"\e002"}table.wp-list-table span.product-type.external:before{content:"\e034"}table.wp-list-table span.product-type.variable:before{content:"\e003"}table.wp-list-table span.product-type.downloadable:before{content:"\e001"}table.wp-list-table span.product-type.virtual:before{content:"\e000"}table.wp-list-table mark.instock{font-weight:700;color:#7ad03a;background:0 0;line-height:1}table.wp-list-table mark.outofstock{font-weight:700;color:#a44;background:0 0;line-height:1}table.wp-list-table .notes_head,table.wp-list-table .order-notes_head,table.wp-list-table .status_head{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%}table.wc_emails .wc-email-settings-table-name,table.wc_emails td.name,table.wc_gateways .wc-email-settings-table-name,table.wc_gateways td.name,table.wc_shipping .wc-email-settings-table-name,table.wc_shipping td.name{font-weight:700}table.wp-list-table .order-notes_head:after{content:"\e028"}table.wp-list-table .notes_head:after{content:"\e026"}table.wp-list-table .status_head:after{content:"\e011"}table.wp-list-table .column-order_items{width:12%}table.wp-list-table .column-order_items table.order_items{width:100%;margin:3px 0 0;padding:0;display:none}table.wp-list-table .column-order_items table.order_items td{border:0;margin:0;padding:0 0 3px}table.wp-list-table .column-order_items table.order_items td.qty{color:#999;padding-right:6px;text-align:left}mark.notice{background:#fff;color:#a00;margin:0 0 0 10px}a.export_rates,a.import_rates{float:right;margin-left:9px;margin-top:-2px;margin-bottom:0}#rates-search{float:right}#rates-search input.wc-tax-rates-search-field{padding:4px 8px;font-size:1.2em}#rates-pagination{float:right;margin-right:.5em}#rates-pagination .tablenav{margin:0}table.wc_input_table,table.wc_tax_rates{width:100%}table.wc_input_table span.tips,table.wc_tax_rates span.tips{color:#2ea2cc}table.wc_input_table td,table.wc_tax_rates td{padding:0;border-right:1px solid #DFDFDF;border-bottom:1px solid #DFDFDF;border-top:0;background:#fff}table.wc_input_table td input[type=text],table.wc_input_table td input[type=number],table.wc_tax_rates td input[type=text],table.wc_tax_rates td input[type=number]{width:100%;padding:5px 7px;margin:0;border:0;background:0 0}table.wc_input_table td.apply_to_shipping,table.wc_input_table td.compound,table.wc_tax_rates td.apply_to_shipping,table.wc_tax_rates td.compound{padding:5px 7px;vertical-align:middle}table.wc_input_table td.apply_to_shipping input,table.wc_input_table td.compound input,table.wc_tax_rates td.apply_to_shipping input,table.wc_tax_rates td.compound input{width:auto;padding:0}table.wc_input_table td:last-child,table.wc_tax_rates td:last-child{border-right:0}table.wc_input_table tr.current td,table.wc_tax_rates tr.current td{background-color:#fefbcc}table.wc_input_table .cost,table.wc_input_table .cost input,table.wc_input_table .item_cost,table.wc_input_table .item_cost input,table.wc_tax_rates .cost,table.wc_tax_rates .cost input,table.wc_tax_rates .item_cost,table.wc_tax_rates .item_cost input{text-align:right}table.wc_input_table th.sort,table.wc_tax_rates th.sort{width:17px;padding:0 4px}table.wc_input_table td.sort,table.wc_tax_rates td.sort{padding:0 4px}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort{cursor:move;font-size:15px;background:#f9f9f9;text-align:center;vertical-align:middle}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before{color:#333}table.wc_input_table .button,table.wc_tax_rates .button{float:left;margin-right:5px}table.wc_input_table .export,table.wc_input_table .import,table.wc_tax_rates .export,table.wc_tax_rates .import{float:right;margin-right:0;margin-left:5px}table.wc_input_table span.tips,table.wc_tax_rates span.tips{padding:0 3px}table.wc_input_table .pagination,table.wc_tax_rates .pagination{float:right}table.wc_input_table .pagination .button,table.wc_tax_rates .pagination .button{margin-left:5px;margin-right:0}table.wc_input_table .pagination .current,table.wc_tax_rates .pagination .current{background:#bbb;text-shadow:none}table.wc_input_table tfoot th,table.wc_tax_rates tfoot th{padding-left:20px;padding-right:20px}table.wc_input_table tr:last-child td,table.wc_tax_rates tr:last-child td{border-bottom:0}table.wc_emails,table.wc_gateways,table.wc_shipping{position:relative}table.wc_emails td,table.wc_gateways td,table.wc_shipping td{vertical-align:middle;padding:7px;line-height:2em}table.wc_emails tr:nth-child(odd) td,table.wc_gateways tr:nth-child(odd) td,table.wc_shipping tr:nth-child(odd) td{background:#f9f9f9}table.wc_emails th,table.wc_gateways th,table.wc_shipping th{padding:9px 7px!important;vertical-align:middle}table.wc_emails .settings,table.wc_gateways .settings,table.wc_shipping .settings{text-align:right}table.wc_emails .default,table.wc_emails .radio,table.wc_emails .status,table.wc_gateways .default,table.wc_gateways .radio,table.wc_gateways .status,table.wc_shipping .default,table.wc_shipping .radio,table.wc_shipping .status{text-align:center}table.wc_emails .default .tips,table.wc_emails .radio .tips,table.wc_emails .status .tips,table.wc_gateways .default .tips,table.wc_gateways .radio .tips,table.wc_gateways .status .tips,table.wc_shipping .default .tips,table.wc_shipping .radio .tips,table.wc_shipping .status .tips{margin:0 auto}table.wc_emails .default input,table.wc_emails .radio input,table.wc_emails .status input,table.wc_gateways .default input,table.wc_gateways .radio input,table.wc_gateways .status input,table.wc_shipping .default input,table.wc_shipping .radio input,table.wc_shipping .status input{margin:0}table.wc_emails th.sort,table.wc_gateways th.sort,table.wc_shipping th.sort{width:28px;padding:0}table.wc_emails td.sort,table.wc_gateways td.sort,table.wc_shipping td.sort{padding:0 7px;cursor:move;font-size:15px;text-align:center;vertical-align:middle}table.wc_emails td.sort:before,table.wc_gateways td.sort:before,table.wc_shipping td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_emails .wc-email-settings-table-name span,table.wc_gateways .wc-email-settings-table-name span,table.wc_shipping .wc-email-settings-table-name span{font-weight:400;color:#999;margin:0 0 0 4px!important}table.wc_emails .wc-email-settings-table-status,table.wc_gateways .wc-email-settings-table-status,table.wc_shipping .wc-email-settings-table-status{text-align:center;width:1em}table.wc_emails .wc-email-settings-table-status .tips,table.wc_gateways .wc-email-settings-table-status .tips,table.wc_shipping .wc-email-settings-table-status .tips{margin:0 auto}table.wc_emails .wc-email-settings-table-actions a,table.wc_gateways .wc-email-settings-table-actions a,table.wc_shipping .wc-email-settings-table-actions a{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}table.wc_emails .wc-email-settings-table-actions a:after,table.wc_gateways .wc-email-settings-table-actions a:after,table.wc_shipping .wc-email-settings-table-actions a:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}table.wc-shipping-classes td,table.wc-shipping-classes th,table.wc-shipping-zone-methods td,table.wc-shipping-zone-methods th,table.wc-shipping-zones td,table.wc-shipping-zones th{vertical-align:top;line-height:24px;padding:1em;font-size:14px;background:#fff}table.wc-shipping-classes td li,table.wc-shipping-classes th li,table.wc-shipping-zone-methods td li,table.wc-shipping-zone-methods th li,table.wc-shipping-zones td li,table.wc-shipping-zones th li{line-height:24px;font-size:14px}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state,table.wc-shipping-classes td.wc-shipping-zones-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state,table.wc-shipping-zones td.wc-shipping-zones-blank-state{background:#F7F1F6!important;overflow:hidden;position:relative;padding:7.5em 7.5%;border-bottom:2px solid #EEE2EC}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zones td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state p{color:#a46497;font-size:1.5em;line-height:1.5em;margin:0 0 1em;position:relative;z-index:1;text-shadow:1px 1px 1px #fff}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state p.main{font-size:2em}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state li{margin-left:1em;list-style:circle inside}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-classes td.wc-shipping-zones-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state:before,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zones td.wc-shipping-zones-blank-state:before{content:"\e01b";font-family:WooCommerce;text-align:center;line-height:1;color:#EEE2EC;display:block;width:1em;font-size:40em;top:50%;right:-3.75%;margin-top:-.1875em;position:absolute}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-classes td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zones-blank-state .button-primary{background-color:#804877;border-color:#804877;-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);margin:0;opacity:1;text-shadow:0 -1px 1px #8a4f7f,1px 0 1px #8a4f7f,0 1px 1px #8a4f7f,-1px 0 1px #8a4f7f;font-size:1.5em;padding:.75em 1em;height:auto;position:relative;z-index:1}table.wc-shipping-classes .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-classes .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-classes tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-classes tr.odd td,table.wc-shipping-zone-methods .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tr.odd td,table.wc-shipping-zones .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zones .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zones tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zones tr.odd td{background:#f9f9f9}table.wc-shipping-classes p,table.wc-shipping-classes ul,table.wc-shipping-zone-methods p,table.wc-shipping-zone-methods ul,table.wc-shipping-zones p,table.wc-shipping-zones ul{margin:0}table.wc-shipping-classes td.wc-shipping-zone-method-sort,table.wc-shipping-classes td.wc-shipping-zone-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-sort,table.wc-shipping-zones td.wc-shipping-zone-method-sort,table.wc-shipping-zones td.wc-shipping-zone-sort{cursor:move;font-size:15px;text-align:center}table.wc-shipping-classes td.wc-shipping-zone-method-sort:before,table.wc-shipping-classes td.wc-shipping-zone-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:before,table.wc-shipping-zones td.wc-shipping-zone-sort:before{content:"\f333";font-family:Dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-classes td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-sort:hover:before{color:#333}table.wc-shipping-classes td.wc-shipping-zone-worldwide,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide,table.wc-shipping-zones td.wc-shipping-zone-worldwide{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-worldwide:before,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide:before,table.wc-shipping-zones td.wc-shipping-zone-worldwide:before{content:"\f319";font-family:dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes .wc-shipping-zone-methods,table.wc-shipping-classes .wc-shipping-zone-name,table.wc-shipping-zone-methods .wc-shipping-zone-methods,table.wc-shipping-zone-methods .wc-shipping-zone-name,table.wc-shipping-zones .wc-shipping-zone-methods,table.wc-shipping-zones .wc-shipping-zone-name{width:25%}table.wc-shipping-classes .wc-shipping-class-description input,table.wc-shipping-classes .wc-shipping-class-description select,table.wc-shipping-classes .wc-shipping-class-description textarea,table.wc-shipping-classes .wc-shipping-class-name input,table.wc-shipping-classes .wc-shipping-class-name select,table.wc-shipping-classes .wc-shipping-class-name textarea,table.wc-shipping-classes .wc-shipping-class-slug input,table.wc-shipping-classes .wc-shipping-class-slug select,table.wc-shipping-classes .wc-shipping-class-slug textarea,table.wc-shipping-classes .wc-shipping-zone-name input,table.wc-shipping-classes .wc-shipping-zone-name select,table.wc-shipping-classes .wc-shipping-zone-name textarea,table.wc-shipping-classes .wc-shipping-zone-region input,table.wc-shipping-classes .wc-shipping-zone-region select,table.wc-shipping-classes .wc-shipping-zone-region textarea,table.wc-shipping-zone-methods .wc-shipping-class-description input,table.wc-shipping-zone-methods .wc-shipping-class-description select,table.wc-shipping-zone-methods .wc-shipping-class-description textarea,table.wc-shipping-zone-methods .wc-shipping-class-name input,table.wc-shipping-zone-methods .wc-shipping-class-name select,table.wc-shipping-zone-methods .wc-shipping-class-name textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug input,table.wc-shipping-zone-methods .wc-shipping-class-slug select,table.wc-shipping-zone-methods .wc-shipping-class-slug textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name input,table.wc-shipping-zone-methods .wc-shipping-zone-name select,table.wc-shipping-zone-methods .wc-shipping-zone-name textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region input,table.wc-shipping-zone-methods .wc-shipping-zone-region select,table.wc-shipping-zone-methods .wc-shipping-zone-region textarea,table.wc-shipping-zones .wc-shipping-class-description input,table.wc-shipping-zones .wc-shipping-class-description select,table.wc-shipping-zones .wc-shipping-class-description textarea,table.wc-shipping-zones .wc-shipping-class-name input,table.wc-shipping-zones .wc-shipping-class-name select,table.wc-shipping-zones .wc-shipping-class-name textarea,table.wc-shipping-zones .wc-shipping-class-slug input,table.wc-shipping-zones .wc-shipping-class-slug select,table.wc-shipping-zones .wc-shipping-class-slug textarea,table.wc-shipping-zones .wc-shipping-zone-name input,table.wc-shipping-zones .wc-shipping-zone-name select,table.wc-shipping-zones .wc-shipping-zone-name textarea,table.wc-shipping-zones .wc-shipping-zone-region input,table.wc-shipping-zones .wc-shipping-zone-region select,table.wc-shipping-zones .wc-shipping-zone-region textarea{width:100%}table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-zone-delete{color:red}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle{float:right;margin:0;font-size:.9em;text-decoration:underline}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes{display:none}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea{margin-top:1em}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes .description{font-size:.9em;color:#999}table.wc-shipping-classes .wc-shipping-class-count,table.wc-shipping-zone-methods .wc-shipping-class-count,table.wc-shipping-zones .wc-shipping-class-count{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-methods,table.wc-shipping-zone-methods td.wc-shipping-zone-methods,table.wc-shipping-zones td.wc-shipping-zone-methods{color:#999}table.wc-shipping-classes td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .method_disabled{text-decoration:line-through}table.wc-shipping-classes td.wc-shipping-zone-methods ul,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul,table.wc-shipping-zones td.wc-shipping-zone-methods ul{color:#999;position:relative;padding-right:32px}table.wc-shipping-classes td.wc-shipping-zone-methods ul li,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li,table.wc-shipping-zones td.wc-shipping-zone-methods ul li{display:inline;margin:0}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:before{content:", "}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-classes td.wc-shipping-zone-methods ul li:last-child:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:last-child:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:last-child:before{content:""}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:last-child,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:last-child,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:last-child{display:block}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child{margin:0!important}table.wc-shipping-classes td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zones td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row{position:absolute;right:0;top:0}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method{display:block;width:24px;padding:24px 0 0;height:0;overflow:hidden;cursor:pointer}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method:before{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;font-family:Dashicons;content:"\f502";color:#999;vertical-align:middle;line-height:24px;font-size:16px;margin:0}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled:before{line-height:inherit}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled{margin-top:1px;display:inline-block}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled{cursor:not-allowed}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled:before{color:#ccc}table.wc-shipping-classes .wc-shipping-zone-method-title,table.wc-shipping-zone-methods .wc-shipping-zone-method-title,table.wc-shipping-zones .wc-shipping-zone-method-title{width:33%}table.wc-shipping-classes .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zone-methods .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zones .wc-shipping-zone-method-title .wc-shipping-zone-method-delete{color:red}table.wc-shipping-classes .wc-shipping-zone-method-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled{text-align:center}table.wc-shipping-classes tfoot input,table.wc-shipping-classes tfoot select,table.wc-shipping-zone-methods tfoot input,table.wc-shipping-zone-methods tfoot select,table.wc-shipping-zones tfoot input,table.wc-shipping-zones tfoot select{vertical-align:middle!important}table.wc-shipping-classes tfoot .button-secondary,table.wc-shipping-zone-methods tfoot .button-secondary,table.wc-shipping-zones tfoot .button-secondary{float:right}table.wc-shipping-classes .editing .wc-shipping-zone-edit,table.wc-shipping-classes .editing .wc-shipping-zone-view,table.wc-shipping-zone-methods .editing .wc-shipping-zone-edit,table.wc-shipping-zone-methods .editing .wc-shipping-zone-view,table.wc-shipping-zones .editing .wc-shipping-zone-edit,table.wc-shipping-zones .editing .wc-shipping-zone-view{display:none}.wc-modal-shipping-method-settings{background:#f8f8f8;padding:1em!important}.wc-modal-shipping-method-settings form .form-table{width:100%;background:#fff;margin:0 0 1.5em}.wc-modal-shipping-method-settings form .form-table tr th{width:30%;position:relative}.wc-modal-shipping-method-settings form .form-table tr th .woocommerce-help-tip{float:right;margin:-8px -.5em 0 0;vertical-align:middle;right:0;top:50%;position:absolute}.wc-modal-shipping-method-settings form .form-table tr td input,.wc-modal-shipping-method-settings form .form-table tr td select,.wc-modal-shipping-method-settings form .form-table tr td textarea{width:50%;min-width:250px}.wc-modal-shipping-method-settings form .form-table tr td input[type=checkbox]{width:auto;min-width:0}.wc-modal-shipping-method-settings form .form-table tr td,.wc-modal-shipping-method-settings form .form-table tr th{vertical-align:middle;margin:0;line-height:24px;padding:1em;border-bottom:1px solid #f8f8f8}.wc-modal-shipping-method-settings form .form-table:last-of-type{margin-bottom:0}.wc-backbone-modal .wc-shipping-zone-method-selector p{margin-top:0}.wc-backbone-modal .wc-shipping-zone-method-selector .wc-shipping-zone-method-description{margin:.75em 1px 0;line-height:1.5em;color:#999;font-style:italic}.wc-backbone-modal .wc-shipping-zone-method-selector select{width:100%;cursor:pointer}img.help_tip{margin:0 0 0 9px;vertical-align:middle}.postbox img.help_tip{margin-top:0}.postbox .woocommerce-help-tip{margin:0 0 0 9px}.status-disabled,.status-enabled,.status-manual{font-size:1.4em;display:block;text-indent:-9999px;position:relative;height:1em;width:1em}.status-disabled:before,.status-enabled:before,.status-manual:before{font-family:WooCommerce;line-height:1;margin:0;position:absolute;width:100%;height:100%;text-indent:0;top:0;font-variant:normal;-webkit-font-smoothing:antialiased;font-weight:400;text-align:center;left:0;speak:none;text-transform:none}.status-manual:before{content:"";color:#999}.status-enabled:before{content:"";color:#a46497}.status-disabled:before{content:"";color:#ccc}.woocommerce h2.woo-nav-tab-wrapper{margin-bottom:1em}.woocommerce nav.woo-nav-tab-wrapper{margin:1.5em 0 1em;border-bottom:1px solid #ccc}.woocommerce .subsubsub{margin:-8px 0 0}.woocommerce .wc-admin-breadcrumb{margin-left:.5em}.woocommerce .wc-admin-breadcrumb a{color:#a46497}.woocommerce #template div{margin:0}.woocommerce #template div p .button{float:right;margin-left:10px;margin-top:-4px}.woocommerce #template div .editor textarea{margin-bottom:8px}.woocommerce textarea[disabled=disabled]{background:#DFDFDF!important}.woocommerce table.form-table{margin:0;position:relative}.woocommerce table.form-table .forminp-radio ul{margin:0}.woocommerce table.form-table .forminp-radio ul li{line-height:1.4em}.woocommerce table.form-table textarea.input-text{height:100%;min-width:150px;display:block}.woocommerce table.form-table input.regular-input{width:25em}.woocommerce table.form-table textarea.wide-input{width:100%}.woocommerce table.form-table .woocommerce-help-tip,.woocommerce table.form-table img.help_tip{padding:0;margin:-4px 0 0 5px;vertical-align:middle;cursor:help;line-height:1}.woocommerce table.form-table span.help_tip{cursor:help;color:#2ea2cc}.woocommerce table.form-table th{position:relative;padding-right:24px}.woocommerce table.form-table .select2-container{display:block;max-width:350px;vertical-align:top;margin-bottom:3px}.woocommerce table.form-table table.widefat th{padding-right:inherit}.woocommerce table.form-table th .woocommerce-help-tip,.woocommerce table.form-table th img.help_tip{margin:0 -24px 0 0;float:right}.woocommerce table.form-table .wp-list-table .woocommerce-help-tip{float:none}.woocommerce table.form-table fieldset{margin-top:4px}.woocommerce table.form-table fieldset .woocommerce-help-tip,.woocommerce table.form-table fieldset img.help_tip{margin:-3px 0 0 5px}.woocommerce table.form-table fieldset p.description{margin-bottom:8px}.woocommerce table.form-table fieldset:first-child{margin-top:0}.woocommerce table.form-table .iris-picker{z-index:100;display:none;position:absolute;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,.2)}.woocommerce table.form-table .iris-picker .ui-slider{border:0!important;margin:0!important;width:auto!important;height:auto!important;background:none!important}.woocommerce table.form-table .iris-picker .ui-slider .ui-slider-handle{margin-bottom:0!important}.woocommerce table.form-table .colorpickpreview{padding:3px 3px 3px 20px;border:1px solid #ddd;border-right:0}.woocommerce table.form-table .colorpick{border-left:0}.woocommerce table.form-table .image_width_settings{vertical-align:middle}.woocommerce table.form-table .image_width_settings label{margin-left:10px}.woocommerce table.form-table .wc_emails_wrapper{padding:0 15px 10px 0}.woocommerce #tabs-wrap table a.remove{margin-left:4px}.woocommerce #tabs-wrap table p{margin:0 0 4px!important;overflow:hidden;zoom:1}.woocommerce #tabs-wrap table p a.add{float:left}#wp-excerpt-editor-container{background:#fff}#product_variation-parent #parent_id{width:100%}#postimagediv img{border:1px solid #d5d5d5;max-width:100%}#woocommerce-product-images .inside{margin:0;padding:0}#woocommerce-product-images .inside .add_product_images{padding:0 12px 12px}#woocommerce-product-images .inside #product_images_container{padding:0 0 0 9px}#woocommerce-product-images .inside #product_images_container ul{margin:0;padding:0}#woocommerce-product-images .inside #product_images_container ul:after,#woocommerce-product-images .inside #product_images_container ul:before{content:" ";display:table}#woocommerce-product-images .inside #product_images_container ul:after{clear:both}#woocommerce-product-images .inside #product_images_container ul li.add,#woocommerce-product-images .inside #product_images_container ul li.image,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{width:80px;float:left;cursor:move;border:1px solid #d5d5d5;margin:9px 9px 0 0;background:#f7f7f7;border-radius:2px;position:relative;box-sizing:border-box}#woocommerce-product-images .inside #product_images_container ul li.add img,#woocommerce-product-images .inside #product_images_container ul li.image img,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder img{width:100%;height:auto;display:block}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{border:3px dashed #ddd;position:relative}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-size:2.618em;line-height:72px;color:#ddd}#woocommerce-product-images .inside #product_images_container ul ul.actions{position:absolute;top:-8px;right:-8px;padding:2px;display:none}#woocommerce-product-images .inside #product_images_container ul ul.actions li{float:right;margin:0 0 0 2px}#woocommerce-product-images .inside #product_images_container ul ul.actions li a{width:1em;margin:0;height:0;display:block;overflow:hidden}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.tips{cursor:pointer}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.4em}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:hover:before{color:#a00}#woocommerce-product-images .inside #product_images_container ul li:hover ul.actions{display:block}#woocommerce-product-data .hndle{padding:10px}#woocommerce-product-data .hndle span{display:block;vertical-align:middle;line-height:24px}#woocommerce-product-data .hndle span span{display:inline;line-height:inherit;vertical-align:baseline}#woocommerce-product-data .hndle label{padding-right:1em;font-size:12px;vertical-align:baseline}#woocommerce-product-data .hndle label:first-child{margin-right:1em;border-right:1px solid #dfdfdf}#woocommerce-product-data .hndle input,#woocommerce-product-data .hndle select{margin:-3px 0 0 .5em;vertical-align:middle}#woocommerce-product-data>.handlediv{margin-top:4px}#woocommerce-product-data .wrap{margin:0}#woocommerce-coupon-description{padding:3px 8px;font-size:1.7em;line-height:1.42em;height:auto;width:100%;outline:0;margin:10px 0;display:block}#woocommerce-coupon-description::-webkit-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description::-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-ms-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap{background:#fff}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{float:left;width:80%}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-product-data .woocommerce_options_panel .wc-radios{display:block;float:left;margin:0}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-product-data .woocommerce_options_panel .wc-radios li{display:block;padding:0 0 10px}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li input,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-product-data .woocommerce_options_panel .wc-radios li input{width:auto}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap,.woocommerce .panel-wrap{overflow:hidden}#woocommerce-coupon-data ul.wc-tabs,#woocommerce-product-data ul.wc-tabs,.woocommerce ul.wc-tabs{margin:0;width:20%;float:left;line-height:1em;padding:0 0 10px;position:relative;background-color:#fafafa;border-right:1px solid #eee;box-sizing:border-box}#woocommerce-coupon-data ul.wc-tabs:after,#woocommerce-product-data ul.wc-tabs:after,.woocommerce ul.wc-tabs:after{content:"";display:block;width:100%;height:9999em;position:absolute;bottom:-9999em;left:0;background-color:#fafafa;border-right:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li,#woocommerce-product-data ul.wc-tabs li,.woocommerce ul.wc-tabs li{margin:0;padding:0;display:block;position:relative}#woocommerce-coupon-data ul.wc-tabs li a,#woocommerce-product-data ul.wc-tabs li a,.woocommerce ul.wc-tabs li a{margin:0;padding:10px;display:block;box-shadow:none;text-decoration:none;line-height:20px!important;border-bottom:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li a:before,#woocommerce-product-data ul.wc-tabs li a:before,.woocommerce ul.wc-tabs li a:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}#woocommerce-coupon-data ul.wc-tabs li.general_options a:before,#woocommerce-product-data ul.wc-tabs li.general_options a:before,.woocommerce ul.wc-tabs li.general_options a:before{content:"\f107"}#woocommerce-coupon-data ul.wc-tabs li.inventory_options a:before,#woocommerce-product-data ul.wc-tabs li.inventory_options a:before,.woocommerce ul.wc-tabs li.inventory_options a:before{content:"\f481"}#woocommerce-coupon-data ul.wc-tabs li.shipping_options a:before,#woocommerce-product-data ul.wc-tabs li.shipping_options a:before,.woocommerce ul.wc-tabs li.shipping_options a:before{font-family:WooCommerce;content:"\e01a"}#woocommerce-coupon-data ul.wc-tabs li.linked_product_options a:before,#woocommerce-product-data ul.wc-tabs li.linked_product_options a:before,.woocommerce ul.wc-tabs li.linked_product_options a:before{content:"\f103"}#woocommerce-coupon-data ul.wc-tabs li.attribute_options a:before,#woocommerce-product-data ul.wc-tabs li.attribute_options a:before,.woocommerce ul.wc-tabs li.attribute_options a:before{content:"\f175"}#woocommerce-coupon-data ul.wc-tabs li.advanced_options a:before,#woocommerce-product-data ul.wc-tabs li.advanced_options a:before,.woocommerce ul.wc-tabs li.advanced_options a:before{font-family:Dashicons;content:"\f111"}#woocommerce-coupon-data ul.wc-tabs li.variations_options a:before,#woocommerce-product-data ul.wc-tabs li.variations_options a:before,.woocommerce ul.wc-tabs li.variations_options a:before{content:"\f509"}#woocommerce-coupon-data ul.wc-tabs li.usage_restriction_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_restriction_options a:before,.woocommerce ul.wc-tabs li.usage_restriction_options a:before{font-family:WooCommerce;content:"\e602"}#woocommerce-coupon-data ul.wc-tabs li.usage_limit_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_limit_options a:before,.woocommerce ul.wc-tabs li.usage_limit_options a:before{font-family:WooCommerce;content:"\e601"}#woocommerce-coupon-data ul.wc-tabs li.general_coupon_data a:before,#woocommerce-product-data ul.wc-tabs li.general_coupon_data a:before,.woocommerce ul.wc-tabs li.general_coupon_data a:before{font-family:WooCommerce;content:"\e600"}#woocommerce-coupon-data ul.wc-tabs li.active a,#woocommerce-product-data ul.wc-tabs li.active a,.woocommerce ul.wc-tabs li.active a{color:#555;position:relative;background-color:#eee}.woocommerce_page_wc-settings .shippingrows th.check-column{padding-top:20px}.woocommerce_page_wc-settings .shippingrows tfoot th{padding-left:10px}.woocommerce_page_wc-settings .shippingrows .add.button:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}.woocommerce_page_wc-settings h3.wc-settings-sub-title{font-size:1.2em}#woocommerce-coupon-data .inside,#woocommerce-order-data .inside,#woocommerce-order-downloads .inside,#woocommerce-product-data .inside,#woocommerce-product-type-options .inside{margin:0;padding:0}.panel,.woocommerce_options_panel{padding:9px;color:#555}.panel .form-field .woocommerce-help-tip,.woocommerce_options_panel .form-field .woocommerce-help-tip{font-size:1.4em}.panel,.woocommerce_page_settings .woocommerce_options_panel{padding:0}#woocommerce-product-specs .inside,#woocommerce-product-type-options .panel{margin:0;padding:9px}#woocommerce-product-type-options .panel p,.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p{margin:0 0 9px;font-size:12px;padding:5px 9px;line-height:24px}#woocommerce-product-type-options .panel p:after,.woocommerce_options_panel fieldset.form-field:after,.woocommerce_options_panel p:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce_options_panel .checkbox,.woocommerce_variable_attributes .checkbox{width:auto;margin:3px 0;vertical-align:middle}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{width:100%;padding:0!important}.woocommerce_options_panel .downloadable_files table th,.woocommerce_variations .downloadable_files table th{padding:7px 0 7px 7px!important}.woocommerce_options_panel .downloadable_files table th.sort,.woocommerce_variations .downloadable_files table th.sort{width:17px;padding:7px!important}.woocommerce_options_panel .downloadable_files table th .woocommerce-help-tip,.woocommerce_variations .downloadable_files table th .woocommerce-help-tip{font-size:1.1em;margin-left:0}.woocommerce_options_panel .downloadable_files table td,.woocommerce_variations .downloadable_files table td{vertical-align:middle!important;padding:4px 0 4px 7px!important;position:relative}.woocommerce_options_panel .downloadable_files table td:last-child,.woocommerce_variations .downloadable_files table td:last-child{padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td input.input_text,.woocommerce_variations .downloadable_files table td input.input_text{width:100%;float:none;min-width:0;margin:1px 0}.woocommerce_options_panel .downloadable_files table td .upload_file_button,.woocommerce_variations .downloadable_files table td .upload_file_button{width:auto;float:right;cursor:pointer}.woocommerce_options_panel .downloadable_files table td .delete,.woocommerce_variations .downloadable_files table td .delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.2em}.woocommerce_options_panel .downloadable_files table td .delete:before,.woocommerce_variations .downloadable_files table td .delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}.woocommerce_options_panel .downloadable_files table td .delete:hover:before,.woocommerce_variations .downloadable_files table td .delete:hover:before{color:#a00}.woocommerce_options_panel .downloadable_files table td.sort,.woocommerce_variations .downloadable_files table td.sort{width:17px;cursor:move;font-size:15px;text-align:center;background:#f9f9f9;padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td.sort:before,.woocommerce_variations .downloadable_files table td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_options_panel .downloadable_files table td.sort:hover:before,.woocommerce_variations .downloadable_files table td.sort:hover:before{color:#333}.woocommerce_variation h3 .sort{width:17px;height:26px;cursor:move;float:right;font-size:15px;font-weight:400;margin-right:.5em;visibility:hidden;text-align:center;vertical-align:middle}.woocommerce_variation h3 .sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:28px;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_variation h3 .sort:hover:before{color:#777}.woocommerce_variation h3:hover .sort,.woocommerce_variation.ui-sortable-helper .sort{visibility:visible}.woocommerce_options_panel{min-height:175px;box-sizing:border-box}.woocommerce_options_panel .downloadable_files{padding:0 9px 0 162px;position:relative;margin:9px 0}.woocommerce_options_panel .downloadable_files label{position:absolute;left:0;margin:0 0 0 12px;line-height:24px}.woocommerce_options_panel p{margin:9px 0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px 5px 162px!important}.woocommerce_options_panel .sale_price_dates_fields .short:first-of-type{margin-bottom:1em}.woocommerce_options_panel .sale_price_dates_fields .short:nth-of-type(2){clear:left}.woocommerce_options_panel label,.woocommerce_options_panel legend{float:left;width:150px;padding:0;margin:0 0 0 -150px}.woocommerce_options_panel label .req,.woocommerce_options_panel legend .req{font-weight:700;font-style:normal;color:#a00}.woocommerce_options_panel .description{padding:0;margin:0 0 0 7px;clear:none;display:inline}.woocommerce_options_panel .description-block{margin-left:0;display:block}.woocommerce_options_panel input,.woocommerce_options_panel select,.woocommerce_options_panel textarea{margin:0}.woocommerce_options_panel textarea{height:3.5em;line-height:1.5em;vertical-align:top}.woocommerce_options_panel input[type=text],.woocommerce_options_panel input[type=number],.woocommerce_options_panel input[type=email],.woocommerce_options_panel input[type=password]{width:50%;float:left}.woocommerce_options_panel input.button{width:auto;margin-left:8px}.woocommerce_options_panel select{float:left}.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:50%}.woocommerce_options_panel .sized{width:auto!important;margin-right:6px}.woocommerce_options_panel .options_group{border-top:1px solid #fff;border-bottom:1px solid #eee}.woocommerce_options_panel .options_group:first-child{border-top:0}.woocommerce_options_panel .options_group:last-child{border-bottom:0}.woocommerce_options_panel .options_group fieldset{margin:9px 0;font-size:12px;padding:5px 9px;line-height:24px}.woocommerce_options_panel .options_group fieldset label{width:auto;float:none}.woocommerce_options_panel .options_group fieldset ul{float:left;width:50%;margin:0;padding:0}.woocommerce_options_panel .options_group fieldset ul li{margin:0;width:auto}.woocommerce_options_panel .options_group fieldset ul li input{width:auto;float:none;margin-right:4px}.woocommerce_options_panel .options_group fieldset ul.wc-radios label{margin-left:0}.woocommerce_options_panel .dimensions_field .wrap{display:block;width:50%}.woocommerce_options_panel .dimensions_field .wrap input{width:30.75%;margin-right:3.8%}.woocommerce_options_panel .dimensions_field .wrap .last{margin-right:0}.woocommerce_options_panel.padded{padding:1em}#woocommerce-product-data input.dp-applied,.woocommerce_options_panel .select2-container{float:left}#grouped_product_options,#simple_product_options,#virtual_product_options{padding:12px;font-style:italic;color:#666}.wc-metaboxes-wrapper .toolbar{margin:0!important;border-top:1px solid #fff;border-bottom:1px solid #eee;padding:9px 12px!important}.wc-metaboxes-wrapper .toolbar:first-child{border-top:0}.wc-metaboxes-wrapper .toolbar:last-child{border-bottom:0}.wc-metaboxes-wrapper .toolbar .add_variation{float:right;margin-left:5px}.wc-metaboxes-wrapper .toolbar .cancel-variation-changes,.wc-metaboxes-wrapper .toolbar .save-variation-changes{float:left;margin-right:5px}.wc-metaboxes-wrapper p.toolbar{overflow:hidden;zoom:1}.wc-metaboxes-wrapper .expand-close{margin-right:2px;color:#777;font-size:12px;font-style:italic}.wc-metaboxes-wrapper .expand-close a{background:0 0;padding:0;font-size:12px;text-decoration:none}.wc-metaboxes-wrapper#product_attributes .expand-close{float:right;line-height:28px}.wc-metaboxes-wrapper .fr,.wc-metaboxes-wrapper button.add_variable_attribute{float:right;margin:0 0 0 6px}.wc-metaboxes-wrapper .wc-metaboxes{border-bottom:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox-sortable-placeholder{border-color:#bbb;background-color:#f5f5f5;margin-bottom:9px;border-width:1px;border-style:dashed}.wc-metaboxes-wrapper .wc-metabox{background:#fff;border-bottom:1px solid #eee;margin:0!important}.wc-metaboxes-wrapper .wc-metabox select{font-weight:400}.wc-metaboxes-wrapper .wc-metabox:last-of-type{border-bottom:0}.wc-metaboxes-wrapper .wc-metabox .handlediv{width:27px}.wc-metaboxes-wrapper .wc-metabox .handlediv:before{content:"\f142"!important;cursor:pointer;display:inline-block;font:400 20px/1 Dashicons;line-height:.5!important;padding:8px 10px;position:relative;right:12px;top:0}.wc-metaboxes-wrapper .wc-metabox.closed{border-radius:3px}.wc-metaboxes-wrapper .wc-metabox.closed .handlediv:before{content:"\f140"!important}.wc-metaboxes-wrapper .wc-metabox.closed h3{border:0}.wc-metaboxes-wrapper .wc-metabox h3{margin:0!important;padding:.75em .75em .75em 1em!important;font-size:1em!important;overflow:hidden;zoom:1;cursor:move}.wc-metaboxes-wrapper .wc-metabox h3 a.delete,.wc-metaboxes-wrapper .wc-metabox h3 button{float:right}.wc-metaboxes-wrapper .wc-metabox h3 a.delete{color:red;font-weight:400;line-height:26px;text-decoration:none;position:relative;visibility:hidden}.wc-metaboxes-wrapper .wc-metabox h3 strong{line-height:26px;font-weight:700}.wc-metaboxes-wrapper .wc-metabox h3 select{font-family:sans-serif;max-width:20%;margin:.25em .25em .25em 0}.wc-metaboxes-wrapper .wc-metabox h3 .handlediv{background-position:6px 5px!important;visibility:hidden;height:26px}.wc-metaboxes-wrapper .wc-metabox h3.fixed{cursor:pointer!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3{cursor:pointer;padding:.5em .75em .5em 1em!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .handlediv,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .sort,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 a.delete{margin-top:.25em}.wc-metaboxes-wrapper .wc-metabox h3:hover .handlediv,.wc-metaboxes-wrapper .wc-metabox h3:hover a.delete,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper .handlediv,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper a.delete{visibility:visible}.wc-metaboxes-wrapper .wc-metabox table{width:100%;position:relative;background-color:#fdfdfd;padding:1em;border-top:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox table td{text-align:left;padding:0 6px 1em 0;vertical-align:top;border:0}.wc-metaboxes-wrapper .wc-metabox table td label{text-align:left;display:block;line-height:21px}.wc-metaboxes-wrapper .wc-metabox table td input{float:left;min-width:200px}.wc-metaboxes-wrapper .wc-metabox table td input,.wc-metaboxes-wrapper .wc-metabox table td textarea{width:100%;margin:0;display:block;font-size:14px;padding:4px;color:#555}.wc-metaboxes-wrapper .wc-metabox table td .select2-container,.wc-metaboxes-wrapper .wc-metabox table td select{width:100%!important}.wc-metaboxes-wrapper .wc-metabox table td input.short{width:200px}.wc-metaboxes-wrapper .wc-metabox table td input.checkbox{width:16px;min-width:inherit;vertical-align:text-bottom;display:inline-block;float:none}.wc-metaboxes-wrapper .wc-metabox table td.attribute_name{width:200px}.wc-metaboxes-wrapper .wc-metabox table .minus,.wc-metaboxes-wrapper .wc-metabox table .plus{margin-top:6px}.wc-metaboxes-wrapper .wc-metabox table .fl{float:left}.wc-metaboxes-wrapper .wc-metabox table .fr{float:right}.variations-pagenav{float:right;line-height:24px}.variations-pagenav .displaying-num{color:#777;font-size:12px;font-style:italic}.variations-pagenav a{padding:0 10px 3px;background:rgba(0,0,0,.05);font-size:16px;font-weight:400;text-decoration:none}.variations-pagenav a.disabled,.variations-pagenav a.disabled:active,.variations-pagenav a.disabled:focus,.variations-pagenav a.disabled:hover{color:#A0A5AA;background:rgba(0,0,0,.05)}.variations-defaults{float:left}.variations-defaults select{margin:.25em .25em .25em 0}.woocommerce_variable_attributes{background-color:#fdfdfd;border-top:1px solid #eee}.woocommerce_variable_attributes .data{padding:1em 2em}.woocommerce_variable_attributes .data:after,.woocommerce_variable_attributes .data:before{content:" ";display:table}.woocommerce_variable_attributes .data:after{clear:both}.woocommerce_variable_attributes .upload_image_button{display:block;width:48px;height:48px;float:left;margin-right:20px;position:relative;cursor:pointer}.woocommerce_variable_attributes .upload_image_button img{width:100%;height:auto;display:none}.woocommerce_variable_attributes .upload_image_button:before{content:"\f128";font-family:Dashicons;position:absolute;top:0;left:0;right:0;bottom:0;text-align:center;line-height:48px;font-size:48px;font-weight:400;-webkit-font-smoothing:antialiased}.woocommerce_variable_attributes .upload_image_button.remove img{display:block}.woocommerce_variable_attributes .upload_image_button.remove:before{content:"\f335";display:none}.woocommerce_variable_attributes .upload_image_button.remove:hover:before{display:block}.woocommerce_variable_attributes .options{border:1px solid #eee;border-width:1px 0;padding:.25em 0}.woocommerce_variable_attributes .options label{display:inline-block;padding:4px 1em 2px 0}.woocommerce_variable_attributes .options input[type=checkbox]{margin-top:5px;margin-right:3px}.form-row label{display:block}.form-row input[type=number],.form-row input[type=text],.form-row select{width:100%}.form-row.dimensions_field input{width:25%;float:left;margin-right:1%}.form-row.dimensions_field input:last-of-type{margin-right:0}.form-row-first,.form-row-last{width:48%;float:right}.form-row-first{clear:both;float:left}.form-row-full{clear:both}.tips{cursor:help;text-decoration:none}img.tips{padding:5px 0 0}#tiptip_holder{display:none;position:absolute;top:0;left:0;z-index:9999999}#tiptip_holder.tip_top{padding-bottom:5px}#tiptip_holder.tip_top #tiptip_arrow_inner{margin-top:-7px;margin-left:-6px;border-top-color:#333}#tiptip_holder.tip_bottom{padding-top:5px}#tiptip_holder.tip_bottom #tiptip_arrow_inner{margin-top:-5px;margin-left:-6px;border-bottom-color:#333}#tiptip_holder.tip_right{padding-left:5px}#tiptip_holder.tip_right #tiptip_arrow_inner{margin-top:-6px;margin-left:-5px;border-right-color:#333}#tiptip_holder.tip_left{padding-right:5px}#tiptip_holder.tip_left #tiptip_arrow_inner{margin-top:-6px;margin-left:-7px;border-left-color:#333}#tiptip_content,.chart-tooltip,.wc_error_tip{color:#fff;font-size:.8em;max-width:150px;background:#333;text-align:center;border-radius:3px;padding:.618em 1em;box-shadow:0 1px 3px rgba(0,0,0,.2)}#tiptip_content code,.chart-tooltip code,.wc_error_tip code{padding:1px;background:#888}#tiptip_arrow,#tiptip_arrow_inner{position:absolute;border-color:transparent;border-style:solid;border-width:6px;height:0;width:0}.wc_error_tip{max-width:20em;line-height:1.8em;position:absolute;white-space:normal;background:#d82223;margin:1.5em 1px 0 -1em;z-index:9999999}.wc_error_tip:after{content:"";display:block;border:8px solid #d82223;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-3px;left:50%;margin:-1em 0 0 -3px}img.ui-datepicker-trigger{vertical-align:middle;margin-top:-1px;cursor:pointer}.wc-metabox-content img.ui-datepicker-trigger,.woocommerce_options_panel img.ui-datepicker-trigger{float:left;margin-right:8px;margin-top:4px;margin-left:4px}#ui-datepicker-div{display:none}.woocommerce-reports-wide.woocommerce-reports-wrap,.woocommerce-reports-wrap.woocommerce-reports-wrap{margin-left:300px;padding-top:18px}.woocommerce-reports-wide.halved,.woocommerce-reports-wrap.halved{margin:0;overflow:hidden;zoom:1}.woocommerce-reports-wide .widefat td,.woocommerce-reports-wrap .widefat td{vertical-align:top;padding:7px}.woocommerce-reports-wide .widefat td .description,.woocommerce-reports-wrap .widefat td .description{margin:4px 0 0}.woocommerce-reports-wide .postbox:after,.woocommerce-reports-wrap .postbox:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox h3,.woocommerce-reports-wrap .postbox h3{cursor:default!important}.woocommerce-reports-wide .postbox .inside,.woocommerce-reports-wrap .postbox .inside{padding:10px;margin:0!important}.woocommerce-reports-wide .postbox div.stats_range,.woocommerce-reports-wide .postbox h3.stats_range,.woocommerce-reports-wrap .postbox div.stats_range,.woocommerce-reports-wrap .postbox h3.stats_range{border-bottom-color:#dfdfdf;margin:0;padding:0!important}.woocommerce-reports-wide .postbox div.stats_range .export_csv,.woocommerce-reports-wide .postbox h3.stats_range .export_csv,.woocommerce-reports-wrap .postbox div.stats_range .export_csv,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv{float:right;line-height:26px;border-left:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range .export_csv:before,.woocommerce-reports-wide .postbox h3.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox div.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;content:"";text-decoration:none;margin-right:4px}.woocommerce-reports-wide .postbox div.stats_range ul,.woocommerce-reports-wide .postbox h3.stats_range ul,.woocommerce-reports-wrap .postbox div.stats_range ul,.woocommerce-reports-wrap .postbox h3.stats_range ul{list-style:none;margin:0;padding:0;zoom:1;background:#f5f5f5;border-bottom:1px solid #ccc}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox div.stats_range ul:before,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:before,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:before,.woocommerce-reports-wrap .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:before{content:" ";display:table}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:after{clear:both}.woocommerce-reports-wide .postbox div.stats_range ul li,.woocommerce-reports-wide .postbox h3.stats_range ul li,.woocommerce-reports-wrap .postbox div.stats_range ul li,.woocommerce-reports-wrap .postbox h3.stats_range ul li{float:left;margin:0;padding:0;line-height:26px;font-weight:700;font-size:14px}.woocommerce-reports-wide .postbox div.stats_range ul li a,.woocommerce-reports-wide .postbox h3.stats_range ul li a,.woocommerce-reports-wrap .postbox div.stats_range ul li a,.woocommerce-reports-wrap .postbox h3.stats_range ul li a{border-right:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range ul li.active,.woocommerce-reports-wide .postbox h3.stats_range ul li.active,.woocommerce-reports-wrap .postbox div.stats_range ul li.active,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active{background:#fff;-webkit-box-shadow:0 4px 0 0 #fff;box-shadow:0 4px 0 0 #fff}.woocommerce-reports-wide .postbox div.stats_range ul li.active a,.woocommerce-reports-wide .postbox h3.stats_range ul li.active a,.woocommerce-reports-wrap .postbox div.stats_range ul li.active a,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active a{color:#777}.woocommerce-reports-wide .postbox div.stats_range ul li.custom,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom{padding:9px 10px;vertical-align:middle}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form{display:inline;margin:0}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form input.range_datepicker{padding:0;margin:0 10px 0 0;background:0 0;border:0;color:#777;text-align:center;-webkit-box-shadow:none;box-shadow:none}.woocommerce-reports-wide .postbox .chart-with-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar{padding:12px 12px 12px 249px;margin:0!important}.woocommerce-reports-wide .postbox .chart-with-sidebar .chart-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar .chart-sidebar{width:225px;margin-left:-237px;float:left}.woocommerce-reports-wide .postbox .chart-widgets,.woocommerce-reports-wrap .postbox .chart-widgets{margin:0;padding:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget{margin:0 0 1em;background:#fafafa;border:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4{background:#fff;border:1px solid #dfdfdf;border-left-width:0;border-right-width:0;padding:10px;margin:0;color:#2ea2cc;border-top-width:0;background-image:-webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9));background-image:-webkit-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-moz-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-o-linear-gradient(bottom,#ececec,#f9f9f9);background-image:linear-gradient(to top,#ececec,#f9f9f9)}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr.active td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr.active td{background:#f5f5f5}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4.section_title:hover,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4.section_title:hover{color:#a00}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title{cursor:pointer}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span{display:block}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin-left:.618em;content:"";text-decoration:none;float:right;font-size:.9em;line-height:1.618}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open{color:#333}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open span:after{display:none}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section{border-bottom:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section .select2-container,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section .select2-container{width:100%!important}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section:last-of-type,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section:last-of-type{border-radius:0 0 3px 3px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td{padding:7px 10px;vertical-align:top;border-top:1px solid #e5e5e5;line-height:1.4em}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.sparkline,form.report_filters div,form.report_filters input,form.report_filters label,form.report_filters p{vertical-align:middle}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr:first-child td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr:first-child td{border-top:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name{max-width:175px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name a,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name a{word-wrap:break-word}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table .wc_sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table .wc_sparkline{width:32px;height:1em;display:block;float:right}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p{margin:0;padding:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p .submit{margin-top:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget #product_ids,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget #product_ids{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_none,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_none{float:right;color:#999;margin-left:4px;margin-top:10px}.woocommerce-reports-wide .postbox .chart-legend,.woocommerce-reports-wrap .postbox .chart-legend{list-style:none;margin:0 0 1em;padding:0;border:1px solid #dfdfdf;border-right-width:0;border-bottom-width:0;background:#fff}.woocommerce-reports-wide .postbox .chart-legend li,.woocommerce-reports-wrap .postbox .chart-legend li{border-right:5px solid #aaa;color:#aaa;padding:1em;display:block;margin:0;-webkit-transition:all ease .5s;box-shadow:inset 0 -1px 0 0 #dfdfdf}.woocommerce-reports-wide .postbox .chart-legend li strong,.woocommerce-reports-wrap .postbox .chart-legend li strong{font-size:1.618em;line-height:1.2em;color:#464646;font-weight:400;display:block;font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif}.woocommerce-reports-wide .postbox .chart-legend li strong del,.woocommerce-reports-wrap .postbox .chart-legend li strong del{color:#e74c3c;font-weight:400}.woocommerce-reports-wide .postbox .chart-legend li:hover,.woocommerce-reports-wrap .postbox .chart-legend li:hover{box-shadow:inset 0 -1px 0 0 #dfdfdf,inset 300px 0 0 rgba(156,93,144,.1);border-right:5px solid #9c5d90!important;padding-left:1.5em;color:#9c5d90}.woocommerce-reports-wide .postbox .pie-chart-legend,.woocommerce-reports-wrap .postbox .pie-chart-legend{margin:12px 0 0;overflow:hidden}.woocommerce-reports-wide .postbox .pie-chart-legend li,.woocommerce-reports-wrap .postbox .pie-chart-legend li{float:left;margin:0;padding:6px 0 0;border-top:4px solid #999;text-align:center;box-sizing:border-box;width:50%}.woocommerce-reports-wide .postbox .stat,.woocommerce-reports-wrap .postbox .stat{font-size:1.5em!important;font-weight:700;text-align:center}.woocommerce-reports-wide .postbox .chart-placeholder,.woocommerce-reports-wrap .postbox .chart-placeholder{width:100%;height:650px;overflow:hidden;position:relative}.woocommerce-reports-wide .postbox .chart-prompt,.woocommerce-reports-wrap .postbox .chart-prompt{line-height:650px;margin:0;color:#999;font-size:1.2em;font-style:italic;text-align:center}.woocommerce-reports-wide .postbox .chart-container,.woocommerce-reports-wrap .postbox .chart-container{background:#fff;padding:12px;position:relative;border:1px solid #dfdfdf;border-radius:3px}.woocommerce-reports-wide .postbox .main .chart-legend,.woocommerce-reports-wrap .postbox .main .chart-legend{margin-top:12px}.woocommerce-reports-wide .postbox .main .chart-legend li,.woocommerce-reports-wrap .postbox .main .chart-legend li{border-right:0;margin:0 8px 0 0;float:left;border-top:4px solid #aaa}.woocommerce-reports-wide .woocommerce-reports-main,.woocommerce-reports-wrap .woocommerce-reports-main{float:left;min-width:100%}.woocommerce-reports-wide .woocommerce-reports-main table td,.woocommerce-reports-wrap .woocommerce-reports-main table td{padding:9px}.woocommerce-reports-wide .woocommerce-reports-sidebar,.woocommerce-reports-wrap .woocommerce-reports-sidebar{display:inline;width:281px;margin-left:-300px;clear:both;float:left}.woocommerce-reports-wide .woocommerce-reports-left,.woocommerce-reports-wrap .woocommerce-reports-left{width:49.5%;float:left}.woocommerce-reports-wide .woocommerce-reports-right,.woocommerce-reports-wrap .woocommerce-reports-right{width:49.5%;float:right}.woocommerce-reports-wide .column-wc_actions a.edit,.woocommerce-reports-wide .column-wc_actions a.view,.woocommerce-reports-wrap .column-wc_actions a.edit,.woocommerce-reports-wrap .column-wc_actions a.view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;line-height:1.85}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after{content:"\f464"}.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{content:"\f177"}.woocommerce-wide-reports-wrap{padding-bottom:11px}.woocommerce-wide-reports-wrap .widefat .export-data{float:right}.woocommerce-wide-reports-wrap .widefat td,.woocommerce-wide-reports-wrap .widefat th{vertical-align:middle;padding:7px}.chart-tooltip{position:absolute;display:none;line-height:1}table.bar_chart{width:100%}table.bar_chart thead th{text-align:left;color:#ccc;padding:6px 0}table.bar_chart tbody th{padding:6px 0;width:25%;text-align:left!important;font-weight:400!important;border-bottom:1px solid #fee}table.bar_chart tbody td{text-align:right;line-height:24px;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td span{color:#8a4b75;display:block}table.bar_chart tbody td span.alt{color:#47a03e;margin-top:6px}table.bar_chart tbody td.bars{position:relative;text-align:left;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td.bars a,table.bar_chart tbody td.bars span{text-decoration:none;clear:both;background:#8a4b75;float:left;display:block;line-height:24px;height:24px;-moz-border-radius:3px;-webkit-border-radius:3px;-o-border-radius:3px;-khtml-border-radius:3px;border-radius:3px}.post-type-product .woocommerce-BlankState-message:before,.post-type-shop_coupon .woocommerce-BlankState-message:before,.post-type-shop_order .woocommerce-BlankState-message:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}table.bar_chart tbody td.bars span.alt{clear:both;background:#47a03e}table.bar_chart tbody td.bars span.alt span{margin:0;color:#c5dec2!important;text-shadow:0 1px 0 #47a03e;background:0 0}.post-type-shop_order .woocommerce-BlankState-message:before{content:""}.post-type-shop_coupon .woocommerce-BlankState-message:before{content:""}.post-type-product .woocommerce-BlankState-message:before{content:""}.woocommerce-BlankState{text-align:center;padding:5em 0 0}.woocommerce-BlankState .woocommerce-BlankState-message{color:#aaa;margin:0 auto 1.5em;line-height:1.5em;font-size:1.2em;max-width:500px}.woocommerce-BlankState .woocommerce-BlankState-message:before{color:#ddd;text-shadow:0 -1px 1px rgba(0,0,0,.2),0 1px 0 rgba(255,255,255,.8);font-size:8em;display:block;position:relative!important;top:auto;left:auto;line-height:1em;margin:0 0 .1875em}.woocommerce-BlankState .woocommerce-BlankState-cta{font-size:1.2em;padding:.75em 1.5em;height:auto}@media only screen and (max-width:1280px){#order_data .order_data_column{width:48%}#order_data .order_data_column:first-child{width:100%}.woocommerce_options_panel .description{display:block;clear:both;margin-left:0}.woocommerce_options_panel .dimensions_field .wrap,.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:80%}.woocommerce_options_panel .downloadable_files,.woocommerce_variations .downloadable_files{padding:0;clear:both}.woocommerce_options_panel .downloadable_files label,.woocommerce_variations .downloadable_files label{position:static}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{margin:0 12px 24px;width:94%}.woocommerce_options_panel .downloadable_files table .sort,.woocommerce_variations .downloadable_files table .sort{visibility:hidden}.woocommerce_options_panel .woocommerce_variable_attributes .downloadable_files table,.woocommerce_variations .woocommerce_variable_attributes .downloadable_files table{margin:0 0 1em;width:100%}}@media only screen and (max-width:900px){#woocommerce-coupon-data ul.coupon_data_tabs,#woocommerce-product-data .wc-tabs-back,#woocommerce-product-data ul.product_data_tabs{width:10%}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{width:90%}#woocommerce-coupon-data ul.coupon_data_tabs li a,#woocommerce-product-data ul.product_data_tabs li a{position:relative;text-indent:-999px;padding:10px}#woocommerce-coupon-data ul.coupon_data_tabs li a:before,#woocommerce-product-data ul.product_data_tabs li a:before{position:absolute;top:0;right:0;bottom:0;left:0;text-indent:0;text-align:center;line-height:40px;width:100%;height:40px}}@media only screen and (max-width:782px){#wp-excerpt-media-buttons a{font-size:16px;line-height:37px;height:39px;padding:0 20px 0 15px}#wp-excerpt-editor-tools{padding-top:20px;padding-right:15px;overflow:hidden;margin-bottom:-1px}.post-type-product .wp-list-table .is-expanded td:not(.hidden),.post-type-shop_order .wp-list-table .is-expanded td:not(.hidden){overflow:visible}#woocommerce-product-data .checkbox{width:25px}.variations-pagenav{float:none;text-align:center;font-size:18px}.variations-pagenav .displaying-num{font-size:16px}.variations-pagenav a{padding:8px 20px 11px;font-size:18px}.variations-pagenav select{padding:0 20px}.variations-defaults{float:none;text-align:center;margin-top:10px}.post-type-product .wp-list-table .column-thumb{display:none;text-align:left;padding-bottom:0}.post-type-product .wp-list-table .column-thumb:before{display:none!important}.post-type-product .wp-list-table .column-thumb img{max-width:32px}.post-type-product .wp-list-table .toggle-row{top:-28px}.post-type-shop_order .wp-list-table .column-order_status{display:none;text-align:left;padding-bottom:0}.post-type-shop_order .wp-list-table .column-order_status mark{margin:0}.post-type-shop_order .wp-list-table .column-order_status:before{display:none!important}.post-type-shop_order .wp-list-table .column-customer_message,.post-type-shop_order .wp-list-table .column-order_notes{text-align:inherit}.post-type-shop_order .wp-list-table .column-order_notes .note-on{font-size:1.3em;margin:0}.post-type-shop_order .wp-list-table .toggle-row{top:-15px}}@media only screen and (max-width:500px){.woocommerce_options_panel label,.woocommerce_options_panel legend{float:none;width:auto;display:block;margin:0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px!important}}.wc-backbone-modal *{box-sizing:border-box}.wc-backbone-modal .wc-backbone-modal-content{position:fixed;background:#fff;z-index:100000;left:50%;top:50%;transform:translate(-50%,-50%);width:500px}.wc-backbone-modal .wc-backbone-modal-content article{overflow:auto}.wc-backbone-modal.wc-backbone-modal-shipping-method-settings .wc-backbone-modal-content{width:75%;min-width:500px}.wc-backbone-modal-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;min-height:360px;background:#000;opacity:.7;z-index:99900}.wc-backbone-modal-main{padding-bottom:55px}.wc-backbone-modal-main article,.wc-backbone-modal-main header{display:block;position:relative}.wc-backbone-modal-main .wc-backbone-modal-header{height:auto;background:#fcfcfc;padding:1em 1.5em;border-bottom:1px solid #ddd}.wc-backbone-modal-main .wc-backbone-modal-header h1{margin:0;font-size:18px;font-weight:700;line-height:1.5em}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link{cursor:pointer;color:#777;height:54px;width:54px;padding:0;position:absolute;top:0;right:0;text-align:center;border:0;border-left:1px solid #ddd;background-color:transparent;-webkit-transition:color .1s ease-in-out,background .1s ease-in-out;transition:color .1s ease-in-out,background .1s ease-in-out}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:before{font:400 22px/50px dashicons!important;color:#666;display:block;content:'\f335';font-weight:300}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus,.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:hover{background:#ddd;border-color:#ccc;color:#000}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus{outline:0}.wc-backbone-modal-main article{padding:1.5em}.wc-backbone-modal-main article p{margin:1.5em 0}.wc-backbone-modal-main article p:last-child,.wc-backbone-modal-main footer .inner .button{margin-bottom:0}.wc-backbone-modal-main article p:first-child{margin-top:0}.wc-backbone-modal-main article .pagination{padding:10px 0 0;text-align:center}.wc-backbone-modal-main footer{position:absolute;left:0;right:0;bottom:0;z-index:100;padding:1em 1.5em;background:#fcfcfc;border-top:1px solid #dfdfdf;box-shadow:0 -4px 4px -4px rgba(0,0,0,.1)}.wc-backbone-modal-main footer .inner{float:right;line-height:23px}.select2-drop{z-index:999999!important}.select2-container-multi .select2-choices .select2-search-field input{font-family:inherit;font-size:inherit;font-weight:inherit;padding:3px 5px}.select2-container{line-height:1.85em;font-size:14px} \ No newline at end of file +@charset "UTF-8";.button.wc-reload:after,.woocommerce-help-tip:after{speak:none;text-transform:none;-webkit-font-smoothing:antialiased}@-webkit-keyframes spin{100%{-webkit-transform:rotate(360deg)}}@-moz-keyframes spin{100%{-moz-transform:rotate(360deg)}}@keyframes spin{100%{-webkit-transform:rotate(360deg);-moz-transform:rotate(360deg);-ms-transform:rotate(360deg);-o-transform:rotate(360deg);transform:rotate(360deg)}}.select2-container{margin:0;position:relative;display:block!important;zoom:1;vertical-align:middle}.select2-container,.select2-drop,.select2-search,.select2-search input{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.select2-container .select2-choice{display:block;padding:0 0 0 8px;overflow:hidden;position:relative;border:1px solid #ccc;white-space:nowrap;color:#444;text-decoration:none;border-radius:3px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#fff;font-weight:400}html[dir=rtl] .select2-container .select2-choice{padding:0 8px 0 0}.select2-container.select2-drop-above .select2-choice{border-bottom-color:#ccc;border-radius:0 0 4px 4px}.select2-container.select2-allowclear .select2-choice .select2-chosen{margin-right:42px}.select2-container .select2-choice>.select2-chosen{margin-right:26px;display:block;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;float:none;width:auto}html[dir=rtl] .select2-container .select2-choice>.select2-chosen{margin-left:26px;margin-right:0}.select2-container .select2-choice abbr{display:none;width:12px;height:12px;position:absolute;right:24px;top:5px;font-size:1px;text-decoration:none;border:0;background:url(../images/select2.png) right top no-repeat;cursor:pointer;outline:0}.select2-container.select2-allowclear .select2-choice abbr{display:inline-block}.select2-container .select2-choice abbr:hover{background-position:right -11px;cursor:pointer}.select2-drop-mask{border:0;margin:0;padding:0;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:9998;background-color:#fff;filter:alpha(opacity=0)}.select2-drop{width:100%;margin-top:-1px;position:absolute;top:100%;background:#fff;color:#000;border:1px solid #ccc;border-top:0;border-radius:0 0 3px 3px}.select2-drop.select2-drop-above{margin-top:1px;border-top:1px solid #ccc;border-bottom:0;border-radius:3px 3px 0 0}.select2-drop-active{border:1px solid #666;border-top:none}.select2-drop.select2-drop-above.select2-drop-active{border-top:1px solid #666}.select2-drop-auto-width{border-top:1px solid #ccc;width:auto}.select2-drop-auto-width .select2-search{padding-top:4px}.select2-container .select2-choice .select2-arrow{display:inline-block;width:18px;height:100%;position:absolute;right:0;top:0;border-radius:0 3px 3px 0;background-clip:padding-box}html[dir=rtl] .select2-container .select2-choice .select2-arrow{left:0;right:auto;border-radius:3px 0 0 3px}.select2-container .select2-choice .select2-arrow b{display:block;width:100%;height:100%;position:relative}.select2-container .select2-choice .select2-arrow b:after{position:absolute;display:block;content:"";top:50%;left:50%;border:4px solid transparent;border-top-color:#666;margin-left:-7px;margin-top:-2px}.select2-search{display:inline-block;width:100%;margin:0;padding-left:4px;padding-right:4px;position:relative;z-index:10000;white-space:nowrap;padding-bottom:4px}.select2-search input{width:100%;height:auto!important;padding:4px 20px 4px 5px!important;margin:0;outline:0;font-family:sans-serif;font-size:1em;border:1px solid #ccc;-webkit-box-shadow:none;box-shadow:none;background:url(../images/select2.png) 100% -22px no-repeat #fff}html[dir=rtl] .select2-search input{padding:4px 5px 4px 20px;background:url(../images/select2.png) -37px -22px no-repeat #fff}.select2-drop.select2-drop-above .select2-search input{margin-top:4px}.select2-search input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff}.select2-container-active .select2-choice,.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-dropdown-open .select2-choice{border-bottom-color:transparent;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-dropdown-open .select2-choice .select2-arrow b:after{border-top-color:transparent;border-bottom-color:#666;margin-top:-6px}.select2-dropdown-open.select2-drop-above .select2-choice,.select2-dropdown-open.select2-drop-above .select2-choices{border:1px solid #666;border-top-color:transparent}.select2-dropdown-open .select2-choice .select2-arrow{background:0 0;border-left:none;filter:none}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow{border-right:none}.select2-dropdown-open .select2-choice .select2-arrow b{background-position:-18px 1px}html[dir=rtl] .select2-dropdown-open .select2-choice .select2-arrow b{background-position:-16px 1px}.select2-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.select2-results{max-height:200px;padding:4px;margin:0;position:relative;overflow-x:hidden;overflow-y:auto;-webkit-tap-highlight-color:transparent;background:#fafafa}html[dir=rtl] .select2-results{padding:0 4px 0 0;margin:4px 0 4px 4px}.select2-results ul.select2-result-sub{margin:0;padding-left:0}.select2-results li{list-style:none;display:list-item;background-image:none;margin:3px 0}.select2-results li.select2-result-with-children>.select2-result-label{font-weight:700}.select2-results .select2-result-label{padding:5px 7px;margin:0;cursor:pointer;min-height:1em;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.select2-results-dept-1 .select2-result-label{padding-left:20px}.select2-results-dept-2 .select2-result-label{padding-left:40px}.select2-results-dept-3 .select2-result-label{padding-left:60px}.select2-results-dept-4 .select2-result-label{padding-left:80px}.select2-results-dept-5 .select2-result-label{padding-left:100px}.select2-results-dept-6 .select2-result-label{padding-left:110px}.select2-results-dept-7 .select2-result-label{padding-left:120px}.select2-results .select2-highlighted{background:#f1f1f1;color:#000;border-radius:3px}.select2-results li em{background:#feffde;font-style:normal}.select2-results .select2-highlighted em{background:0 0}.select2-results .select2-highlighted ul{background:#fff;color:#000}.select2-results .select2-ajax-error,.select2-results .select2-no-results,.select2-results .select2-searching,.select2-results .select2-selection-limit{background:#f4f4f4;display:list-item;padding-left:5px}.select2-results .select2-disabled.select2-highlighted{color:#666;background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-disabled{background:#f4f4f4;display:list-item;cursor:default}.select2-results .select2-selected{display:none}.select2-more-results.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #f4f4f4}.select2-results .select2-ajax-error{background:rgba(255,50,50,.2)}.select2-more-results{background:#f4f4f4;display:list-item}.select2-container.select2-container-disabled .select2-choice{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container.select2-container-disabled .select2-choice .select2-arrow{background-color:#f4f4f4;background-image:none;border-left:0}.select2-container.select2-container-disabled .select2-choice abbr{display:none}.select2-container-multi .select2-choices{height:auto!important;height:1%;margin:0;padding:0 5px 0 0;position:relative;border:1px solid #ccc;cursor:text;overflow:hidden;background-color:#fff;min-height:26px}html[dir=rtl] .select2-container-multi .select2-choices{padding:0 0 0 5px}.select2-locked{padding:3px 5px!important}.select2-container-multi.select2-container-active .select2-choices{border:1px solid #666;outline:0}.select2-container-multi .select2-choices li{float:left;list-style:none}html[dir=rtl] .select2-container-multi .select2-choices li{float:right}.select2-container-multi .select2-choices .select2-search-field{margin:0;padding:0;white-space:nowrap}.select2-container-multi .select2-choices .select2-search-field:first-child{width:100%}.select2-container-multi .select2-choices .select2-search-field input{margin:1px 0;outline:0;border:0;-webkit-box-shadow:none;box-shadow:none;background:0 0!important}.select2-container-multi .select2-choices .select2-search-field input.select2-active{background:url(../images/select2-spinner.gif) 100% no-repeat #fff!important}.select2-default{color:#999!important}.select2-container-multi .select2-choices .select2-search-choice{padding:5px 8px 5px 24px;margin:3px 0 3px 5px;position:relative;line-height:15px;color:#333;cursor:default;border-radius:2px;background-clip:padding-box;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#e4e4e4}html[dir=rtl] .select2-container-multi .select2-choices .select2-search-choice{margin:3px 5px 3px 0;padding:5px 24px 5px 8px}.select2-container-multi .select2-choices .select2-search-choice .select2-chosen{cursor:default}.select2-container-multi .select2-choices .select2-search-choice-focus{background:#d4d4d4}.select2-search-choice-close{display:block;width:12px;height:13px;position:absolute;right:7px;top:6px;font-size:1px;outline:0;background:url(../images/select2.png) right top no-repeat}html[dir=rtl] .select2-search-choice-close{right:auto;left:7px}.select2-container-multi .select2-search-choice-close{left:7px}html[dir=rtl] .select2-container-multi .select2-search-choice-close{left:auto;right:7px}.select2-container-multi .select2-choices .select2-search-choice .select2-search-choice-close:hover,.select2-container-multi .select2-choices .select2-search-choice-focus .select2-search-choice-close{background-position:right -11px}.select2-container-multi.select2-container-disabled .select2-choices{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice{padding:3px 5px;border:1px solid #ddd;background-image:none;background-color:#f4f4f4}.select2-container-multi.select2-container-disabled .select2-choices .select2-search-choice .select2-search-choice-close{display:none;background:0 0}.select2-result-selectable .select2-match,.select2-result-unselectable .select2-match{text-decoration:underline}.select2-offscreen,.select2-offscreen:focus{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:0!important;top:0!important}.select2-display-none{display:none}.select2-measure-scrollbar{position:absolute;top:-10000px;left:-10000px;width:100px;height:100px;overflow:scroll}@media only screen and (-webkit-min-device-pixel-ratio:1.5),only screen and (min-resolution:2dppx){.select2-search input{background-image:url(../images/select2x2.png)!important;background-repeat:no-repeat!important;background-size:60px 40px!important;background-position:100% -21px!important}}@font-face{font-family:star;src:url(../fonts/star.eot);src:url(../fonts/star.eot?#iefix) format("embedded-opentype"),url(../fonts/star.woff) format("woff"),url(../fonts/star.ttf) format("truetype"),url(../fonts/star.svg#star) format("svg");font-weight:400;font-style:normal}@font-face{font-family:WooCommerce;src:url(../fonts/WooCommerce.eot);src:url(../fonts/WooCommerce.eot?#iefix) format("embedded-opentype"),url(../fonts/WooCommerce.woff) format("woff"),url(../fonts/WooCommerce.ttf) format("truetype"),url(../fonts/WooCommerce.svg#WooCommerce) format("svg");font-weight:400;font-style:normal}.blockUI.blockOverlay:before{height:1em;width:1em;position:absolute;top:50%;left:50%;margin-left:-.5em;margin-top:-.5em;display:block;content:"";-webkit-animation:spin 1s ease-in-out infinite;-moz-animation:spin 1s ease-in-out infinite;animation:spin 1s ease-in-out infinite;background:url(../images/icons/loader.svg) center center;background-size:cover;line-height:1;text-align:center;font-size:2em;color:rgba(0,0,0,.75)}.wc_addons_wrap .products{overflow:hidden}.wc_addons_wrap .products li{float:left;margin:0 1em 1em 0!important;padding:0;vertical-align:top;width:300px}.wc_addons_wrap .products li a{text-decoration:none;color:inherit;border:1px solid #ddd;display:block;min-height:220px;overflow:hidden;background:#f5f5f5;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),inset 0 -1px 0 rgba(0,0,0,.1)}.wc_addons_wrap .products li a img{max-width:258px;max-height:24px;padding:17px 20px;display:block;margin:0;background:#fff;border-right:260px solid #fff}.wc_addons_wrap .products li a .price,.wc_addons_wrap .products li a img.extension-thumb+h3{display:none}.wc_addons_wrap .products li a h2,.wc_addons_wrap .products li a h3{margin:0!important;padding:20px!important;background:#fff}.wc_addons_wrap .products li a p{padding:20px!important;margin:0!important;border-top:1px solid #f1f1f1}.wc_addons_wrap .products li a:focus,.wc_addons_wrap .products li a:hover{background-color:#fff}.wc_addons_wrap .storefront{background:url(../images/storefront-bg.jpg) bottom right #f6f6f6;border:1px solid #ddd;padding:20px;overflow:hidden;zoom:1}.wc_addons_wrap .storefront img{width:278px;height:auto;float:left;margin:0 20px 0 0;box-shadow:0 1px 6px rgba(0,0,0,.1)}.wc_addons_wrap .storefront p{max-width:750px}.woocommerce-BlankState a.button-primary,.woocommerce-BlankState button.button-primary,.woocommerce-message a.button-primary,.woocommerce-message button.button-primary{background:#bb77ae;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;color:#fff;text-shadow:0 -1px 1px #A36597,1px 0 1px #A36597,0 1px 1px #A36597,-1px 0 1px #A36597}.woocommerce-BlankState a.button-primary:active,.woocommerce-BlankState a.button-primary:focus,.woocommerce-BlankState a.button-primary:hover,.woocommerce-BlankState button.button-primary:active,.woocommerce-BlankState button.button-primary:focus,.woocommerce-BlankState button.button-primary:hover,.woocommerce-message a.button-primary:active,.woocommerce-message a.button-primary:focus,.woocommerce-message a.button-primary:hover,.woocommerce-message button.button-primary:active,.woocommerce-message button.button-primary:focus,.woocommerce-message button.button-primary:hover{background:#A36597;border-color:#A36597;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597;box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 1px 0 #A36597}.woocommerce-message{position:relative;border-left-color:#cc99c2!important;overflow:hidden}.woocommerce-message a.docs,.woocommerce-message a.skip{text-decoration:none!important}.woocommerce-message a.woocommerce-message-close{position:absolute;top:10px;right:10px;padding:10px 15px 10px 21px;font-size:13px;line-height:1.23076923;text-decoration:none}.woocommerce-message a.woocommerce-message-close:before{position:absolute;top:8px;left:0;-webkit-transition:all .1s ease-in-out;transition:all .1s ease-in-out}.woocommerce-message .twitter-share-button{margin-top:-3px;margin-left:3px;vertical-align:middle}#variable_product_options #message,#variable_product_options .notice{margin:10px}.clear{clear:both}#woocommerce-fields-bulk.inline-edit-col label,#woocommerce-fields.inline-edit-col{clear:left}.wrap.woocommerce div.error,.wrap.woocommerce div.updated{margin-top:10px}mark.amount{background:0 0;color:inherit}.postbox,.woocommerce{input:invalid;input-border:1px solid #cc010b;input-background:#ffebe8}.simplify-commerce-banner{overflow:hidden}.simplify-commerce-banner img{float:right;padding:15px 0;margin-left:1em;width:200px}.woocommerce-help-tip{color:#666;display:inline-block;font-size:1.1em;font-style:normal;height:16px;line-height:16px;position:relative;vertical-align:middle;width:16px}.woocommerce-help-tip:after{font-family:Dashicons;font-weight:400;font-variant:normal;line-height:1;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";cursor:help}h2 .woocommerce-help-tip{margin-top:-5px;margin-left:.25em}table.wc_status_table{margin-bottom:1em}table.wc_status_table h2{font-size:14px;margin:0}table.wc_status_table tr:nth-child(2n) td,table.wc_status_table tr:nth-child(2n) th{background:#fcfcfc}table.wc_status_table th{font-weight:700;padding:9px}table.wc_status_table td:first-child{width:33%}table.wc_status_table td.help{width:1em}table.wc_status_table td{padding:9px;font-size:1.1em}table.wc_status_table td mark{background:0 0}table.wc_status_table td mark.yes{color:#7ad03a}table.wc_status_table td mark.no{color:#999}table.wc_status_table td mark.error{color:#a00}table.wc_status_table td ul{margin:0}table.wc_status_table .help_tip{cursor:help}#debug-report{display:none;margin:10px 0;padding:0;position:relative}#debug-report textarea{font-family:monospace;width:100%;margin:0;height:300px;padding:20px;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0;resize:none;font-size:12px;line-height:20px;outline:0}#log-viewer-select{padding:10px 0 8px;line-height:28px}#log-viewer-select h2 a{vertical-align:middle}#log-viewer textarea{width:100%;resize:vertical}.inline-edit-product.quick-edit-row .inline-edit-col-center,.inline-edit-product.quick-edit-row .inline-edit-col-right{float:right!important}#woocommerce-fields.inline-edit-col label.featured,#woocommerce-fields.inline-edit-col label.manage_stock{margin-left:10px}#woocommerce-fields.inline-edit-col .dimensions div{display:block;margin:.2em 0}#woocommerce-fields.inline-edit-col .dimensions div span.title{display:block;float:left;width:5em}#woocommerce-fields.inline-edit-col .dimensions div span.input-text-wrap{display:block;margin-left:5em}#woocommerce-fields.inline-edit-col .text{box-sizing:border-box;width:99%;float:left;margin:1px 1% 1px 1px}#woocommerce-fields.inline-edit-col .height,#woocommerce-fields.inline-edit-col .length,#woocommerce-fields.inline-edit-col .width{width:32.33%}#woocommerce-fields.inline-edit-col .height{margin-right:0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group label{clear:none;width:49%;margin:.2em 0}#woocommerce-fields-bulk.inline-edit-col .inline-edit-group.dimensions label{width:75%;max-width:75%}#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .regular_price,#woocommerce-fields-bulk.inline-edit-col .sale_price,#woocommerce-fields-bulk.inline-edit-col .stock,#woocommerce-fields-bulk.inline-edit-col .weight{box-sizing:border-box;width:100%;margin-left:4.4em}#woocommerce-fields-bulk.inline-edit-col .height,#woocommerce-fields-bulk.inline-edit-col .length,#woocommerce-fields-bulk.inline-edit-col .width{box-sizing:border-box;width:25%}.column-coupon_code{line-height:2.25em}.column-coupon_code,ul.wc_coupon_list{margin:0;overflow:hidden;zoom:1;clear:both}ul.wc_coupon_list li{margin:0}ul.wc_coupon_list li.code{display:inline-block}ul.wc_coupon_list li.code:after{content:", "}ul.wc_coupon_list li.code:last-of-type:after{display:none}ul.wc_coupon_list li.code .tips{cursor:pointer}ul.wc_coupon_list_block{margin:0;padding-bottom:2px}ul.wc_coupon_list_block li{border-top:1px solid #fff;border-bottom:1px solid #ccc;line-height:2.5em;margin:0;padding:.5em 0}ul.wc_coupon_list_block li:first-child{border-top:0;padding-top:0}ul.wc_coupon_list_block li:last-child{border-bottom:0;padding-bottom:0}.button.wc-reload{text-indent:-9999px;position:relative;padding:0;height:28px;width:28px!important;display:inline-block}.button.wc-reload:after{font-family:Dashicons;font-weight:400;font-variant:normal;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:28px}#order_data h2,#order_data p.order_number{font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif;font-weight:400}.tablenav .actions{overflow:visible}.tablenav .select2-container{float:left;max-width:200px;font-size:14px;vertical-align:middle;margin:1px 6px 1px 1px}#woocommerce-order-data .handlediv,#woocommerce-order-data .hndle{display:none}#woocommerce-order-data .inside{display:block!important}#order_data{padding:23px 24px 12px}#order_data h2{margin:0;font-size:21px;line-height:1.2;text-shadow:1px 1px 1px #fff;padding:0}#order_data h3{font-size:14px}#order_data h3,#order_data h4{color:#333;margin:1.33em 0 0}#order_data p{color:#777}#order_data p.order_number{margin:0;line-height:1.6em;font-size:16px}#order_data .order_data_column_container{clear:both}#order_data .order_data_column{width:32%;padding:0 2% 0 0;float:left}#order_data .order_data_column:last-child{padding-right:0}#order_data .order_data_column p{padding:0!important}#order_data .order_data_column .address strong{display:block}#order_data .order_data_column .form-field{float:left;width:48%;padding:0;margin:9px 0 0}#order_data .order_data_column .form-field label{display:block;padding:0 0 3px}#order_data .order_data_column .form-field input,#order_data .order_data_column .form-field select,#order_data .order_data_column .form-field textarea{width:100%}#order_data .order_data_column .form-field .select2-container{width:100%!important}#order_data .order_data_column .form-field .date-picker{width:50%}#order_data .order_data_column .form-field .hour,#order_data .order_data_column .form-field .minute{width:2.5em}#order_data .order_data_column .form-field small{display:block;margin:5px 0 0;color:#999}#order_data .order_data_column .form-field.last{float:right}#order_data .order_data_column .form-field-wide{width:100%;clear:both}#order_data .order_data_column .form-field-wide .wc-customer-search,#order_data .order_data_column .form-field-wide .wc-enhanced-select,#order_data .order_data_column .form-field-wide input,#order_data .order_data_column .form-field-wide select,#order_data .order_data_column .form-field-wide textarea{width:100%}#order_data .order_data_column p.none_set{color:#999}#order_data .order_data_column ._billing_address_1_field,#order_data .order_data_column ._billing_city_field,#order_data .order_data_column ._billing_country_field,#order_data .order_data_column ._billing_email_field,#order_data .order_data_column ._billing_first_name_field,#order_data .order_data_column ._shipping_address_1_field,#order_data .order_data_column ._shipping_city_field,#order_data .order_data_column ._shipping_country_field,#order_data .order_data_column ._shipping_first_name_field{float:left}#order_data .order_data_column ._billing_address_2_field,#order_data .order_data_column ._billing_last_name_field,#order_data .order_data_column ._billing_phone_field,#order_data .order_data_column ._billing_postcode_field,#order_data .order_data_column ._billing_state_field,#order_data .order_data_column ._shipping_address_2_field,#order_data .order_data_column ._shipping_last_name_field,#order_data .order_data_column ._shipping_postcode_field,#order_data .order_data_column ._shipping_state_field,#order_data .order_data_column .wc-customer-user label a,#order_data .order_data_column .wc-order-status label a{float:right}#order_data .order_data_column ._billing_company_field,#order_data .order_data_column ._shipping_company_field,#order_data .order_data_column ._transaction_id_field{clear:both;width:100%}#order_data .order_data_column ._billing_email_field{clear:left}#order_data .order_data_column div.edit_address{display:none;zoom:1;padding-right:1px}#order_data .order_data_column .billing-same-as-shipping,#order_data .order_data_column .load_customer_billing,#order_data .order_data_column .load_customer_shipping,#order_data .order_data_column a.edit_address{width:14px;height:0;padding:14px 0 0;margin:0 0 0 6px;overflow:hidden;position:relative;color:#999;border:0;float:right}#order_data .order_data_column .billing-same-as-shipping:focus,#order_data .order_data_column .billing-same-as-shipping:hover,#order_data .order_data_column .load_customer_billing:focus,#order_data .order_data_column .load_customer_billing:hover,#order_data .order_data_column .load_customer_shipping:focus,#order_data .order_data_column .load_customer_shipping:hover,#order_data .order_data_column a.edit_address:focus,#order_data .order_data_column a.edit_address:hover{color:#000}#order_data .order_data_column .billing-same-as-shipping:after,#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after,#order_data .order_data_column a.edit_address: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}#order_data .order_data_column .billing-same-as-shipping:after{content:"\e008"}#order_data .order_data_column .load_customer_billing:after,#order_data .order_data_column .load_customer_shipping:after{content:"\e03a"}#order_data .order_data_column a.edit_address:after{font-family:Dashicons;content:"\f464"}.order_actions{margin:0;overflow:hidden;zoom:1}.order_actions li{border-top:1px solid #fff;border-bottom:1px solid #ddd;padding:6px 0;margin:0;line-height:1.6em;float:left;width:50%;text-align:center}.order_actions li a{float:none;text-align:center;text-decoration:underline}.order_actions li.wide{width:auto;float:none;clear:both;padding:6px;text-align:left;overflow:hidden}.order_actions li #delete-action{line-height:25px;vertical-align:middle;text-align:left;float:left}.order_actions li .save_order{float:right}.order_actions li#actions{overflow:hidden}.order_actions li#actions .button{width:24px;box-sizing:border-box;float:right}.order_actions li#actions select{width:225px;box-sizing:border-box;float:left}#woocommerce-order-items .inside{margin:0;padding:0;background:#fefefe}#woocommerce-order-items .wc-order-data-row{border-bottom:1px solid #DFDFDF;padding:1.5em 2em;background:#f8f8f8;line-height:2em;text-align:right}#woocommerce-order-items .wc-order-data-row:after,#woocommerce-order-items .wc-order-data-row:before{content:" ";display:table}#woocommerce-order-items .wc-order-data-row:after{clear:both}#woocommerce-order-items .wc-order-data-row p{margin:0;line-height:2em}#woocommerce-order-items .wc-order-data-row .wc-used-coupons{text-align:left}#woocommerce-order-items .wc-order-data-row .wc-used-coupons .tips{display:inline-block}#woocommerce-order-items .wc-order-add-item{background:#fff;vertical-align:top;border-top:none}#woocommerce-order-items .wc-order-add-item .add_item_id,#woocommerce-order-items .wc-order-add-item .select2-container{vertical-align:top}#woocommerce-order-items .wc-order-add-item .add_item_id .search-field input,#woocommerce-order-items .wc-order-add-item .select2-container .search-field input{min-width:100px}#woocommerce-order-items .wc-order-add-item .select2-container{width:400px!important;text-align:left}#woocommerce-order-items .wc-order-add-item .calculate-action,#woocommerce-order-items .wc-order-add-item .cancel-action,#woocommerce-order-items .wc-order-add-item .save-action{float:left;margin-right:2px}#woocommerce-order-items .wc-used-coupons{float:left;width:50%}#woocommerce-order-items .wc-order-totals{float:right;width:50%;margin:0;padding:0;text-align:right}#woocommerce-order-items .wc-order-totals .amount{font-weight:700}#woocommerce-order-items .wc-order-totals .label{vertical-align:top}#woocommerce-order-items .wc-order-totals .total{font-size:1em!important;width:10em;margin:0 0 0 .5em;box-sizing:border-box}#woocommerce-order-items .wc-order-totals .total input[type=text]{width:96%;float:right}#woocommerce-order-items .wc-order-totals .refunded-total{color:#a00}#woocommerce-order-items .refund-actions{margin-top:5px;padding-top:12px;border-top:1px solid #DFDFDF}#woocommerce-order-items .refund-actions .button{float:right;margin-left:4px}#woocommerce-order-items .refund-actions .cancel-action,#woocommerce-order-items .wc-order-item-bulk-edit .cancel-action{float:left;margin-left:0}#woocommerce-order-items .add_meta{margin-left:0!important}#woocommerce-order-items h3 small{color:#999}#woocommerce-order-items .amount{white-space:nowrap}#woocommerce-order-items .add-items .description{margin-right:10px}#woocommerce-order-items .add-items .button{float:left;margin-right:.25em}#woocommerce-order-items .add-items .button-primary{float:none;margin-right:0}#woocommerce-order-items .inside{display:block!important}#woocommerce-order-items .handlediv,#woocommerce-order-items .hndle{display:none}#woocommerce-order-items .woocommerce_order_items_wrapper{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items{width:100%;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th{text-align:left;padding:1em;font-weight:400;color:#999;background:#f8f8f8;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th.sortable{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items thead th .wc-arrow{float:right;position:relative;margin-right:-1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td{padding:1.5em 1em 1em;text-align:left;line-height:1.5em;vertical-align:top;border-bottom:1px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td select{width:50%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td textarea{font-size:14px;padding:4px;color:#555}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:last-child{padding-right:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody th:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td:first-child{padding-left:2em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr td{cursor:pointer}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected{background:#F5EBF3}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr.selected td{border-color:#E6CCE1;opacity:.8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:last-child td{border-bottom:1px solid #dfdfdf}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody tr:first-child td{border-top:8px solid #f8f8f8}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tbody#order_line_items tr:first-child td{border-top:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb{text-align:left;width:38px;padding-bottom:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail{width:38px;height:38px;border:2px solid #e8e8e8;background:#f8f8f8;color:#ccc;position:relative;font-size:21px;display:block;text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;height:100%;text-align:center;content:"";width:38px;line-height:38px;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.thumb .wc-order-item-thumbnail img{width:100%;height:100%;margin:0;padding:0;position:relative}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-sku,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.name .wc-order-item-variation{display:block;margin-top:.5em;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item{min-width:200px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .center,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .variation-id{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class{text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label{white-space:nowrap;color:#999;font-size:.833em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax label input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class label input{display:inline}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class input{width:70px;vertical-align:middle;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax select,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class select{width:85px;height:26px;vertical-align:middle;font-size:1em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input{display:inline-block;background:#fff;border:1px solid #ddd;box-shadow:inset 0 1px 2px rgba(0,0,0,.07);margin:1px 0;min-width:80px;overflow:hidden;line-height:1em;text-align:right}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input{width:100%;box-sizing:border-box}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input label{font-size:.75em;padding:4px 6px 0;color:#555;display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input{width:100%;box-sizing:border-box;border:0;box-shadow:none;margin:0;padding:0 6px 4px;color:#555;background:0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input input::-webkit-input-placeholder,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input input::-webkit-input-placeholder{color:#ddd}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child{border-bottom:1px dashed #ddd;background:#fff}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .split-input div.input:first-child label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .split-input div.input:first-child label{color:#ccc}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .view,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .view{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .edit,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .edit{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class del,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-taxes label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-refund-fields label,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-taxes label{display:block}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax .wc-order-item-discount,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class .wc-order-item-discount{display:block;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .item_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_cost small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .line_tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax small.times,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .tax_class small.times{margin-right:.25em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity{text-align:center}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .quantity input{text-align:center;width:50px}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items span.subtotal{opacity:.5}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.tax_class,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.tax_class{text-align:left}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .calculated{border-color:#ae8ca2;border-style:dotted}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{width:100%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta{margin:.5em 0 0;font-size:.92em!important;color:#888}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{color:#ccc;top:0;left:0;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-align:center;font-family:WooCommerce}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr th,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr th{border:0;padding:0 4px .5em 0;line-height:1.5em;width:20%}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td{padding:0 4px .5em 0;border:0;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input{width:100%;margin:0;position:relative;border-bottom:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items .refund_by,ul.order_notes li p.meta .exact-date{border-bottom:1px dotted #999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td textarea{width:100%;height:4em;margin:0;box-shadow:none}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td input:focus+textarea,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td input:focus+textarea{border-top-color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p{margin:0 0 .5em;line-height:1.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.display_meta tr td p:last-child,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items table.meta tr td p:last-child{margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.fee .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.refund .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.5em;line-height:1em;vertical-align:middle;margin:0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .thumb div:before{line-height:1;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items tr.shipping .shipping_method_name{width:100%;margin:0 0 .5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax{white-space:nowrap}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;float:right;font-size:14px;visibility:hidden;margin:3px -18px 0 0}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax .delete-order-tax:hover:before,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax .delete-order-tax:hover:before{color:#a00}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items td.line_tax:hover .delete-order-tax,#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items th.line_tax:hover .delete-order-tax{visibility:visible}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded{display:block;color:#a00;white-space:nowrap;margin-top:.5em}#woocommerce-order-items .woocommerce_order_items_wrapper table.woocommerce_order_items small.refunded:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;width:100%;height:100%;text-align:center;content:"";position:relative;top:auto;left:auto;margin:-1px 4px 0 0;vertical-align:middle;line-height:1em}#woocommerce-order-items .wc-order-edit-line-item{padding-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions{width:44px;text-align:right;padding-left:0;vertical-align:middle}#woocommerce-order-items .wc-order-edit-line-item-actions a{color:#ccc;display:inline-block;cursor:pointer;padding:0 0 .5em;margin:0 0 0 12px;vertical-align:middle;text-decoration:none;line-height:16px;width:16px;overflow:hidden}#woocommerce-order-items .wc-order-edit-line-item-actions a:before{margin:0;padding:0;font-size:16px;width:16px;height:16px}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before,#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{font-family:Dashicons;-webkit-font-smoothing:antialiased;text-indent:0;top:0;left:0;width:100%;height:100%;margin:0;text-align:center;position:relative;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1}#woocommerce-order-items .wc-order-edit-line-item-actions a:hover:before{color:#999}#woocommerce-order-items .wc-order-edit-line-item-actions a:first-child{margin-left:0}#woocommerce-order-items .wc-order-edit-line-item-actions .edit-order-item:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:before{content:""}#woocommerce-order-items .wc-order-edit-line-item-actions .delete-order-item:hover:before,#woocommerce-order-items .wc-order-edit-line-item-actions .delete_refund:hover:before{color:#a00}#woocommerce-order-items tbody tr .wc-order-edit-line-item-actions{visibility:hidden}#woocommerce-order-items tbody tr:hover .wc-order-edit-line-item-actions{visibility:visible}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions{width:1.5em;visibility:visible!important}#woocommerce-order-items .wc-order-totals .wc-order-edit-line-item-actions a{padding:0}#woocommerce-order-downloads .buttons{float:left;padding:0;margin:0;vertical-align:top}#woocommerce-order-downloads .buttons .add_item_id,#woocommerce-order-downloads .buttons .select2-container{width:400px!important;margin-right:9px;vertical-align:top;float:left}#woocommerce-order-downloads .buttons button{margin:2px 0 0}#woocommerce-order-downloads h3 small{color:#999}#poststuff #woocommerce-order-actions .inside{margin:0;padding:0}#poststuff #woocommerce-order-actions .inside ul.order_actions li{padding:6px 10px;box-sizing:border-box}#poststuff #woocommerce-order-actions .inside ul.order_actions li:last-child{border-bottom:0}#poststuff #woocommerce-order-notes .inside{margin:0;padding:0}#poststuff #woocommerce-order-notes .inside ul.order_notes li{padding:0 10px}#woocommerce_customers p.search-box{margin:6px 0 4px;float:left}#woocommerce_customers .tablenav{float:right;clear:none}.widefat.customers td{vertical-align:middle;padding:4px 7px}.widefat .column-order_title{width:15%}.widefat .column-order_title time{display:block;color:#999;margin:3px 0}.widefat .column-orders,.widefat .column-paying,.widefat .column-spent{text-align:center;width:8%}.widefat .column-last_order{width:11%}.widefat .column-order_actions,.widefat .column-user_actions,.widefat .column-wc_actions{width:110px}.widefat .column-order_actions a.button,.widefat .column-user_actions a.button,.widefat .column-wc_actions a.button{float:left;margin:0 4px 2px 0;cursor:pointer;padding:3px 4px;height:auto}.widefat .column-order_actions a.button img,.widefat .column-user_actions a.button img,.widefat .column-wc_actions a.button img{display:block;width:12px;height:auto}.widefat small.meta{display:block;color:#999;font-size:inherit;margin:3px 0}.widefat .column-order_date,.widefat .column-order_total{width:9%}.widefat .column-order_status{width:45px;text-align:center}.widefat .column-order_status mark{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;background:0 0;font-size:1.4em;margin:0 auto}.widefat .column-order_status mark.cancelled:after,.widefat .column-order_status mark.completed:after,.widefat .column-order_status mark.failed:after,.widefat .column-order_status mark.on-hold:after,.widefat .column-order_status mark.pending:after,.widefat .column-order_status mark.processing:after,.widefat .column-order_status mark.refunded:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}.column-customer_message .note-on:after,.column-order_notes .note-on:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;left:0;text-align:center;line-height:16px;font-family:WooCommerce}.widefat .column-order_status mark.pending:after{content:"\e012";color:#ffba00}.widefat .column-order_status mark.completed:after{content:"\e015";color:#2ea2cc}.widefat .column-order_status mark.on-hold:after{content:"\e033";color:#999}.widefat .column-order_status mark.failed:after{content:"\e016";color:#d0c21f}.widefat .column-order_status mark.cancelled:after{content:"\e013";color:#a00}.widefat .column-order_status mark.processing:after{content:"\e011";color:#73a724}.widefat .column-order_status mark.refunded:after{content:"\e014";color:#999}.widefat td.column-order_status{padding-top:9px}.column-customer_message .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-customer_message .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.column-order_notes .note-on{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto;color:#999}.column-order_notes .note-on:after{margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}.order_actions .complete,.order_actions .processing,.order_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.order_actions .processing:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.order_actions .complete:after,.order_actions .view:after{font-family:Dashicons;text-indent:0;position:absolute;width:100%;height:100%;left:0;line-height:1.85;margin:0;text-align:center;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;top:0;font-weight:400}.order_actions .complete:after{content:""}.order_actions .view:after{content:""}.user_actions .edit,.user_actions .link,.user_actions .refresh,.user_actions .view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.user_actions .edit:after,.user_actions .link:after,.user_actions .refresh:after,.user_actions .view:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";line-height:1.85}.user_actions .edit:after{font-family:Dashicons;content:"\f464"}.user_actions .link:after{content:"\e00d"}.user_actions .view:after{content:"\e010"}.user_actions .refresh:after{content:"\e031"}.attributes-table td,.attributes-table th{width:15%;vertical-align:top}.attributes-table .attribute-terms{width:32%}.attributes-table .attribute-actions{width:2em}.attributes-table .attribute-actions .configure-terms{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.attributes-table .attribute-actions .configure-terms:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}ul.order_notes{padding:2px 0 0}ul.order_notes li .note_content{padding:10px;background:#efefef;position:relative}ul.order_notes li .note_content p{margin:0;padding:0;word-wrap:break-word}ul.order_notes li p.meta{padding:10px;color:#999;margin:0;font-size:11px}ul.order_notes li a.delete_note{color:#a00}table.wp-list-table .row-actions,table.wp-list-table span.na{color:#999}ul.order_notes li .note_content:after{content:"";display:block;position:absolute;bottom:-10px;left:20px;width:0;height:0;border-width:10px 10px 0 0;border-style:solid;border-color:#efefef transparent}ul.order_notes li.customer-note .note_content{background:#A7CEDC}ul.order_notes li.customer-note .note_content:after{border-color:#A7CEDC transparent}ul.order_notes li.system-note .note_content{background:#d7cad2}ul.order_notes li.system-note .note_content:after{border-color:#d7cad2 transparent}.add_note{border-top:1px solid #ddd;padding:10px 10px 0}.add_note h4{margin-top:5px!important}.add_note #add_order_note{width:100%;height:50px}table.wp-list-table .column-thumb{width:52px;text-align:center;white-space:nowrap}table.wp-list-table .column-name{width:22%}table.wp-list-table .column-product_cat,table.wp-list-table .column-product_tag{width:11%!important}table.wp-list-table .column-featured,table.wp-list-table .column-product_type{width:48px;text-align:left!important}table.wp-list-table .column-customer_message,table.wp-list-table .column-order_notes{width:48px;text-align:center}table.wp-list-table .column-customer_message img,table.wp-list-table .column-order_notes img{margin:0 auto;padding-top:0!important}table.wp-list-table .manage-column.column-featured img,table.wp-list-table .manage-column.column-product_type img{padding-left:2px}table.wp-list-table .column-price .woocommerce-price-suffix{display:none}table.wp-list-table img{margin:1px 2px}table.wp-list-table td.column-thumb img{margin:0;width:auto;height:auto;max-width:40px;max-height:40px;vertical-align:middle}table.wp-list-table .column-is_in_stock{text-align:left!important}table.wp-list-table span.wc-featured,table.wp-list-table span.wc-image,table.wp-list-table span.wc-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table span.wc-featured:before,table.wp-list-table span.wc-image:before,table.wp-list-table span.wc-type:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:""}table.wp-list-table span.wc-featured{margin:0;cursor:pointer}table.wp-list-table span.wc-featured:before{content:"\f155"}table.wp-list-table span.wc-featured.not-featured:before{content:"\f154"}table.wp-list-table td.column-featured span.wc-featured{font-size:1.6em}table.wp-list-table span.wc-type{margin:0}table.wp-list-table span.wc-type:before{font-family:WooCommerce;content:"\e006"}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after,table.wp-list-table span.product-type:before{font-family:WooCommerce;text-align:center;line-height:1;top:0;speak:none;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;left:0}table.wp-list-table span.product-type{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.6em}table.wp-list-table span.product-type:before{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%;content:""}table.wp-list-table span.product-type.grouped:before{content:"\e002"}table.wp-list-table span.product-type.external:before{content:"\e034"}table.wp-list-table span.product-type.variable:before{content:"\e003"}table.wp-list-table span.product-type.downloadable:before{content:"\e001"}table.wp-list-table span.product-type.virtual:before{content:"\e000"}table.wp-list-table mark.instock{font-weight:700;color:#7ad03a;background:0 0;line-height:1}table.wp-list-table mark.outofstock{font-weight:700;color:#a44;background:0 0;line-height:1}table.wp-list-table .notes_head,table.wp-list-table .order-notes_head,table.wp-list-table .status_head{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;margin:0 auto}table.wp-list-table .notes_head:after,table.wp-list-table .order-notes_head:after,table.wp-list-table .status_head:after{font-weight:400;margin:0;text-indent:0;position:absolute;width:100%;height:100%}table.wc_emails .wc-email-settings-table-name,table.wc_emails td.name,table.wc_gateways .wc-email-settings-table-name,table.wc_gateways td.name,table.wc_shipping .wc-email-settings-table-name,table.wc_shipping td.name{font-weight:700}table.wp-list-table .order-notes_head:after{content:"\e028"}table.wp-list-table .notes_head:after{content:"\e026"}table.wp-list-table .status_head:after{content:"\e011"}table.wp-list-table .column-order_items{width:12%}table.wp-list-table .column-order_items table.order_items{width:100%;margin:3px 0 0;padding:0;display:none}table.wp-list-table .column-order_items table.order_items td{border:0;margin:0;padding:0 0 3px}table.wp-list-table .column-order_items table.order_items td.qty{color:#999;padding-right:6px;text-align:left}mark.notice{background:#fff;color:#a00;margin:0 0 0 10px}a.export_rates,a.import_rates{float:right;margin-left:9px;margin-top:-2px;margin-bottom:0}#rates-search{float:right}#rates-search input.wc-tax-rates-search-field{padding:4px 8px;font-size:1.2em}#rates-pagination{float:right;margin-right:.5em}#rates-pagination .tablenav{margin:0}table.wc_input_table,table.wc_tax_rates{width:100%}table.wc_input_table span.tips,table.wc_tax_rates span.tips{color:#2ea2cc}table.wc_input_table td,table.wc_tax_rates td{padding:0;border-right:1px solid #DFDFDF;border-bottom:1px solid #DFDFDF;border-top:0;background:#fff}table.wc_input_table td input[type=text],table.wc_input_table td input[type=number],table.wc_tax_rates td input[type=text],table.wc_tax_rates td input[type=number]{width:100%;padding:5px 7px;margin:0;border:0;background:0 0}table.wc_input_table td.apply_to_shipping,table.wc_input_table td.compound,table.wc_tax_rates td.apply_to_shipping,table.wc_tax_rates td.compound{padding:5px 7px;vertical-align:middle}table.wc_input_table td.apply_to_shipping input,table.wc_input_table td.compound input,table.wc_tax_rates td.apply_to_shipping input,table.wc_tax_rates td.compound input{width:auto;padding:0}table.wc_input_table td:last-child,table.wc_tax_rates td:last-child{border-right:0}table.wc_input_table tr.current td,table.wc_tax_rates tr.current td{background-color:#fefbcc}table.wc_input_table .cost,table.wc_input_table .cost input,table.wc_input_table .item_cost,table.wc_input_table .item_cost input,table.wc_tax_rates .cost,table.wc_tax_rates .cost input,table.wc_tax_rates .item_cost,table.wc_tax_rates .item_cost input{text-align:right}table.wc_input_table th.sort,table.wc_tax_rates th.sort{width:17px;padding:0 4px}table.wc_input_table td.sort,table.wc_tax_rates td.sort{padding:0 4px}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort{cursor:move;font-size:15px;background:#f9f9f9;text-align:center;vertical-align:middle}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_input_table .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before,table.wc_tax_rates .ui-sortable:not(.ui-sortable-disabled) td.sort:hover:before{color:#333}table.wc_input_table .button,table.wc_tax_rates .button{float:left;margin-right:5px}table.wc_input_table .export,table.wc_input_table .import,table.wc_tax_rates .export,table.wc_tax_rates .import{float:right;margin-right:0;margin-left:5px}table.wc_input_table span.tips,table.wc_tax_rates span.tips{padding:0 3px}table.wc_input_table .pagination,table.wc_tax_rates .pagination{float:right}table.wc_input_table .pagination .button,table.wc_tax_rates .pagination .button{margin-left:5px;margin-right:0}table.wc_input_table .pagination .current,table.wc_tax_rates .pagination .current{background:#bbb;text-shadow:none}table.wc_input_table tfoot th,table.wc_tax_rates tfoot th{padding-left:20px;padding-right:20px}table.wc_input_table tr:last-child td,table.wc_tax_rates tr:last-child td{border-bottom:0}table.wc_emails,table.wc_gateways,table.wc_shipping{position:relative}table.wc_emails td,table.wc_gateways td,table.wc_shipping td{vertical-align:middle;padding:7px;line-height:2em}table.wc_emails tr:nth-child(odd) td,table.wc_gateways tr:nth-child(odd) td,table.wc_shipping tr:nth-child(odd) td{background:#f9f9f9}table.wc_emails th,table.wc_gateways th,table.wc_shipping th{padding:9px 7px!important;vertical-align:middle}table.wc_emails .settings,table.wc_gateways .settings,table.wc_shipping .settings{text-align:right}table.wc_emails .default,table.wc_emails .radio,table.wc_emails .status,table.wc_gateways .default,table.wc_gateways .radio,table.wc_gateways .status,table.wc_shipping .default,table.wc_shipping .radio,table.wc_shipping .status{text-align:center}table.wc_emails .default .tips,table.wc_emails .radio .tips,table.wc_emails .status .tips,table.wc_gateways .default .tips,table.wc_gateways .radio .tips,table.wc_gateways .status .tips,table.wc_shipping .default .tips,table.wc_shipping .radio .tips,table.wc_shipping .status .tips{margin:0 auto}table.wc_emails .default input,table.wc_emails .radio input,table.wc_emails .status input,table.wc_gateways .default input,table.wc_gateways .radio input,table.wc_gateways .status input,table.wc_shipping .default input,table.wc_shipping .radio input,table.wc_shipping .status input{margin:0}table.wc_emails th.sort,table.wc_gateways th.sort,table.wc_shipping th.sort{width:28px;padding:0}table.wc_emails td.sort,table.wc_gateways td.sort,table.wc_shipping td.sort{padding:0 7px;cursor:move;font-size:15px;text-align:center;vertical-align:middle}table.wc_emails td.sort:before,table.wc_gateways td.sort:before,table.wc_shipping td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}table.wc_emails .wc-email-settings-table-name span,table.wc_gateways .wc-email-settings-table-name span,table.wc_shipping .wc-email-settings-table-name span{font-weight:400;color:#999;margin:0 0 0 4px!important}table.wc_emails .wc-email-settings-table-status,table.wc_gateways .wc-email-settings-table-status,table.wc_shipping .wc-email-settings-table-status{text-align:center;width:1em}table.wc_emails .wc-email-settings-table-status .tips,table.wc_gateways .wc-email-settings-table-status .tips,table.wc_shipping .wc-email-settings-table-status .tips{margin:0 auto}table.wc_emails .wc-email-settings-table-actions a,table.wc_gateways .wc-email-settings-table-actions a,table.wc_shipping .wc-email-settings-table-actions a{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}table.wc_emails .wc-email-settings-table-actions a:after,table.wc_gateways .wc-email-settings-table-actions a:after,table.wc_shipping .wc-email-settings-table-actions a:after{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-family:Dashicons;line-height:1.85}table.wc-shipping-classes td,table.wc-shipping-classes th,table.wc-shipping-zone-methods td,table.wc-shipping-zone-methods th,table.wc-shipping-zones td,table.wc-shipping-zones th{vertical-align:top;line-height:24px;padding:1em;font-size:14px;background:#fff}table.wc-shipping-classes td li,table.wc-shipping-classes th li,table.wc-shipping-zone-methods td li,table.wc-shipping-zone-methods th li,table.wc-shipping-zones td li,table.wc-shipping-zones th li{line-height:24px;font-size:14px}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state,table.wc-shipping-classes td.wc-shipping-zones-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state,table.wc-shipping-zones td.wc-shipping-zones-blank-state{background:#F7F1F6!important;overflow:hidden;position:relative;padding:7.5em 7.5%;border-bottom:2px solid #EEE2EC}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p,table.wc-shipping-zones td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state p{color:#a46497;font-size:1.5em;line-height:1.5em;margin:0 0 1em;position:relative;z-index:1;text-shadow:1px 1px 1px #fff}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state li.main,table.wc-shipping-classes td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state p.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state li.main,table.wc-shipping-zones td.wc-shipping-zones-blank-state p.main{font-size:2em}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state li,table.wc-shipping-classes td.wc-shipping-zones-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state li,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state li,table.wc-shipping-zones td.wc-shipping-zones-blank-state li{margin-left:1em;list-style:circle inside}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-classes td.wc-shipping-zones-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state:before,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state:before,table.wc-shipping-zones td.wc-shipping-zones-blank-state:before{content:"\e01b";font-family:WooCommerce;text-align:center;line-height:1;color:#EEE2EC;display:block;width:1em;font-size:40em;top:50%;right:-3.75%;margin-top:-.1875em;position:absolute}table.wc-shipping-classes td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-classes td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zone-methods td.wc-shipping-zones-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zone-method-blank-state .button-primary,table.wc-shipping-zones td.wc-shipping-zones-blank-state .button-primary{background-color:#804877;border-color:#804877;-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);margin:0;opacity:1;text-shadow:0 -1px 1px #8a4f7f,1px 0 1px #8a4f7f,0 1px 1px #8a4f7f,-1px 0 1px #8a4f7f;font-size:1.5em;padding:.75em 1em;height:auto;position:relative;z-index:1}table.wc-shipping-classes .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-classes .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-classes tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-classes tr.odd td,table.wc-shipping-zone-methods .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zone-methods tr.odd td,table.wc-shipping-zones .wc-shipping-class-rows tr:nth-child(odd) td,table.wc-shipping-zones .wc-shipping-zone-method-rows tr:nth-child(odd) td,table.wc-shipping-zones tbody.wc-shipping-zone-rows tr:nth-child(odd) td,table.wc-shipping-zones tr.odd td{background:#f9f9f9}table.wc-shipping-classes p,table.wc-shipping-classes ul,table.wc-shipping-zone-methods p,table.wc-shipping-zone-methods ul,table.wc-shipping-zones p,table.wc-shipping-zones ul{margin:0}table.wc-shipping-classes td.wc-shipping-zone-method-sort,table.wc-shipping-classes td.wc-shipping-zone-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort,table.wc-shipping-zone-methods td.wc-shipping-zone-sort,table.wc-shipping-zones td.wc-shipping-zone-method-sort,table.wc-shipping-zones td.wc-shipping-zone-sort{cursor:move;font-size:15px;text-align:center}table.wc-shipping-classes td.wc-shipping-zone-method-sort:before,table.wc-shipping-classes td.wc-shipping-zone-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:before,table.wc-shipping-zones td.wc-shipping-zone-sort:before{content:"\f333";font-family:Dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-classes td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zone-methods td.wc-shipping-zone-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-method-sort:hover:before,table.wc-shipping-zones td.wc-shipping-zone-sort:hover:before{color:#333}table.wc-shipping-classes td.wc-shipping-zone-worldwide,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide,table.wc-shipping-zones td.wc-shipping-zone-worldwide{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-worldwide:before,table.wc-shipping-zone-methods td.wc-shipping-zone-worldwide:before,table.wc-shipping-zones td.wc-shipping-zone-worldwide:before{content:"\f319";font-family:dashicons;text-align:center;color:#999;display:block;width:17px;float:left;height:100%;line-height:24px}table.wc-shipping-classes .wc-shipping-zone-methods,table.wc-shipping-classes .wc-shipping-zone-name,table.wc-shipping-zone-methods .wc-shipping-zone-methods,table.wc-shipping-zone-methods .wc-shipping-zone-name,table.wc-shipping-zones .wc-shipping-zone-methods,table.wc-shipping-zones .wc-shipping-zone-name{width:25%}table.wc-shipping-classes .wc-shipping-class-description input,table.wc-shipping-classes .wc-shipping-class-description select,table.wc-shipping-classes .wc-shipping-class-description textarea,table.wc-shipping-classes .wc-shipping-class-name input,table.wc-shipping-classes .wc-shipping-class-name select,table.wc-shipping-classes .wc-shipping-class-name textarea,table.wc-shipping-classes .wc-shipping-class-slug input,table.wc-shipping-classes .wc-shipping-class-slug select,table.wc-shipping-classes .wc-shipping-class-slug textarea,table.wc-shipping-classes .wc-shipping-zone-name input,table.wc-shipping-classes .wc-shipping-zone-name select,table.wc-shipping-classes .wc-shipping-zone-name textarea,table.wc-shipping-classes .wc-shipping-zone-region input,table.wc-shipping-classes .wc-shipping-zone-region select,table.wc-shipping-classes .wc-shipping-zone-region textarea,table.wc-shipping-zone-methods .wc-shipping-class-description input,table.wc-shipping-zone-methods .wc-shipping-class-description select,table.wc-shipping-zone-methods .wc-shipping-class-description textarea,table.wc-shipping-zone-methods .wc-shipping-class-name input,table.wc-shipping-zone-methods .wc-shipping-class-name select,table.wc-shipping-zone-methods .wc-shipping-class-name textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug input,table.wc-shipping-zone-methods .wc-shipping-class-slug select,table.wc-shipping-zone-methods .wc-shipping-class-slug textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name input,table.wc-shipping-zone-methods .wc-shipping-zone-name select,table.wc-shipping-zone-methods .wc-shipping-zone-name textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region input,table.wc-shipping-zone-methods .wc-shipping-zone-region select,table.wc-shipping-zone-methods .wc-shipping-zone-region textarea,table.wc-shipping-zones .wc-shipping-class-description input,table.wc-shipping-zones .wc-shipping-class-description select,table.wc-shipping-zones .wc-shipping-class-description textarea,table.wc-shipping-zones .wc-shipping-class-name input,table.wc-shipping-zones .wc-shipping-class-name select,table.wc-shipping-zones .wc-shipping-class-name textarea,table.wc-shipping-zones .wc-shipping-class-slug input,table.wc-shipping-zones .wc-shipping-class-slug select,table.wc-shipping-zones .wc-shipping-class-slug textarea,table.wc-shipping-zones .wc-shipping-zone-name input,table.wc-shipping-zones .wc-shipping-zone-name select,table.wc-shipping-zones .wc-shipping-zone-name textarea,table.wc-shipping-zones .wc-shipping-zone-region input,table.wc-shipping-zones .wc-shipping-zone-region select,table.wc-shipping-zones .wc-shipping-zone-region textarea{width:100%}table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-classes .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zone-methods .wc-shipping-zone-region a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-description a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-class-slug a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-name a.wc-shipping-zone-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-class-delete,table.wc-shipping-zones .wc-shipping-zone-region a.wc-shipping-zone-delete{color:red}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes-toggle,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes-toggle{float:right;margin:0;font-size:.9em;text-decoration:underline}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes{display:none}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes textarea,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes textarea{margin-top:1em}table.wc-shipping-classes .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-classes .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zone-methods .wc-shipping-zone-region .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-description .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-class-slug .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-name .wc-shipping-zone-postcodes .description,table.wc-shipping-zones .wc-shipping-zone-region .wc-shipping-zone-postcodes .description{font-size:.9em;color:#999}table.wc-shipping-classes .wc-shipping-class-count,table.wc-shipping-zone-methods .wc-shipping-class-count,table.wc-shipping-zones .wc-shipping-class-count{text-align:center}table.wc-shipping-classes td.wc-shipping-zone-methods,table.wc-shipping-zone-methods td.wc-shipping-zone-methods,table.wc-shipping-zones td.wc-shipping-zone-methods{color:#999}table.wc-shipping-classes td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .method_disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .method_disabled{text-decoration:line-through}table.wc-shipping-classes td.wc-shipping-zone-methods ul,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul,table.wc-shipping-zones td.wc-shipping-zone-methods ul{color:#999;position:relative;padding-right:32px}table.wc-shipping-classes td.wc-shipping-zone-methods ul li,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li,table.wc-shipping-zones td.wc-shipping-zone-methods ul li{display:inline;margin:0}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:before{content:", "}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-classes td.wc-shipping-zone-methods ul li:last-child:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:last-child:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child:before,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:last-child:before{content:""}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:last-child,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:last-child,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:last-child{display:block}table.wc-shipping-classes td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li:first-child,table.wc-shipping-zones td.wc-shipping-zone-methods ul li:first-child{margin:0!important}table.wc-shipping-classes td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zone-methods td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row,table.wc-shipping-zones td.wc-shipping-zone-methods ul li.wc-shipping-zone-methods-add-row{position:absolute;right:0;top:0}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method{display:block;width:24px;padding:24px 0 0;height:0;overflow:hidden;cursor:pointer}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method:before{speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;font-family:Dashicons;content:"\f502";color:#999;vertical-align:middle;line-height:24px;font-size:16px;margin:0}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled:before,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled:before{line-height:inherit}table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-classes .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled .status-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-disabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled .status-enabled{margin-top:1px;display:inline-block}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled{cursor:not-allowed}table.wc-shipping-classes td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zone-methods td.wc-shipping-zone-methods .add_shipping_method.disabled:before,table.wc-shipping-zones td.wc-shipping-zone-methods .add_shipping_method.disabled:before{color:#ccc}table.wc-shipping-classes .wc-shipping-zone-method-title,table.wc-shipping-zone-methods .wc-shipping-zone-method-title,table.wc-shipping-zones .wc-shipping-zone-method-title{width:33%}table.wc-shipping-classes .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zone-methods .wc-shipping-zone-method-title .wc-shipping-zone-method-delete,table.wc-shipping-zones .wc-shipping-zone-method-title .wc-shipping-zone-method-delete{color:red}table.wc-shipping-classes .wc-shipping-zone-method-enabled,table.wc-shipping-zone-methods .wc-shipping-zone-method-enabled,table.wc-shipping-zones .wc-shipping-zone-method-enabled{text-align:center}table.wc-shipping-classes tfoot input,table.wc-shipping-classes tfoot select,table.wc-shipping-zone-methods tfoot input,table.wc-shipping-zone-methods tfoot select,table.wc-shipping-zones tfoot input,table.wc-shipping-zones tfoot select{vertical-align:middle!important}table.wc-shipping-classes tfoot .button-secondary,table.wc-shipping-zone-methods tfoot .button-secondary,table.wc-shipping-zones tfoot .button-secondary{float:right}table.wc-shipping-classes .editing .wc-shipping-zone-edit,table.wc-shipping-classes .editing .wc-shipping-zone-view,table.wc-shipping-zone-methods .editing .wc-shipping-zone-edit,table.wc-shipping-zone-methods .editing .wc-shipping-zone-view,table.wc-shipping-zones .editing .wc-shipping-zone-edit,table.wc-shipping-zones .editing .wc-shipping-zone-view{display:none}.wc-modal-shipping-method-settings{background:#f8f8f8;padding:1em!important}.wc-modal-shipping-method-settings form .form-table{width:100%;background:#fff;margin:0 0 1.5em}.wc-modal-shipping-method-settings form .form-table tr th{width:30%;position:relative}.wc-modal-shipping-method-settings form .form-table tr th .woocommerce-help-tip{float:right;margin:-8px -.5em 0 0;vertical-align:middle;right:0;top:50%;position:absolute}.wc-modal-shipping-method-settings form .form-table tr td input,.wc-modal-shipping-method-settings form .form-table tr td select,.wc-modal-shipping-method-settings form .form-table tr td textarea{width:50%;min-width:250px}.wc-modal-shipping-method-settings form .form-table tr td input[type=checkbox]{width:auto;min-width:0}.wc-modal-shipping-method-settings form .form-table tr td,.wc-modal-shipping-method-settings form .form-table tr th{vertical-align:middle;margin:0;line-height:24px;padding:1em;border-bottom:1px solid #f8f8f8}.wc-modal-shipping-method-settings form .form-table:last-of-type{margin-bottom:0}.wc-backbone-modal .wc-shipping-zone-method-selector p{margin-top:0}.wc-backbone-modal .wc-shipping-zone-method-selector .wc-shipping-zone-method-description{margin:.75em 1px 0;line-height:1.5em;color:#999;font-style:italic}.wc-backbone-modal .wc-shipping-zone-method-selector select{width:100%;cursor:pointer}img.help_tip{margin:0 0 0 9px;vertical-align:middle}.postbox img.help_tip{margin-top:0}.postbox .woocommerce-help-tip{margin:0 0 0 9px}.status-disabled,.status-enabled,.status-manual{font-size:1.4em;display:block;text-indent:-9999px;position:relative;height:1em;width:1em}.status-disabled:before,.status-enabled:before,.status-manual:before{font-family:WooCommerce;line-height:1;margin:0;position:absolute;width:100%;height:100%;text-indent:0;top:0;font-variant:normal;-webkit-font-smoothing:antialiased;font-weight:400;text-align:center;left:0;speak:none;text-transform:none}.status-manual:before{content:"";color:#999}.status-enabled:before{content:"";color:#a46497}.status-disabled:before{content:"";color:#ccc}.woocommerce h2.woo-nav-tab-wrapper{margin-bottom:1em}.woocommerce nav.woo-nav-tab-wrapper{margin:1.5em 0 1em;border-bottom:1px solid #ccc}.woocommerce .subsubsub{margin:-8px 0 0}.woocommerce .wc-admin-breadcrumb{margin-left:.5em}.woocommerce .wc-admin-breadcrumb a{color:#a46497}.woocommerce #template div{margin:0}.woocommerce #template div p .button{float:right;margin-left:10px;margin-top:-4px}.woocommerce #template div .editor textarea{margin-bottom:8px}.woocommerce textarea[disabled=disabled]{background:#DFDFDF!important}.woocommerce table.form-table{margin:0;position:relative}.woocommerce table.form-table .forminp-radio ul{margin:0}.woocommerce table.form-table .forminp-radio ul li{line-height:1.4em}.woocommerce table.form-table textarea.input-text{height:100%;min-width:150px;display:block}.woocommerce table.form-table input.regular-input{width:25em}.woocommerce table.form-table textarea.wide-input{width:100%}.woocommerce table.form-table .woocommerce-help-tip,.woocommerce table.form-table img.help_tip{padding:0;margin:-4px 0 0 5px;vertical-align:middle;cursor:help;line-height:1}.woocommerce table.form-table span.help_tip{cursor:help;color:#2ea2cc}.woocommerce table.form-table th{position:relative;padding-right:24px}.woocommerce table.form-table .select2-container{display:block;max-width:350px;vertical-align:top;margin-bottom:3px}.woocommerce table.form-table table.widefat th{padding-right:inherit}.woocommerce table.form-table th .woocommerce-help-tip,.woocommerce table.form-table th img.help_tip{margin:0 -24px 0 0;float:right}.woocommerce table.form-table .wp-list-table .woocommerce-help-tip{float:none}.woocommerce table.form-table fieldset{margin-top:4px}.woocommerce table.form-table fieldset .woocommerce-help-tip,.woocommerce table.form-table fieldset img.help_tip{margin:-3px 0 0 5px}.woocommerce table.form-table fieldset p.description{margin-bottom:8px}.woocommerce table.form-table fieldset:first-child{margin-top:0}.woocommerce table.form-table .iris-picker{z-index:100;display:none;position:absolute;border:1px solid #ccc;border-radius:3px;box-shadow:0 1px 3px rgba(0,0,0,.2)}.woocommerce table.form-table .iris-picker .ui-slider{border:0!important;margin:0!important;width:auto!important;height:auto!important;background:none!important}.woocommerce table.form-table .iris-picker .ui-slider .ui-slider-handle{margin-bottom:0!important}.woocommerce table.form-table .colorpickpreview{padding:3px 3px 3px 20px;border:1px solid #ddd;border-right:0}.woocommerce table.form-table .colorpick{border-left:0}.woocommerce table.form-table .image_width_settings{vertical-align:middle}.woocommerce table.form-table .image_width_settings label{margin-left:10px}.woocommerce table.form-table .wc_emails_wrapper{padding:0 15px 10px 0}.woocommerce #tabs-wrap table a.remove{margin-left:4px}.woocommerce #tabs-wrap table p{margin:0 0 4px!important;overflow:hidden;zoom:1}.woocommerce #tabs-wrap table p a.add{float:left}#wp-excerpt-editor-container{background:#fff}#product_variation-parent #parent_id{width:100%}#postimagediv img{border:1px solid #d5d5d5;max-width:100%}#woocommerce-product-images .inside{margin:0;padding:0}#woocommerce-product-images .inside .add_product_images{padding:0 12px 12px}#woocommerce-product-images .inside #product_images_container{padding:0 0 0 9px}#woocommerce-product-images .inside #product_images_container ul{margin:0;padding:0}#woocommerce-product-images .inside #product_images_container ul:after,#woocommerce-product-images .inside #product_images_container ul:before{content:" ";display:table}#woocommerce-product-images .inside #product_images_container ul:after{clear:both}#woocommerce-product-images .inside #product_images_container ul li.add,#woocommerce-product-images .inside #product_images_container ul li.image,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{width:80px;float:left;cursor:move;border:1px solid #d5d5d5;margin:9px 9px 0 0;background:#f7f7f7;border-radius:2px;position:relative;box-sizing:border-box}#woocommerce-product-images .inside #product_images_container ul li.add img,#woocommerce-product-images .inside #product_images_container ul li.image img,#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder img{width:100%;height:auto;display:block}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder{border:3px dashed #ddd;position:relative}#woocommerce-product-images .inside #product_images_container ul li.wc-metabox-sortable-placeholder:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";font-size:2.618em;line-height:72px;color:#ddd}#woocommerce-product-images .inside #product_images_container ul ul.actions{position:absolute;top:-8px;right:-8px;padding:2px;display:none}#woocommerce-product-images .inside #product_images_container ul ul.actions li{float:right;margin:0 0 0 2px}#woocommerce-product-images .inside #product_images_container ul ul.actions li a{width:1em;margin:0;height:0;display:block;overflow:hidden}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.tips{cursor:pointer}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.4em}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}#woocommerce-product-images .inside #product_images_container ul ul.actions li a.delete:hover:before{color:#a00}#woocommerce-product-images .inside #product_images_container ul li:hover ul.actions{display:block}#woocommerce-product-data .hndle{padding:10px}#woocommerce-product-data .hndle span{display:block;vertical-align:middle;line-height:24px}#woocommerce-product-data .hndle span span{display:inline;line-height:inherit;vertical-align:baseline}#woocommerce-product-data .hndle label{padding-right:1em;font-size:12px;vertical-align:baseline}#woocommerce-product-data .hndle label:first-child{margin-right:1em;border-right:1px solid #dfdfdf}#woocommerce-product-data .hndle input,#woocommerce-product-data .hndle select{margin:-3px 0 0 .5em;vertical-align:middle}#woocommerce-product-data>.handlediv{margin-top:4px}#woocommerce-product-data .wrap{margin:0}#woocommerce-coupon-description{padding:3px 8px;font-size:1.7em;line-height:1.42em;height:auto;width:100%;outline:0;margin:10px 0;display:block}#woocommerce-coupon-description::-webkit-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description::-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-ms-input-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-description:-moz-placeholder{line-height:1.42em;color:#bbb}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap{background:#fff}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{float:left;width:80%}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios,#woocommerce-product-data .woocommerce_options_panel .wc-radios{display:block;float:left;margin:0}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li,#woocommerce-product-data .woocommerce_options_panel .wc-radios li{display:block;padding:0 0 10px}#woocommerce-coupon-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-coupon-data .woocommerce_options_panel .wc-radios li input,#woocommerce-product-data .wc-metaboxes-wrapper .wc-radios li input,#woocommerce-product-data .woocommerce_options_panel .wc-radios li input{width:auto}#woocommerce-coupon-data .panel-wrap,#woocommerce-product-data .panel-wrap,.woocommerce .panel-wrap{overflow:hidden}#woocommerce-coupon-data ul.wc-tabs,#woocommerce-product-data ul.wc-tabs,.woocommerce ul.wc-tabs{margin:0;width:20%;float:left;line-height:1em;padding:0 0 10px;position:relative;background-color:#fafafa;border-right:1px solid #eee;box-sizing:border-box}#woocommerce-coupon-data ul.wc-tabs:after,#woocommerce-product-data ul.wc-tabs:after,.woocommerce ul.wc-tabs:after{content:"";display:block;width:100%;height:9999em;position:absolute;bottom:-9999em;left:0;background-color:#fafafa;border-right:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li,#woocommerce-product-data ul.wc-tabs li,.woocommerce ul.wc-tabs li{margin:0;padding:0;display:block;position:relative}#woocommerce-coupon-data ul.wc-tabs li a,#woocommerce-product-data ul.wc-tabs li a,.woocommerce ul.wc-tabs li a{margin:0;padding:10px;display:block;box-shadow:none;text-decoration:none;line-height:20px!important;border-bottom:1px solid #eee}#woocommerce-coupon-data ul.wc-tabs li a:before,#woocommerce-product-data ul.wc-tabs li a:before,.woocommerce ul.wc-tabs li a:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}#woocommerce-coupon-data ul.wc-tabs li.general_options a:before,#woocommerce-product-data ul.wc-tabs li.general_options a:before,.woocommerce ul.wc-tabs li.general_options a:before{content:"\f107"}#woocommerce-coupon-data ul.wc-tabs li.inventory_options a:before,#woocommerce-product-data ul.wc-tabs li.inventory_options a:before,.woocommerce ul.wc-tabs li.inventory_options a:before{content:"\f481"}#woocommerce-coupon-data ul.wc-tabs li.shipping_options a:before,#woocommerce-product-data ul.wc-tabs li.shipping_options a:before,.woocommerce ul.wc-tabs li.shipping_options a:before{font-family:WooCommerce;content:"\e01a"}#woocommerce-coupon-data ul.wc-tabs li.linked_product_options a:before,#woocommerce-product-data ul.wc-tabs li.linked_product_options a:before,.woocommerce ul.wc-tabs li.linked_product_options a:before{content:"\f103"}#woocommerce-coupon-data ul.wc-tabs li.attribute_options a:before,#woocommerce-product-data ul.wc-tabs li.attribute_options a:before,.woocommerce ul.wc-tabs li.attribute_options a:before{content:"\f175"}#woocommerce-coupon-data ul.wc-tabs li.advanced_options a:before,#woocommerce-product-data ul.wc-tabs li.advanced_options a:before,.woocommerce ul.wc-tabs li.advanced_options a:before{font-family:Dashicons;content:"\f111"}#woocommerce-coupon-data ul.wc-tabs li.variations_options a:before,#woocommerce-product-data ul.wc-tabs li.variations_options a:before,.woocommerce ul.wc-tabs li.variations_options a:before{content:"\f509"}#woocommerce-coupon-data ul.wc-tabs li.usage_restriction_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_restriction_options a:before,.woocommerce ul.wc-tabs li.usage_restriction_options a:before{font-family:WooCommerce;content:"\e602"}#woocommerce-coupon-data ul.wc-tabs li.usage_limit_options a:before,#woocommerce-product-data ul.wc-tabs li.usage_limit_options a:before,.woocommerce ul.wc-tabs li.usage_limit_options a:before{font-family:WooCommerce;content:"\e601"}#woocommerce-coupon-data ul.wc-tabs li.general_coupon_data a:before,#woocommerce-product-data ul.wc-tabs li.general_coupon_data a:before,.woocommerce ul.wc-tabs li.general_coupon_data a:before{font-family:WooCommerce;content:"\e600"}#woocommerce-coupon-data ul.wc-tabs li.active a,#woocommerce-product-data ul.wc-tabs li.active a,.woocommerce ul.wc-tabs li.active a{color:#555;position:relative;background-color:#eee}.woocommerce_page_wc-settings .shippingrows th.check-column{padding-top:20px}.woocommerce_page_wc-settings .shippingrows tfoot th{padding-left:10px}.woocommerce_page_wc-settings .shippingrows .add.button:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin-right:.618em;content:"";text-decoration:none}.woocommerce_page_wc-settings h3.wc-settings-sub-title{font-size:1.2em}#woocommerce-coupon-data .inside,#woocommerce-order-data .inside,#woocommerce-order-downloads .inside,#woocommerce-product-data .inside,#woocommerce-product-type-options .inside{margin:0;padding:0}.panel,.woocommerce_options_panel{padding:9px;color:#555}.panel .form-field .woocommerce-help-tip,.woocommerce_options_panel .form-field .woocommerce-help-tip{font-size:1.4em}.panel,.woocommerce_page_settings .woocommerce_options_panel{padding:0}#woocommerce-product-specs .inside,#woocommerce-product-type-options .panel{margin:0;padding:9px}#woocommerce-product-type-options .panel p,.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p{margin:0 0 9px;font-size:12px;padding:5px 9px;line-height:24px}#woocommerce-product-type-options .panel p:after,.woocommerce_options_panel fieldset.form-field:after,.woocommerce_options_panel p:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce_options_panel .checkbox,.woocommerce_variable_attributes .checkbox{width:auto;margin:3px 0;vertical-align:middle}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{width:100%;padding:0!important}.woocommerce_options_panel .downloadable_files table th,.woocommerce_variations .downloadable_files table th{padding:7px 0 7px 7px!important}.woocommerce_options_panel .downloadable_files table th.sort,.woocommerce_variations .downloadable_files table th.sort{width:17px;padding:7px!important}.woocommerce_options_panel .downloadable_files table th .woocommerce-help-tip,.woocommerce_variations .downloadable_files table th .woocommerce-help-tip{font-size:1.1em;margin-left:0}.woocommerce_options_panel .downloadable_files table td,.woocommerce_variations .downloadable_files table td{vertical-align:middle!important;padding:4px 0 4px 7px!important;position:relative}.woocommerce_options_panel .downloadable_files table td:last-child,.woocommerce_variations .downloadable_files table td:last-child{padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td input.input_text,.woocommerce_variations .downloadable_files table td input.input_text{width:100%;float:none;min-width:0;margin:1px 0}.woocommerce_options_panel .downloadable_files table td .upload_file_button,.woocommerce_variations .downloadable_files table td .upload_file_button{width:auto;float:right;cursor:pointer}.woocommerce_options_panel .downloadable_files table td .delete,.woocommerce_variations .downloadable_files table td .delete{display:block;text-indent:-9999px;position:relative;height:1em;width:1em;font-size:1.2em}.woocommerce_options_panel .downloadable_files table td .delete:before,.woocommerce_variations .downloadable_files table td .delete:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;content:"";color:#999}.woocommerce_options_panel .downloadable_files table td .delete:hover:before,.woocommerce_variations .downloadable_files table td .delete:hover:before{color:#a00}.woocommerce_options_panel .downloadable_files table td.sort,.woocommerce_variations .downloadable_files table td.sort{width:17px;cursor:move;font-size:15px;text-align:center;background:#f9f9f9;padding-right:7px!important}.woocommerce_options_panel .downloadable_files table td.sort:before,.woocommerce_variations .downloadable_files table td.sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:1;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_options_panel .downloadable_files table td.sort:hover:before,.woocommerce_variations .downloadable_files table td.sort:hover:before{color:#333}.woocommerce_variation h3 .sort{width:17px;height:26px;cursor:move;float:right;font-size:15px;font-weight:400;margin-right:.5em;visibility:hidden;text-align:center;vertical-align:middle}.woocommerce_variation h3 .sort:before{content:"\f333";font-family:Dashicons;text-align:center;line-height:28px;color:#999;display:block;width:17px;float:left;height:100%}.woocommerce_variation h3 .sort:hover:before{color:#777}.woocommerce_variation h3:hover .sort,.woocommerce_variation.ui-sortable-helper .sort{visibility:visible}.woocommerce_options_panel{min-height:175px;box-sizing:border-box}.woocommerce_options_panel .downloadable_files{padding:0 9px 0 162px;position:relative;margin:9px 0}.woocommerce_options_panel .downloadable_files label{position:absolute;left:0;margin:0 0 0 12px;line-height:24px}.woocommerce_options_panel p{margin:9px 0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px 5px 162px!important}.woocommerce_options_panel .sale_price_dates_fields .short:first-of-type{margin-bottom:1em}.woocommerce_options_panel .sale_price_dates_fields .short:nth-of-type(2){clear:left}.woocommerce_options_panel label,.woocommerce_options_panel legend{float:left;width:150px;padding:0;margin:0 0 0 -150px}.woocommerce_options_panel label .req,.woocommerce_options_panel legend .req{font-weight:700;font-style:normal;color:#a00}.woocommerce_options_panel .description{padding:0;margin:0 0 0 7px;clear:none;display:inline}.woocommerce_options_panel .description-block{margin-left:0;display:block}.woocommerce_options_panel input,.woocommerce_options_panel select,.woocommerce_options_panel textarea{margin:0}.woocommerce_options_panel textarea{height:3.5em;line-height:1.5em;vertical-align:top}.woocommerce_options_panel input[type=text],.woocommerce_options_panel input[type=number],.woocommerce_options_panel input[type=email],.woocommerce_options_panel input[type=password]{width:50%;float:left}.woocommerce_options_panel input.button{width:auto;margin-left:8px}.woocommerce_options_panel select{float:left}.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:50%}.woocommerce_options_panel .sized{width:auto!important;margin-right:6px}.woocommerce_options_panel .options_group{border-top:1px solid #fff;border-bottom:1px solid #eee}.woocommerce_options_panel .options_group:first-child{border-top:0}.woocommerce_options_panel .options_group:last-child{border-bottom:0}.woocommerce_options_panel .options_group fieldset{margin:9px 0;font-size:12px;padding:5px 9px;line-height:24px}.woocommerce_options_panel .options_group fieldset label{width:auto;float:none}.woocommerce_options_panel .options_group fieldset ul{float:left;width:50%;margin:0;padding:0}.woocommerce_options_panel .options_group fieldset ul li{margin:0;width:auto}.woocommerce_options_panel .options_group fieldset ul li input{width:auto;float:none;margin-right:4px}.woocommerce_options_panel .options_group fieldset ul.wc-radios label{margin-left:0}.woocommerce_options_panel .dimensions_field .wrap{display:block;width:50%}.woocommerce_options_panel .dimensions_field .wrap input{width:30.75%;margin-right:3.8%}.woocommerce_options_panel .dimensions_field .wrap .last{margin-right:0}.woocommerce_options_panel.padded{padding:1em}#woocommerce-product-data input.dp-applied,.woocommerce_options_panel .select2-container{float:left}#grouped_product_options,#simple_product_options,#virtual_product_options{padding:12px;font-style:italic;color:#666}.wc-metaboxes-wrapper .toolbar{margin:0!important;border-top:1px solid #fff;border-bottom:1px solid #eee;padding:9px 12px!important}.wc-metaboxes-wrapper .toolbar:first-child{border-top:0}.wc-metaboxes-wrapper .toolbar:last-child{border-bottom:0}.wc-metaboxes-wrapper .toolbar .add_variation{float:right;margin-left:5px}.wc-metaboxes-wrapper .toolbar .cancel-variation-changes,.wc-metaboxes-wrapper .toolbar .save-variation-changes{float:left;margin-right:5px}.wc-metaboxes-wrapper p.toolbar{overflow:hidden;zoom:1}.wc-metaboxes-wrapper .expand-close{margin-right:2px;color:#777;font-size:12px;font-style:italic}.wc-metaboxes-wrapper .expand-close a{background:0 0;padding:0;font-size:12px;text-decoration:none}.wc-metaboxes-wrapper#product_attributes .expand-close{float:right;line-height:28px}.wc-metaboxes-wrapper .fr,.wc-metaboxes-wrapper button.add_variable_attribute{float:right;margin:0 0 0 6px}.wc-metaboxes-wrapper .wc-metaboxes{border-bottom:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox-sortable-placeholder{border-color:#bbb;background-color:#f5f5f5;margin-bottom:9px;border-width:1px;border-style:dashed}.wc-metaboxes-wrapper .wc-metabox{background:#fff;border-bottom:1px solid #eee;margin:0!important}.wc-metaboxes-wrapper .wc-metabox select{font-weight:400}.wc-metaboxes-wrapper .wc-metabox:last-of-type{border-bottom:0}.wc-metaboxes-wrapper .wc-metabox .handlediv{width:27px}.wc-metaboxes-wrapper .wc-metabox .handlediv:before{content:"\f142"!important;cursor:pointer;display:inline-block;font:400 20px/1 Dashicons;line-height:.5!important;padding:8px 10px;position:relative;right:12px;top:0}.wc-metaboxes-wrapper .wc-metabox.closed{border-radius:3px}.wc-metaboxes-wrapper .wc-metabox.closed .handlediv:before{content:"\f140"!important}.wc-metaboxes-wrapper .wc-metabox.closed h3{border:0}.wc-metaboxes-wrapper .wc-metabox h3{margin:0!important;padding:.75em .75em .75em 1em!important;font-size:1em!important;overflow:hidden;zoom:1;cursor:move}.wc-metaboxes-wrapper .wc-metabox h3 a.delete,.wc-metaboxes-wrapper .wc-metabox h3 button{float:right}.wc-metaboxes-wrapper .wc-metabox h3 a.delete{color:red;font-weight:400;line-height:26px;text-decoration:none;position:relative;visibility:hidden}.wc-metaboxes-wrapper .wc-metabox h3 strong{line-height:26px;font-weight:700}.wc-metaboxes-wrapper .wc-metabox h3 select{font-family:sans-serif;max-width:20%;margin:.25em .25em .25em 0}.wc-metaboxes-wrapper .wc-metabox h3 .handlediv{background-position:6px 5px!important;visibility:hidden;height:26px}.wc-metaboxes-wrapper .wc-metabox h3.fixed{cursor:pointer!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3{cursor:pointer;padding:.5em .75em .5em 1em!important}.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .handlediv,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 .sort,.wc-metaboxes-wrapper .wc-metabox.woocommerce_variation h3 a.delete{margin-top:.25em}.wc-metaboxes-wrapper .wc-metabox h3:hover .handlediv,.wc-metaboxes-wrapper .wc-metabox h3:hover a.delete,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper .handlediv,.wc-metaboxes-wrapper .wc-metabox.ui-sortable-helper a.delete{visibility:visible}.wc-metaboxes-wrapper .wc-metabox table{width:100%;position:relative;background-color:#fdfdfd;padding:1em;border-top:1px solid #eee}.wc-metaboxes-wrapper .wc-metabox table td{text-align:left;padding:0 6px 1em 0;vertical-align:top;border:0}.wc-metaboxes-wrapper .wc-metabox table td label{text-align:left;display:block;line-height:21px}.wc-metaboxes-wrapper .wc-metabox table td input{float:left;min-width:200px}.wc-metaboxes-wrapper .wc-metabox table td input,.wc-metaboxes-wrapper .wc-metabox table td textarea{width:100%;margin:0;display:block;font-size:14px;padding:4px;color:#555}.wc-metaboxes-wrapper .wc-metabox table td .select2-container,.wc-metaboxes-wrapper .wc-metabox table td select{width:100%!important}.wc-metaboxes-wrapper .wc-metabox table td input.short{width:200px}.wc-metaboxes-wrapper .wc-metabox table td input.checkbox{width:16px;min-width:inherit;vertical-align:text-bottom;display:inline-block;float:none}.wc-metaboxes-wrapper .wc-metabox table td.attribute_name{width:200px}.wc-metaboxes-wrapper .wc-metabox table .minus,.wc-metaboxes-wrapper .wc-metabox table .plus{margin-top:6px}.wc-metaboxes-wrapper .wc-metabox table .fl{float:left}.wc-metaboxes-wrapper .wc-metabox table .fr{float:right}.variations-pagenav{float:right;line-height:24px}.variations-pagenav .displaying-num{color:#777;font-size:12px;font-style:italic}.variations-pagenav a{padding:0 10px 3px;background:rgba(0,0,0,.05);font-size:16px;font-weight:400;text-decoration:none}.variations-pagenav a.disabled,.variations-pagenav a.disabled:active,.variations-pagenav a.disabled:focus,.variations-pagenav a.disabled:hover{color:#A0A5AA;background:rgba(0,0,0,.05)}.variations-defaults{float:left}.variations-defaults select{margin:.25em .25em .25em 0}.woocommerce_variable_attributes{background-color:#fdfdfd;border-top:1px solid #eee}.woocommerce_variable_attributes .data{padding:1em 2em}.woocommerce_variable_attributes .data:after,.woocommerce_variable_attributes .data:before{content:" ";display:table}.woocommerce_variable_attributes .data:after{clear:both}.woocommerce_variable_attributes .upload_image_button{display:block;width:48px;height:48px;float:left;margin-right:20px;position:relative;cursor:pointer}.woocommerce_variable_attributes .upload_image_button img{width:100%;height:auto;display:none}.woocommerce_variable_attributes .upload_image_button:before{content:"\f128";font-family:Dashicons;position:absolute;top:0;left:0;right:0;bottom:0;text-align:center;line-height:48px;font-size:48px;font-weight:400;-webkit-font-smoothing:antialiased}.woocommerce_variable_attributes .upload_image_button.remove img{display:block}.woocommerce_variable_attributes .upload_image_button.remove:before{content:"\f335";display:none}.woocommerce_variable_attributes .upload_image_button.remove:hover:before{display:block}.woocommerce_variable_attributes .options{border:1px solid #eee;border-width:1px 0;padding:.25em 0}.woocommerce_variable_attributes .options label{display:inline-block;padding:4px 1em 2px 0}.woocommerce_variable_attributes .options input[type=checkbox]{margin-top:5px;margin-right:3px}.form-row label{display:block}.form-row input[type=number],.form-row input[type=text],.form-row select{width:100%}.form-row.dimensions_field input{width:25%;float:left;margin-right:1%}.form-row.dimensions_field input:last-of-type{margin-right:0}.form-row-first,.form-row-last{width:48%;float:right}.form-row-first{clear:both;float:left}.form-row-full{clear:both}.tips{cursor:help;text-decoration:none}img.tips{padding:5px 0 0}#tiptip_holder{display:none;position:absolute;top:0;left:0;z-index:9999999}#tiptip_holder.tip_top{padding-bottom:5px}#tiptip_holder.tip_top #tiptip_arrow_inner{margin-top:-7px;margin-left:-6px;border-top-color:#333}#tiptip_holder.tip_bottom{padding-top:5px}#tiptip_holder.tip_bottom #tiptip_arrow_inner{margin-top:-5px;margin-left:-6px;border-bottom-color:#333}#tiptip_holder.tip_right{padding-left:5px}#tiptip_holder.tip_right #tiptip_arrow_inner{margin-top:-6px;margin-left:-5px;border-right-color:#333}#tiptip_holder.tip_left{padding-right:5px}#tiptip_holder.tip_left #tiptip_arrow_inner{margin-top:-6px;margin-left:-7px;border-left-color:#333}#tiptip_content,.chart-tooltip,.wc_error_tip{color:#fff;font-size:.8em;max-width:150px;background:#333;text-align:center;border-radius:3px;padding:.618em 1em;box-shadow:0 1px 3px rgba(0,0,0,.2)}#tiptip_content code,.chart-tooltip code,.wc_error_tip code{padding:1px;background:#888}#tiptip_arrow,#tiptip_arrow_inner{position:absolute;border-color:transparent;border-style:solid;border-width:6px;height:0;width:0}.wc_error_tip{max-width:20em;line-height:1.8em;position:absolute;white-space:normal;background:#d82223;margin:1.5em 1px 0 -1em;z-index:9999999}.wc_error_tip:after{content:"";display:block;border:8px solid #d82223;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-3px;left:50%;margin:-1em 0 0 -3px}img.ui-datepicker-trigger{vertical-align:middle;margin-top:-1px;cursor:pointer}.wc-metabox-content img.ui-datepicker-trigger,.woocommerce_options_panel img.ui-datepicker-trigger{float:left;margin-right:8px;margin-top:4px;margin-left:4px}#ui-datepicker-div{display:none}.woocommerce-reports-wide.woocommerce-reports-wrap,.woocommerce-reports-wrap.woocommerce-reports-wrap{margin-left:300px;padding-top:18px}.woocommerce-reports-wide.halved,.woocommerce-reports-wrap.halved{margin:0;overflow:hidden;zoom:1}.woocommerce-reports-wide .widefat td,.woocommerce-reports-wrap .widefat td{vertical-align:top;padding:7px}.woocommerce-reports-wide .widefat td .description,.woocommerce-reports-wrap .widefat td .description{margin:4px 0 0}.woocommerce-reports-wide .postbox:after,.woocommerce-reports-wrap .postbox:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox h3,.woocommerce-reports-wrap .postbox h3{cursor:default!important}.woocommerce-reports-wide .postbox .inside,.woocommerce-reports-wrap .postbox .inside{padding:10px;margin:0!important}.woocommerce-reports-wide .postbox div.stats_range,.woocommerce-reports-wide .postbox h3.stats_range,.woocommerce-reports-wrap .postbox div.stats_range,.woocommerce-reports-wrap .postbox h3.stats_range{border-bottom-color:#dfdfdf;margin:0;padding:0!important}.woocommerce-reports-wide .postbox div.stats_range .export_csv,.woocommerce-reports-wide .postbox h3.stats_range .export_csv,.woocommerce-reports-wrap .postbox div.stats_range .export_csv,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv{float:right;line-height:26px;border-left:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range .export_csv:before,.woocommerce-reports-wide .postbox h3.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox div.stats_range .export_csv:before,.woocommerce-reports-wrap .postbox h3.stats_range .export_csv:before{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;content:"";text-decoration:none;margin-right:4px}.woocommerce-reports-wide .postbox div.stats_range ul,.woocommerce-reports-wide .postbox h3.stats_range ul,.woocommerce-reports-wrap .postbox div.stats_range ul,.woocommerce-reports-wrap .postbox h3.stats_range ul{list-style:none;margin:0;padding:0;zoom:1;background:#f5f5f5;border-bottom:1px solid #ccc}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox div.stats_range ul:before,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:before,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:before,.woocommerce-reports-wrap .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:before{content:" ";display:table}.woocommerce-reports-wide .postbox div.stats_range ul:after,.woocommerce-reports-wide .postbox h3.stats_range ul:after,.woocommerce-reports-wrap .postbox div.stats_range ul:after,.woocommerce-reports-wrap .postbox h3.stats_range ul:after{clear:both}.woocommerce-reports-wide .postbox div.stats_range ul li,.woocommerce-reports-wide .postbox h3.stats_range ul li,.woocommerce-reports-wrap .postbox div.stats_range ul li,.woocommerce-reports-wrap .postbox h3.stats_range ul li{float:left;margin:0;padding:0;line-height:26px;font-weight:700;font-size:14px}.woocommerce-reports-wide .postbox div.stats_range ul li a,.woocommerce-reports-wide .postbox h3.stats_range ul li a,.woocommerce-reports-wrap .postbox div.stats_range ul li a,.woocommerce-reports-wrap .postbox h3.stats_range ul li a{border-right:1px solid #dfdfdf;padding:10px;display:block;text-decoration:none}.woocommerce-reports-wide .postbox div.stats_range ul li.active,.woocommerce-reports-wide .postbox h3.stats_range ul li.active,.woocommerce-reports-wrap .postbox div.stats_range ul li.active,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active{background:#fff;-webkit-box-shadow:0 4px 0 0 #fff;box-shadow:0 4px 0 0 #fff}.woocommerce-reports-wide .postbox div.stats_range ul li.active a,.woocommerce-reports-wide .postbox h3.stats_range ul li.active a,.woocommerce-reports-wrap .postbox div.stats_range ul li.active a,.woocommerce-reports-wrap .postbox h3.stats_range ul li.active a{color:#777}.woocommerce-reports-wide .postbox div.stats_range ul li.custom,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom{padding:9px 10px;vertical-align:middle}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form{display:inline;margin:0}.woocommerce-reports-wide .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wide .postbox h3.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox div.stats_range ul li.custom form input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom div input.range_datepicker,.woocommerce-reports-wrap .postbox h3.stats_range ul li.custom form input.range_datepicker{padding:0;margin:0 10px 0 0;background:0 0;border:0;color:#777;text-align:center;-webkit-box-shadow:none;box-shadow:none}.woocommerce-reports-wide .postbox .chart-with-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar{padding:12px 12px 12px 249px;margin:0!important}.woocommerce-reports-wide .postbox .chart-with-sidebar .chart-sidebar,.woocommerce-reports-wrap .postbox .chart-with-sidebar .chart-sidebar{width:225px;margin-left:-237px;float:left}.woocommerce-reports-wide .postbox .chart-widgets,.woocommerce-reports-wrap .postbox .chart-widgets{margin:0;padding:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget{margin:0 0 1em;background:#fafafa;border:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget:after{content:".";display:block;height:0;clear:both;visibility:hidden}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4{background:#fff;border:1px solid #dfdfdf;border-left-width:0;border-right-width:0;padding:10px;margin:0;color:#2ea2cc;border-top-width:0;background-image:-webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9));background-image:-webkit-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-moz-linear-gradient(bottom,#ececec,#f9f9f9);background-image:-o-linear-gradient(bottom,#ececec,#f9f9f9);background-image:linear-gradient(to top,#ececec,#f9f9f9)}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr.active td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.count,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr.active td{background:#f5f5f5}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget h4.section_title:hover,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget h4.section_title:hover{color:#a00}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title{cursor:pointer}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span{display:block}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title span:after{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin-left:.618em;content:"";text-decoration:none;float:right;font-size:.9em;line-height:1.618}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open{color:#333}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section_title.open span:after,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section_title.open span:after{display:none}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section{border-bottom:1px solid #dfdfdf}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section .select2-container,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section .select2-container{width:100%!important}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .section:last-of-type,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .section:last-of-type{border-radius:0 0 3px 3px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td{padding:7px 10px;vertical-align:top;border-top:1px solid #e5e5e5;line-height:1.4em}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.sparkline,form.report_filters div,form.report_filters input,form.report_filters label,form.report_filters p{vertical-align:middle}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table tr:first-child td,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table tr:first-child td{border-top:0}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name{max-width:175px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table td.name a,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table td.name a{word-wrap:break-word}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget table .wc_sparkline,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget table .wc_sparkline{width:32px;height:1em;display:block;float:right}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p{margin:0;padding:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget p .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget form .submit,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget p .submit{margin-top:10px}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget #product_ids,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget #product_ids{width:100%}.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wide .postbox .chart-widgets li.chart-widget .select_none,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_all,.woocommerce-reports-wrap .postbox .chart-widgets li.chart-widget .select_none{float:right;color:#999;margin-left:4px;margin-top:10px}.woocommerce-reports-wide .postbox .chart-legend,.woocommerce-reports-wrap .postbox .chart-legend{list-style:none;margin:0 0 1em;padding:0;border:1px solid #dfdfdf;border-right-width:0;border-bottom-width:0;background:#fff}.woocommerce-reports-wide .postbox .chart-legend li,.woocommerce-reports-wrap .postbox .chart-legend li{border-right:5px solid #aaa;color:#aaa;padding:1em;display:block;margin:0;-webkit-transition:all ease .5s;box-shadow:inset 0 -1px 0 0 #dfdfdf}.woocommerce-reports-wide .postbox .chart-legend li strong,.woocommerce-reports-wrap .postbox .chart-legend li strong{font-size:1.618em;line-height:1.2em;color:#464646;font-weight:400;display:block;font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif}.woocommerce-reports-wide .postbox .chart-legend li strong del,.woocommerce-reports-wrap .postbox .chart-legend li strong del{color:#e74c3c;font-weight:400}.woocommerce-reports-wide .postbox .chart-legend li:hover,.woocommerce-reports-wrap .postbox .chart-legend li:hover{box-shadow:inset 0 -1px 0 0 #dfdfdf,inset 300px 0 0 rgba(156,93,144,.1);border-right:5px solid #9c5d90!important;padding-left:1.5em;color:#9c5d90}.woocommerce-reports-wide .postbox .pie-chart-legend,.woocommerce-reports-wrap .postbox .pie-chart-legend{margin:12px 0 0;overflow:hidden}.woocommerce-reports-wide .postbox .pie-chart-legend li,.woocommerce-reports-wrap .postbox .pie-chart-legend li{float:left;margin:0;padding:6px 0 0;border-top:4px solid #999;text-align:center;box-sizing:border-box;width:50%}.woocommerce-reports-wide .postbox .stat,.woocommerce-reports-wrap .postbox .stat{font-size:1.5em!important;font-weight:700;text-align:center}.woocommerce-reports-wide .postbox .chart-placeholder,.woocommerce-reports-wrap .postbox .chart-placeholder{width:100%;height:650px;overflow:hidden;position:relative}.woocommerce-reports-wide .postbox .chart-prompt,.woocommerce-reports-wrap .postbox .chart-prompt{line-height:650px;margin:0;color:#999;font-size:1.2em;font-style:italic;text-align:center}.woocommerce-reports-wide .postbox .chart-container,.woocommerce-reports-wrap .postbox .chart-container{background:#fff;padding:12px;position:relative;border:1px solid #dfdfdf;border-radius:3px}.woocommerce-reports-wide .postbox .main .chart-legend,.woocommerce-reports-wrap .postbox .main .chart-legend{margin-top:12px}.woocommerce-reports-wide .postbox .main .chart-legend li,.woocommerce-reports-wrap .postbox .main .chart-legend li{border-right:0;margin:0 8px 0 0;float:left;border-top:4px solid #aaa}.woocommerce-reports-wide .woocommerce-reports-main,.woocommerce-reports-wrap .woocommerce-reports-main{float:left;min-width:100%}.woocommerce-reports-wide .woocommerce-reports-main table td,.woocommerce-reports-wrap .woocommerce-reports-main table td{padding:9px}.woocommerce-reports-wide .woocommerce-reports-sidebar,.woocommerce-reports-wrap .woocommerce-reports-sidebar{display:inline;width:281px;margin-left:-300px;clear:both;float:left}.woocommerce-reports-wide .woocommerce-reports-left,.woocommerce-reports-wrap .woocommerce-reports-left{width:49.5%;float:left}.woocommerce-reports-wide .woocommerce-reports-right,.woocommerce-reports-wrap .woocommerce-reports-right{width:49.5%;float:right}.woocommerce-reports-wide .column-wc_actions a.edit,.woocommerce-reports-wide .column-wc_actions a.view,.woocommerce-reports-wrap .column-wc_actions a.edit,.woocommerce-reports-wrap .column-wc_actions a.view{display:block;text-indent:-9999px;position:relative;padding:0!important;height:2em!important;width:2em}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{font-family:Dashicons;speak:none;font-weight:400;font-variant:normal;text-transform:none;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;line-height:1.85}.woocommerce-reports-wide .column-wc_actions a.edit:after,.woocommerce-reports-wrap .column-wc_actions a.edit:after{content:"\f464"}.woocommerce-reports-wide .column-wc_actions a.view:after,.woocommerce-reports-wrap .column-wc_actions a.view:after{content:"\f177"}.woocommerce-wide-reports-wrap{padding-bottom:11px}.woocommerce-wide-reports-wrap .widefat .export-data{float:right}.woocommerce-wide-reports-wrap .widefat td,.woocommerce-wide-reports-wrap .widefat th{vertical-align:middle;padding:7px}.chart-tooltip{position:absolute;display:none;line-height:1}table.bar_chart{width:100%}table.bar_chart thead th{text-align:left;color:#ccc;padding:6px 0}table.bar_chart tbody th{padding:6px 0;width:25%;text-align:left!important;font-weight:400!important;border-bottom:1px solid #fee}table.bar_chart tbody td{text-align:right;line-height:24px;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td span{color:#8a4b75;display:block}table.bar_chart tbody td span.alt{color:#47a03e;margin-top:6px}table.bar_chart tbody td.bars{position:relative;text-align:left;padding:6px 6px 6px 0;border-bottom:1px solid #fee}table.bar_chart tbody td.bars a,table.bar_chart tbody td.bars span{text-decoration:none;clear:both;background:#8a4b75;float:left;display:block;line-height:24px;height:24px;-moz-border-radius:3px;-webkit-border-radius:3px;-o-border-radius:3px;-khtml-border-radius:3px;border-radius:3px}.post-type-product .woocommerce-BlankState-message:before,.post-type-shop_coupon .woocommerce-BlankState-message:before,.post-type-shop_order .woocommerce-BlankState-message:before{font-family:WooCommerce;speak:none;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;margin:0;text-indent:0;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center}table.bar_chart tbody td.bars span.alt{clear:both;background:#47a03e}table.bar_chart tbody td.bars span.alt span{margin:0;color:#c5dec2!important;text-shadow:0 1px 0 #47a03e;background:0 0}.post-type-shop_order .woocommerce-BlankState-message:before{content:""}.post-type-shop_coupon .woocommerce-BlankState-message:before{content:""}.post-type-product .woocommerce-BlankState-message:before{content:""}.woocommerce-BlankState{text-align:center;padding:5em 0 0}.woocommerce-BlankState .woocommerce-BlankState-message{color:#aaa;margin:0 auto 1.5em;line-height:1.5em;font-size:1.2em;max-width:500px}.woocommerce-BlankState .woocommerce-BlankState-message:before{color:#ddd;text-shadow:0 -1px 1px rgba(0,0,0,.2),0 1px 0 rgba(255,255,255,.8);font-size:8em;display:block;position:relative!important;top:auto;left:auto;line-height:1em;margin:0 0 .1875em}.woocommerce-BlankState .woocommerce-BlankState-cta{font-size:1.2em;padding:.75em 1.5em;height:auto}@media only screen and (max-width:1280px){#order_data .order_data_column{width:48%}#order_data .order_data_column:first-child{width:100%}.woocommerce_options_panel .description{display:block;clear:both;margin-left:0}.woocommerce_options_panel .dimensions_field .wrap,.woocommerce_options_panel .short,.woocommerce_options_panel input[type=text].short,.woocommerce_options_panel input[type=number].short,.woocommerce_options_panel input[type=email].short,.woocommerce_options_panel input[type=password].short{width:80%}.woocommerce_options_panel .downloadable_files,.woocommerce_variations .downloadable_files{padding:0;clear:both}.woocommerce_options_panel .downloadable_files label,.woocommerce_variations .downloadable_files label{position:static}.woocommerce_options_panel .downloadable_files table,.woocommerce_variations .downloadable_files table{margin:0 12px 24px;width:94%}.woocommerce_options_panel .downloadable_files table .sort,.woocommerce_variations .downloadable_files table .sort{visibility:hidden}.woocommerce_options_panel .woocommerce_variable_attributes .downloadable_files table,.woocommerce_variations .woocommerce_variable_attributes .downloadable_files table{margin:0 0 1em;width:100%}}@media only screen and (max-width:900px){#woocommerce-coupon-data ul.coupon_data_tabs,#woocommerce-product-data .wc-tabs-back,#woocommerce-product-data ul.product_data_tabs{width:10%}#woocommerce-coupon-data .wc-metaboxes-wrapper,#woocommerce-coupon-data .woocommerce_options_panel,#woocommerce-product-data .wc-metaboxes-wrapper,#woocommerce-product-data .woocommerce_options_panel{width:90%}#woocommerce-coupon-data ul.coupon_data_tabs li a,#woocommerce-product-data ul.product_data_tabs li a{position:relative;text-indent:-999px;padding:10px}#woocommerce-coupon-data ul.coupon_data_tabs li a:before,#woocommerce-product-data ul.product_data_tabs li a:before{position:absolute;top:0;right:0;bottom:0;left:0;text-indent:0;text-align:center;line-height:40px;width:100%;height:40px}}@media only screen and (max-width:782px){#wp-excerpt-media-buttons a{font-size:16px;line-height:37px;height:39px;padding:0 20px 0 15px}#wp-excerpt-editor-tools{padding-top:20px;padding-right:15px;overflow:hidden;margin-bottom:-1px}.post-type-product .wp-list-table .is-expanded td:not(.hidden),.post-type-shop_order .wp-list-table .is-expanded td:not(.hidden){overflow:visible}#woocommerce-product-data .checkbox{width:25px}.variations-pagenav{float:none;text-align:center;font-size:18px}.variations-pagenav .displaying-num{font-size:16px}.variations-pagenav a{padding:8px 20px 11px;font-size:18px}.variations-pagenav select{padding:0 20px}.variations-defaults{float:none;text-align:center;margin-top:10px}.post-type-product .wp-list-table .column-thumb{display:none;text-align:left;padding-bottom:0}.post-type-product .wp-list-table .column-thumb:before{display:none!important}.post-type-product .wp-list-table .column-thumb img{max-width:32px}.post-type-product .wp-list-table .toggle-row{top:-28px}.post-type-shop_order .wp-list-table .column-order_status{display:none;text-align:left;padding-bottom:0}.post-type-shop_order .wp-list-table .column-order_status mark{margin:0}.post-type-shop_order .wp-list-table .column-order_status:before{display:none!important}.post-type-shop_order .wp-list-table .column-customer_message,.post-type-shop_order .wp-list-table .column-order_notes{text-align:inherit}.post-type-shop_order .wp-list-table .column-order_notes .note-on{font-size:1.3em;margin:0}.post-type-shop_order .wp-list-table .toggle-row{top:-15px}}@media only screen and (max-width:500px){.woocommerce_options_panel label,.woocommerce_options_panel legend{float:none;width:auto;display:block;margin:0}.woocommerce_options_panel fieldset.form-field,.woocommerce_options_panel p.form-field{padding:5px 20px!important}}.wc-backbone-modal *{box-sizing:border-box}.wc-backbone-modal .wc-backbone-modal-content{position:fixed;background:#fff;z-index:100000;left:50%;top:50%;transform:translate(-50%,-50%);width:500px}.wc-backbone-modal .wc-backbone-modal-content article{overflow:auto}.wc-backbone-modal.wc-backbone-modal-shipping-method-settings .wc-backbone-modal-content{width:75%;min-width:500px}.wc-backbone-modal-backdrop{position:fixed;top:0;left:0;right:0;bottom:0;min-height:360px;background:#000;opacity:.7;z-index:99900}.wc-backbone-modal-main{padding-bottom:55px}.wc-backbone-modal-main article,.wc-backbone-modal-main header{display:block;position:relative}.wc-backbone-modal-main .wc-backbone-modal-header{height:auto;background:#fcfcfc;padding:1em 1.5em;border-bottom:1px solid #ddd}.wc-backbone-modal-main .wc-backbone-modal-header h1{margin:0;font-size:18px;font-weight:700;line-height:1.5em}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link{cursor:pointer;color:#777;height:54px;width:54px;padding:0;position:absolute;top:0;right:0;text-align:center;border:0;border-left:1px solid #ddd;background-color:transparent;-webkit-transition:color .1s ease-in-out,background .1s ease-in-out;transition:color .1s ease-in-out,background .1s ease-in-out}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:before{font:400 22px/50px dashicons!important;color:#666;display:block;content:'\f335';font-weight:300}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus,.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:hover{background:#ddd;border-color:#ccc;color:#000}.wc-backbone-modal-main .wc-backbone-modal-header .modal-close-link:focus{outline:0}.wc-backbone-modal-main article{padding:1.5em}.wc-backbone-modal-main article p{margin:1.5em 0}.wc-backbone-modal-main article p:last-child,.wc-backbone-modal-main footer .inner .button{margin-bottom:0}.wc-backbone-modal-main article p:first-child{margin-top:0}.wc-backbone-modal-main article .pagination{padding:10px 0 0;text-align:center}.wc-backbone-modal-main footer{position:absolute;left:0;right:0;bottom:0;z-index:100;padding:1em 1.5em;background:#fcfcfc;border-top:1px solid #dfdfdf;box-shadow:0 -4px 4px -4px rgba(0,0,0,.1)}.wc-backbone-modal-main footer .inner{float:right;line-height:23px}.select2-drop{z-index:999999!important}.select2-container-multi .select2-choices .select2-search-field input{font-family:inherit;font-size:inherit;font-weight:inherit;padding:3px 5px}.select2-container{line-height:1.85em;font-size:14px} \ No newline at end of file diff --git a/assets/css/admin.scss b/assets/css/admin.scss index c1fe022b46c..e332f2f1c14 100644 --- a/assets/css/admin.scss +++ b/assets/css/admin.scss @@ -306,7 +306,12 @@ table.wc_status_table { #log-viewer-select { padding: 10px 0 8px; - line-height: 180%; + line-height: 28px; + h2 { + a { + vertical-align: middle; + } + } } #log-viewer { diff --git a/assets/js/accounting/accounting.min.js b/assets/js/accounting/accounting.min.js index 168a2796e54..3067cfb5e5e 100644 --- a/assets/js/accounting/accounting.min.js +++ b/assets/js/accounting/accounting.min.js @@ -8,4 +8,4 @@ * Full details and documentation: * http://openexchangerates.github.io/accounting.js/ */ -!function(a,b){function c(a){return!!(""===a||a&&a.charCodeAt&&a.substr)}function d(a){return l?l(a):"[object Array]"===m.call(a)}function e(a){return a&&"[object Object]"===m.call(a)}function f(a,b){var c;a=a||{},b=b||{};for(c in b)b.hasOwnProperty(c)&&null==a[c]&&(a[c]=b[c]);return a}function g(a,b,c){var d,e,f=[];if(!a)return f;if(k&&a.map===k)return a.map(b,c);for(d=0,e=a.length;e>d;d++)f[d]=b.call(c,a[d],d,a);return f}function h(a,b){return a=Math.round(Math.abs(a)),isNaN(a)?b:a}function i(a){var b=j.settings.currency.format;return"function"==typeof a&&(a=a()),c(a)&&a.match("%v")?{pos:a,neg:a.replace("-","").replace("%v","-%v"),zero:a}:a&&a.pos&&a.pos.match("%v")?a:c(b)?j.settings.currency.format={pos:b,neg:b.replace("%v","-%v"),zero:b}:b}var j={};j.version="0.4.1",j.settings={currency:{symbol:"$",format:"%s%v",decimal:".",thousand:",",precision:2,grouping:3},number:{precision:0,grouping:3,thousand:",",decimal:"."}};var k=Array.prototype.map,l=Array.isArray,m=Object.prototype.toString,n=j.unformat=j.parse=function(a,b){if(d(a))return g(a,function(a){return n(a,b)});if(a=a||0,"number"==typeof a)return a;b=b||j.settings.number.decimal;var c=new RegExp("[^0-9-"+b+"]",["g"]),e=parseFloat((""+a).replace(/\((.*)\)/,"-$1").replace(c,"").replace(b,"."));return isNaN(e)?0:e},o=j.toFixed=function(a,b){b=h(b,j.settings.number.precision);var c=Math.pow(10,b);return(Math.round(j.unformat(a)*c)/c).toFixed(b)},p=j.formatNumber=j.format=function(a,b,c,i){if(d(a))return g(a,function(a){return p(a,b,c,i)});a=n(a);var k=f(e(b)?b:{precision:b,thousand:c,decimal:i},j.settings.number),l=h(k.precision),m=0>a?"-":"",q=parseInt(o(Math.abs(a||0),l),10)+"",r=q.length>3?q.length%3:0;return m+(r?q.substr(0,r)+k.thousand:"")+q.substr(r).replace(/(\d{3})(?=\d)/g,"$1"+k.thousand)+(l?k.decimal+o(Math.abs(a),l).split(".")[1]:"")},q=j.formatMoney=function(a,b,c,k,l,m){if(d(a))return g(a,function(a){return q(a,b,c,k,l,m)});a=n(a);var o=f(e(b)?b:{symbol:b,precision:c,thousand:k,decimal:l,format:m},j.settings.currency),r=i(o.format),s=a>0?r.pos:0>a?r.neg:r.zero;return s.replace("%s",o.symbol).replace("%v",p(Math.abs(a),h(o.precision),o.thousand,o.decimal))};j.formatColumn=function(a,b,k,l,m,o){if(!a)return[];var q=f(e(b)?b:{symbol:b,precision:k,thousand:l,decimal:m,format:o},j.settings.currency),r=i(q.format),s=r.pos.indexOf("%s")0?r.pos:0>a?r.neg:r.zero,e=c.replace("%s",q.symbol).replace("%v",p(Math.abs(a),h(q.precision),q.thousand,q.decimal));return e.length>t&&(t=e.length),e});return g(u,function(a,b){return c(a)&&a.length3?q.length%3:0;return m+(r?q.substr(0,r)+k.thousand:"")+q.substr(r).replace(/(\d{3})(?=\d)/g,"$1"+k.thousand)+(l?k.decimal+o(Math.abs(a),l).split(".")[1]:"")},q=j.formatMoney=function(a,b,c,k,l,m){if(d(a))return g(a,function(a){return q(a,b,c,k,l,m)});a=n(a);var o=f(e(b)?b:{symbol:b,precision:c,thousand:k,decimal:l,format:m},j.settings.currency),r=i(o.format),s=a>0?r.pos:a<0?r.neg:r.zero;return s.replace("%s",o.symbol).replace("%v",p(Math.abs(a),h(o.precision),o.thousand,o.decimal))};j.formatColumn=function(a,b,k,l,m,o){if(!a)return[];var q=f(e(b)?b:{symbol:b,precision:k,thousand:l,decimal:m,format:o},j.settings.currency),r=i(q.format),s=r.pos.indexOf("%s")0?r.pos:a<0?r.neg:r.zero,e=c.replace("%s",q.symbol).replace("%v",p(Math.abs(a),h(q.precision),q.thousand,q.decimal));return e.length>t&&(t=e.length),e});return g(u,function(a,b){return c(a)&&a.length');else{var m=a(''),n=b.states[f];m.append(a('")),a.each(n,function(b){m.append(a('"))}),m.val(k),g.replaceWith(m),m.show().select2().hide().change()}a(document.body).trigger("contry-change.woocommerce",[f,a(this).closest("div")]),a(document.body).trigger("country-change.woocommerce",[f,a(this).closest("div")])}},change_state:function(){var b=a(this),c=b.val(),d=b.parents("div.edit_address").find(":input.js_field-country"),e=d.val();d.data("woocommerce.stickState-"+e,c)},init_tiptip:function(){a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200})},edit_address:function(b){b.preventDefault(),a(this).hide(),a(this).parent().find("a:not(.edit_address)").show(),a(this).closest(".order_data_column").find("div.address").hide(),a(this).closest(".order_data_column").find("div.edit_address").show()},change_customer_user:function(){a("#_billing_country").val()||(a("a.edit_address").click(),b.load_billing(!0),b.load_shipping(!0))},load_billing:function(b){if(!0===b||window.confirm(woocommerce_admin_meta_boxes.load_billing)){var c=a("#customer_user").val();if(!c)return window.alert(woocommerce_admin_meta_boxes.no_customer_selected),!1;var d={user_id:c,type_to_load:"billing",action:"woocommerce_get_customer_details",security:woocommerce_admin_meta_boxes.get_customer_details_nonce};a(this).closest("div.edit_address").block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:d,type:"POST",success:function(b){b&&a.each(b,function(b,c){a(":input#_"+b).val(c).change()}),a("div.edit_address").unblock()}})}return!1},load_shipping:function(b){if(!0===b||window.confirm(woocommerce_admin_meta_boxes.load_shipping)){var c=a("#customer_user").val();if(!c)return window.alert(woocommerce_admin_meta_boxes.no_customer_selected),!1;var d={user_id:c,type_to_load:"shipping",action:"woocommerce_get_customer_details",security:woocommerce_admin_meta_boxes.get_customer_details_nonce};a(this).closest("div.edit_address").block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:d,type:"POST",success:function(b){b&&a.each(b,function(b,c){a(":input#_"+b).val(c).change()}),a("div.edit_address").unblock()}})}return!1},copy_billing_to_shipping:function(){return window.confirm(woocommerce_admin_meta_boxes.copy_billing)&&a('.order_data_column :input[name^="_billing_"]').each(function(){var b=a(this).attr("name");b=b.replace("_billing_","_shipping_"),a(":input#"+b).val(a(this).val()).change()}),!1}},c={init:function(){this.stupidtable.init(),a("#woocommerce-order-items").on("click","button.add-line-item",this.add_line_item).on("click","button.refund-items",this.refund_items).on("click",".cancel-action",this.cancel).on("click","button.add-order-item",this.add_item).on("click","button.add-order-fee",this.add_fee).on("click","button.add-order-shipping",this.add_shipping).on("click","button.add-order-tax",this.add_tax).on("click","button.calculate-action",this.calculate_totals).on("click","button.save-action",this.save_line_items).on("click","a.delete-order-tax",this.delete_tax).on("click","button.calculate-tax-action",this.calculate_tax).on("click","a.edit-order-item",this.edit_item).on("click","a.delete-order-item",this.delete_item).on("click","tr.item, tr.fee, tr.shipping, tr.refund",this.select_row).on("click","tr.item :input, tr.fee :input, tr.shipping :input, tr.refund :input, tr.item a, tr.fee a, tr.shipping a, tr.refund a",this.select_row_child).on("click","button.bulk-delete-items",this.bulk_actions.do_delete).on("click","button.bulk-increase-stock",this.bulk_actions.do_increase_stock).on("click","button.bulk-decrease-stock",this.bulk_actions.do_reduce_stock).on("click",".delete_refund",this.refunds.delete_refund).on("click","button.do-api-refund, button.do-manual-refund",this.refunds.do_refund).on("change",".refund input.refund_line_total, .refund input.refund_line_tax",this.refunds.input_changed).on("change keyup",".wc-order-refund-items #refund_amount",this.refunds.amount_changed).on("change","input.refund_order_item_qty",this.refunds.refund_quantity_changed).on("change","input.quantity",this.quantity_changed).on("keyup change",".split-input :input",function(){var b=a(this).parent().prev().find(":input");b&&(""===b.val()||b.is(".match-total"))&&b.val(a(this).val()).addClass("match-total")}).on("keyup",".split-input :input",function(){a(this).removeClass("match-total")}).on("click","button.add_order_item_meta",this.item_meta.add).on("click","button.remove_order_item_meta",this.item_meta.remove),a(document.body).on("wc_backbone_modal_loaded",this.backbone.init).on("wc_backbone_modal_response",this.backbone.response)},block:function(){a("#woocommerce-order-items").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a("#woocommerce-order-items").unblock()},reload_items:function(){var d={order_id:woocommerce_admin_meta_boxes.post_id,action:"woocommerce_load_order_items",security:woocommerce_admin_meta_boxes.order_item_nonce};c.block(),a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:d,type:"POST",success:function(d){a("#woocommerce-order-items").find(".inside").empty(),a("#woocommerce-order-items").find(".inside").append(d),b.init_tiptip(),c.unblock(),c.stupidtable.init()}})},quantity_changed:function(){var b=a(this).closest("tr.item"),c=a(this).val(),d=a(this).attr("data-qty"),e=a("input.line_total",b),f=a("input.line_subtotal",b),g=accounting.unformat(e.attr("data-total"),woocommerce_admin.mon_decimal_point)/d;e.val(parseFloat(accounting.formatNumber(g*c,woocommerce_admin_meta_boxes.rounding_precision,"")).toString().replace(".",woocommerce_admin.mon_decimal_point));var h=accounting.unformat(f.attr("data-subtotal"),woocommerce_admin.mon_decimal_point)/d;f.val(parseFloat(accounting.formatNumber(h*c,woocommerce_admin_meta_boxes.rounding_precision,"")).toString().replace(".",woocommerce_admin.mon_decimal_point)),a("input.line_tax",b).each(function(){var e=a(this),f=e.data("tax_id"),g=accounting.unformat(e.attr("data-total_tax"),woocommerce_admin.mon_decimal_point)/d,h=a('input.line_subtotal_tax[data-tax_id="'+f+'"]',b),i=accounting.unformat(h.attr("data-subtotal_tax"),woocommerce_admin.mon_decimal_point)/d;g>0&&e.val(parseFloat(accounting.formatNumber(g*c,woocommerce_admin_meta_boxes.rounding_precision,"")).toString().replace(".",woocommerce_admin.mon_decimal_point)),i>0&&h.val(parseFloat(accounting.formatNumber(i*c,woocommerce_admin_meta_boxes.rounding_precision,"")).toString().replace(".",woocommerce_admin.mon_decimal_point))}),a(this).trigger("quantity_changed")},add_line_item:function(){return a("div.wc-order-add-item").slideDown(),a("div.wc-order-data-row-toggle").not("div.wc-order-add-item").slideUp(),!1},refund_items:function(){return a("div.wc-order-refund-items").slideDown(),a("div.wc-order-data-row-toggle").not("div.wc-order-refund-items").slideUp(),a("div.wc-order-totals-items").slideUp(),a("#woocommerce-order-items").find("div.refund").show(),a(".wc-order-edit-line-item .wc-order-edit-line-item-actions").hide(),!1},cancel:function(){return a("div.wc-order-data-row-toggle").not("div.wc-order-bulk-actions").slideUp(),a("div.wc-order-bulk-actions").slideDown(),a("div.wc-order-totals-items").slideDown(),a("#woocommerce-order-items").find("div.refund").hide(),a(".wc-order-edit-line-item .wc-order-edit-line-item-actions").show(),"true"===a(this).attr("data-reload")&&c.reload_items(),!1},add_item:function(){return a(this).WCBackboneModal({template:"wc-modal-add-products"}),!1},add_fee:function(){c.block();var b={action:"woocommerce_add_order_fee",order_id:woocommerce_admin_meta_boxes.post_id,security:woocommerce_admin_meta_boxes.order_item_nonce};return a.post(woocommerce_admin_meta_boxes.ajax_url,b,function(b){a("table.woocommerce_order_items tbody#order_fee_line_items").append(b),c.unblock()}),!1},add_shipping:function(){c.block();var b={action:"woocommerce_add_order_shipping",order_id:woocommerce_admin_meta_boxes.post_id,security:woocommerce_admin_meta_boxes.order_item_nonce};return a.post(woocommerce_admin_meta_boxes.ajax_url,b,function(b){a("table.woocommerce_order_items tbody#order_shipping_line_items").append(b),c.unblock()}),!1},add_tax:function(){return a(this).WCBackboneModal({template:"wc-modal-add-tax"}),!1},edit_item:function(){return a(this).closest("tr").find(".view").hide(),a(this).closest("tr").find(".edit").show(),a(this).hide(),a("button.add-line-item").click(),a("button.cancel-action").attr("data-reload",!0),!1},delete_item:function(){var b=window.confirm(woocommerce_admin_meta_boxes.remove_item_notice);if(b){var d=a(this).closest("tr.item, tr.fee, tr.shipping"),e=d.attr("data-order_item_id");c.block();var f={order_item_ids:e,action:"woocommerce_remove_order_item",security:woocommerce_admin_meta_boxes.order_item_nonce};a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:f,type:"POST",success:function(){d.remove(),c.unblock()}})}return!1},delete_tax:function(){if(window.confirm(woocommerce_admin_meta_boxes.i18n_delete_tax)){c.block();var d={action:"woocommerce_remove_order_tax",rate_id:a(this).attr("data-rate_id"),order_id:woocommerce_admin_meta_boxes.post_id,security:woocommerce_admin_meta_boxes.order_item_nonce};a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:d,type:"POST",success:function(d){a("#woocommerce-order-items").find(".inside").empty(),a("#woocommerce-order-items").find(".inside").append(d),b.init_tiptip(),c.unblock(),c.stupidtable.init()}})}return!1},calculate_tax:function(){if(window.confirm(woocommerce_admin_meta_boxes.calc_line_taxes)){c.block();var d="",e="",f="",g="";"shipping"===woocommerce_admin_meta_boxes.tax_based_on&&(d=a("#_shipping_country").val(),e=a("#_shipping_state").val(),f=a("#_shipping_postcode").val(),g=a("#_shipping_city").val()),"billing"!==woocommerce_admin_meta_boxes.tax_based_on&&d||(d=a("#_billing_country").val(),e=a("#_billing_state").val(),f=a("#_billing_postcode").val(),g=a("#_billing_city").val());var h={action:"woocommerce_calc_line_taxes",order_id:woocommerce_admin_meta_boxes.post_id,items:a("table.woocommerce_order_items :input[name], .wc-order-totals-items :input[name]").serialize(),country:d,state:e,postcode:f,city:g,security:woocommerce_admin_meta_boxes.calc_totals_nonce};a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:h,type:"POST",success:function(d){a("#woocommerce-order-items").find(".inside").empty(),a("#woocommerce-order-items").find(".inside").append(d),b.init_tiptip(),c.unblock(),c.stupidtable.init()}})}return!1},calculate_totals:function(){if(window.confirm(woocommerce_admin_meta_boxes.calc_totals)){c.block();var b=0,d=0,e=0;a(".woocommerce_order_items tr.shipping input.line_total").each(function(){var b=a(this).val()||"0";b=accounting.unformat(b,woocommerce_admin.mon_decimal_point),e+=parseFloat(b)}),a(".woocommerce_order_items input.line_tax").each(function(){var b=a(this).val()||"0";b=accounting.unformat(b,woocommerce_admin.mon_decimal_point),d+=parseFloat(b)}),a(".woocommerce_order_items tr.item, .woocommerce_order_items tr.fee").each(function(){var c=a(this).find("input.line_total").val()||"0";b+=accounting.unformat(c.replace(",","."))}),"yes"===woocommerce_admin_meta_boxes.round_at_subtotal&&(d=parseFloat(accounting.toFixed(d,woocommerce_admin_meta_boxes.rounding_precision))),a("#_order_total").val(accounting.formatNumber(b+d+e,woocommerce_admin_meta_boxes.currency_format_num_decimals,"",woocommerce_admin.mon_decimal_point)).change(),a("button.save-action").click()}return!1},save_line_items:function(){var d={order_id:woocommerce_admin_meta_boxes.post_id,items:a("table.woocommerce_order_items :input[name], .wc-order-totals-items :input[name]").serialize(),action:"woocommerce_save_order_items",security:woocommerce_admin_meta_boxes.order_item_nonce};return c.block(),a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:d,type:"POST",success:function(d){a("#woocommerce-order-items").find(".inside").empty(),a("#woocommerce-order-items").find(".inside").append(d),b.init_tiptip(),c.unblock(),c.stupidtable.init()}}),a(this).trigger("items_saved"),!1},refunds:{do_refund:function(){if(c.block(),window.confirm(woocommerce_admin_meta_boxes.i18n_do_refund)){var b=a("input#refund_amount").val(),d=a("input#refund_reason").val(),e={},f={},g={};a(".refund input.refund_order_item_qty").each(function(b,c){a(c).closest("tr").data("order_item_id")&&c.value&&(e[a(c).closest("tr").data("order_item_id")]=c.value)}),a(".refund input.refund_line_total").each(function(b,c){a(c).closest("tr").data("order_item_id")&&(f[a(c).closest("tr").data("order_item_id")]=accounting.unformat(c.value,woocommerce_admin.mon_decimal_point))}),a(".refund input.refund_line_tax").each(function(b,c){if(a(c).closest("tr").data("order_item_id")){var d=a(c).data("tax_id");g[a(c).closest("tr").data("order_item_id")]||(g[a(c).closest("tr").data("order_item_id")]={}),g[a(c).closest("tr").data("order_item_id")][d]=accounting.unformat(c.value,woocommerce_admin.mon_decimal_point)}});var h={action:"woocommerce_refund_line_items",order_id:woocommerce_admin_meta_boxes.post_id,refund_amount:b,refund_reason:d,line_item_qtys:JSON.stringify(e,null,""),line_item_totals:JSON.stringify(f,null,""),line_item_tax_totals:JSON.stringify(g,null,""),api_refund:a(this).is(".do-api-refund"),restock_refunded_items:a("#restock_refunded_items:checked").length?"true":"false",security:woocommerce_admin_meta_boxes.order_item_nonce};a.post(woocommerce_admin_meta_boxes.ajax_url,h,function(a){!0===a.success?(c.reload_items(),"fully_refunded"===a.data.status&&(window.location.href=window.location.href)):(window.alert(a.data.error),c.unblock())})}else c.unblock()},delete_refund:function(){if(window.confirm(woocommerce_admin_meta_boxes.i18n_delete_refund)){var b=a(this).closest("tr.refund"),d=b.attr("data-order_refund_id");c.block();var e={action:"woocommerce_delete_refund",refund_id:d,security:woocommerce_admin_meta_boxes.order_item_nonce};a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:e,type:"POST",success:function(){c.reload_items()}})}return!1},input_changed:function(){var b=0,c=a(".woocommerce_order_items").find("tr.item, tr.fee, tr.shipping");c.each(function(){var c=a(this),d=c.find(".refund input:not(.refund_order_item_qty)");d.each(function(c,d){b+=parseFloat(accounting.unformat(a(d).val()||0,woocommerce_admin.mon_decimal_point))})}),a("#refund_amount").val(accounting.formatNumber(b,woocommerce_admin_meta_boxes.currency_format_num_decimals,"",woocommerce_admin.mon_decimal_point)).change()},amount_changed:function(){var b=accounting.unformat(a(this).val(),woocommerce_admin.mon_decimal_point);a("button .wc-order-refund-amount .amount").text(accounting.formatMoney(b,{symbol:woocommerce_admin_meta_boxes.currency_format_symbol,decimal:woocommerce_admin_meta_boxes.currency_format_decimal_sep,thousand:woocommerce_admin_meta_boxes.currency_format_thousand_sep,precision:woocommerce_admin_meta_boxes.currency_format_num_decimals,format:woocommerce_admin_meta_boxes.currency_format}))},refund_quantity_changed:function(){var b=a(this).closest("tr.item"),c=b.find("input.quantity").val(),d=a(this).val(),e=a("input.line_total",b),f=a("input.refund_line_total",b),g=accounting.unformat(e.attr("data-total"),woocommerce_admin.mon_decimal_point)/c;f.val(parseFloat(accounting.formatNumber(g*d,woocommerce_admin_meta_boxes.rounding_precision,"")).toString().replace(".",woocommerce_admin.mon_decimal_point)).change(),a(".refund_line_tax",b).each(function(){var e=a(this),f=e.data("tax_id"),g=a('input.line_tax[data-tax_id="'+f+'"]',b),h=accounting.unformat(g.data("total_tax"),woocommerce_admin.mon_decimal_point)/c;h>0?e.val(parseFloat(accounting.formatNumber(h*d,woocommerce_admin_meta_boxes.rounding_precision,"")).toString().replace(".",woocommerce_admin.mon_decimal_point)).change():e.val(0).change()}),d>0?a("#restock_refunded_items").closest("tr").show():(a("#restock_refunded_items").closest("tr").hide(),a(".woocommerce_order_items input.refund_order_item_qty").each(function(){a(this).val()>0&&a("#restock_refunded_items").closest("tr").show()})),a(this).trigger("refund_quantity_changed")}},item_meta:{add:function(){var b=a(this),d=b.closest("tr.item, tr.shipping"),e={order_item_id:d.attr("data-order_item_id"),action:"woocommerce_add_order_item_meta",security:woocommerce_admin_meta_boxes.order_item_nonce};return c.block(),a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:e,type:"POST",success:function(a){d.find("tbody.meta_items").append(a),c.unblock()}}),!1},remove:function(){if(window.confirm(woocommerce_admin_meta_boxes.remove_item_meta)){var b=a(this).closest("tr"),d={meta_id:b.attr("data-meta_id"),action:"woocommerce_remove_order_item_meta",security:woocommerce_admin_meta_boxes.order_item_nonce};c.block(),a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:d,type:"POST",success:function(){b.remove(),c.unblock()}})}return!1}},select_row:function(){var b=!1;b=a(this).is("tr")?a(this):a(this).closest("tr");var c=a(this).closest("table");b.is(".selected")?b.removeClass("selected"):b.addClass("selected");var d=c.find("tr.selected");if(d.length){a("div.wc-order-item-bulk-edit").slideDown();var e=!1;d.each(function(){a(this).is("tr.item")&&(e=!0)}),e?a(".bulk-increase-stock, .bulk-decrease-stock").show():a(".bulk-increase-stock, .bulk-decrease-stock").hide()}else a("div.wc-order-item-bulk-edit").slideUp()},select_row_child:function(a){a.stopPropagation()},bulk_actions:{do_delete:function(b){b.preventDefault();var d=a("table.woocommerce_order_items"),e=d.find("tr.selected");if(e.length&&window.confirm(woocommerce_admin_meta_boxes.remove_item_notice)){c.block();var f=[],g=[],h=[];a.map(e,function(b){var c=a(b);c.is(".refund")?g.push(parseInt(a(c).data("order_refund_id"),10)):f.push(parseInt(a(c).data("order_item_id"),10))}),f.length&&h.push(a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:{order_item_ids:f,action:"woocommerce_remove_order_item",security:woocommerce_admin_meta_boxes.order_item_nonce},type:"POST"})),g.length&&h.push(a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:{action:"woocommerce_delete_refund",refund_id:g,security:woocommerce_admin_meta_boxes.order_item_nonce},type:"POST"})),h?a.when.apply(a,h).done(function(){c.reload_items(),c.unblock()}):c.unblock()}},do_increase_stock:function(b){b.preventDefault(),c.block();var d=a("table.woocommerce_order_items"),e=d.find("tr.selected"),f={},g=a.map(e,function(b){return parseInt(a(b).data("order_item_id"),10)});e.each(function(){a(this).find("input.quantity").length&&(f[a(this).attr("data-order_item_id")]=a(this).find("input.quantity").val())});var h={order_id:woocommerce_admin_meta_boxes.post_id,order_item_ids:g,order_item_qty:f,action:"woocommerce_increase_order_item_stock",security:woocommerce_admin_meta_boxes.order_item_nonce};a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:h,type:"POST",success:function(a){window.alert(a),c.unblock()}})},do_reduce_stock:function(b){b.preventDefault(),c.block();var d=a("table.woocommerce_order_items"),e=d.find("tr.selected"),f={},g=a.map(e,function(b){return parseInt(a(b).data("order_item_id"),10)});e.each(function(){a(this).find("input.quantity").length&&(f[a(this).attr("data-order_item_id")]=a(this).find("input.quantity").val())});var h={order_id:woocommerce_admin_meta_boxes.post_id,order_item_ids:g,order_item_qty:f,action:"woocommerce_reduce_order_item_stock",security:woocommerce_admin_meta_boxes.order_item_nonce};a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:h,type:"POST",success:function(a){window.alert(a),c.unblock()}})}},backbone:{init:function(b,c){"wc-modal-add-products"===c&&a(document.body).trigger("wc-enhanced-select-init")},response:function(a,b,d){if("wc-modal-add-tax"===b){var e=d.add_order_tax,f="";d.manual_tax_rate_id&&(f=d.manual_tax_rate_id),c.backbone.add_tax(e,f)}"wc-modal-add-products"===b&&c.backbone.add_item(d.add_order_items)},add_item:function(d){if(d=d.split(",")){var e=d.length;c.block(),a.each(d,function(d,f){var g={action:"woocommerce_add_order_item",item_to_add:f,order_id:woocommerce_admin_meta_boxes.post_id,security:woocommerce_admin_meta_boxes.order_item_nonce};a.post(woocommerce_admin_meta_boxes.ajax_url,g,function(d){a("table.woocommerce_order_items tbody#order_line_items").append(d),--e||(b.init_tiptip(),c.unblock())})})}},add_tax:function(d,e){if(e&&(d=e),!d)return!1;var f=a(".order-tax-id").map(function(){return a(this).val()}).get();if(-1===a.inArray(d,f)){c.block();var g={action:"woocommerce_add_order_tax",rate_id:d,order_id:woocommerce_admin_meta_boxes.post_id,security:woocommerce_admin_meta_boxes.order_item_nonce};a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:g,type:"POST",success:function(d){a("#woocommerce-order-items").find(".inside").empty(),a("#woocommerce-order-items").find(".inside").append(d),b.init_tiptip(),c.unblock(),c.stupidtable.init()}})}else window.alert(woocommerce_admin_meta_boxes.i18n_tax_rate_already_exists)}},stupidtable:{init:function(){a(".woocommerce_order_items").stupidtable(),a(".woocommerce_order_items").on("aftertablesort",this.add_arrows)},add_arrows:function(b,c){var d=a(this).find("th"),e="asc"===c.direction?"↑":"↓",f=c.column;d.find(".wc-arrow").remove(),d.eq(f).append(''+e+"")}}},d={init:function(){a("#woocommerce-order-notes").on("click","a.add_note",this.add_order_note).on("click","a.delete_note",this.delete_order_note)},add_order_note:function(){if(a("textarea#add_order_note").val()){a("#woocommerce-order-notes").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var b={action:"woocommerce_add_order_note",post_id:woocommerce_admin_meta_boxes.post_id,note:a("textarea#add_order_note").val(),note_type:a("select#order_note_type").val(),security:woocommerce_admin_meta_boxes.add_order_note_nonce};return a.post(woocommerce_admin_meta_boxes.ajax_url,b,function(b){a("ul.order_notes").prepend(b),a("#woocommerce-order-notes").unblock(),a("#add_order_note").val("")}),!1}},delete_order_note:function(){if(window.confirm(woocommerce_admin_meta_boxes.i18n_delete_note)){var b=a(this).closest("li.note");a(b).block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={action:"woocommerce_delete_order_note",note_id:a(b).attr("rel"),security:woocommerce_admin_meta_boxes.delete_order_note_nonce};a.post(woocommerce_admin_meta_boxes.ajax_url,c,function(){a(b).remove()})}return!1}},e={init:function(){a(".order_download_permissions").on("click","button.grant_access",this.grant_access).on("click","button.revoke_access",this.revoke_access)},grant_access:function(){var b=a("#grant_access_id").val();if(b){a(".order_download_permissions").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={action:"woocommerce_grant_access_to_download",product_ids:b,loop:a(".order_download_permissions .wc-metabox").length,order_id:woocommerce_admin_meta_boxes.post_id,security:woocommerce_admin_meta_boxes.grant_access_nonce};return a.post(woocommerce_admin_meta_boxes.ajax_url,c,function(b){b?a(".order_download_permissions .wc-metaboxes").append(b):window.alert(woocommerce_admin_meta_boxes.i18n_download_permission_fail),a(document.body).trigger("wc-init-datepickers"),a("#grant_access_id").val("").change(),a(".order_download_permissions").unblock()}),!1}},revoke_access:function(){if(window.confirm(woocommerce_admin_meta_boxes.i18n_permission_revoke)){var b=a(this).parent().parent(),c=a(this).attr("rel").split(",")[0],d=a(this).attr("rel").split(",")[1];if(c>0){a(b).block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var e={action:"woocommerce_revoke_access_to_download",product_id:c,download_id:d,order_id:woocommerce_admin_meta_boxes.post_id,security:woocommerce_admin_meta_boxes.revoke_access_nonce};a.post(woocommerce_admin_meta_boxes.ajax_url,e,function(){a(b).fadeOut("300",function(){a(b).remove()})})}else a(b).fadeOut("300",function(){a(b).remove()})}return!1}};b.init(),c.init(),d.init(),e.init()}); \ No newline at end of file +jQuery(function(a){var b={states:null,init:function(){"undefined"!=typeof woocommerce_admin_meta_boxes_order&&"undefined"!=typeof woocommerce_admin_meta_boxes_order.countries&&(this.states=a.parseJSON(woocommerce_admin_meta_boxes_order.countries.replace(/"/g,'"'))),a(".js_field-country").select2().change(this.change_country),a(".js_field-country").trigger("change",[!0]),a(document.body).on("change","select.js_field-state",this.change_state),a("#woocommerce-order-actions input, #woocommerce-order-actions a").click(function(){window.onbeforeunload=""}),a("a.edit_address").click(this.edit_address),a("a.billing-same-as-shipping").on("click",this.copy_billing_to_shipping),a("a.load_customer_billing").on("click",this.load_billing),a("a.load_customer_shipping").on("click",this.load_shipping),a("#customer_user").on("change",this.change_customer_user)},change_country:function(c,d){if("undefined"==typeof d&&(d=!1),null!==b.states){var e=a(this),f=e.val(),g=e.parents("div.edit_address").find(":input.js_field-state"),h=g.parent(),i=g.attr("name"),j=g.attr("id"),k=e.data("woocommerce.stickState-"+f)?e.data("woocommerce.stickState-"+f):g.val(),l=g.attr("placeholder");if(d&&e.data("woocommerce.stickState-"+f,k),h.show().find(".select2-container").remove(),a.isEmptyObject(b.states[f]))g.replaceWith('');else{var m=a(''),n=b.states[f];m.append(a('")),a.each(n,function(b){m.append(a('"))}),m.val(k),g.replaceWith(m),m.show().select2().hide().change()}a(document.body).trigger("contry-change.woocommerce",[f,a(this).closest("div")]),a(document.body).trigger("country-change.woocommerce",[f,a(this).closest("div")])}},change_state:function(){var b=a(this),c=b.val(),d=b.parents("div.edit_address").find(":input.js_field-country"),e=d.val();d.data("woocommerce.stickState-"+e,c)},init_tiptip:function(){a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200})},edit_address:function(b){b.preventDefault(),a(this).hide(),a(this).parent().find("a:not(.edit_address)").show(),a(this).closest(".order_data_column").find("div.address").hide(),a(this).closest(".order_data_column").find("div.edit_address").show()},change_customer_user:function(){a("#_billing_country").val()||(a("a.edit_address").click(),b.load_billing(!0),b.load_shipping(!0))},load_billing:function(b){if(!0===b||window.confirm(woocommerce_admin_meta_boxes.load_billing)){var c=a("#customer_user").val();if(!c)return window.alert(woocommerce_admin_meta_boxes.no_customer_selected),!1;var d={user_id:c,type_to_load:"billing",action:"woocommerce_get_customer_details",security:woocommerce_admin_meta_boxes.get_customer_details_nonce};a(this).closest("div.edit_address").block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:d,type:"POST",success:function(b){b&&a.each(b,function(b,c){a(":input#_"+b).val(c).change()}),a("div.edit_address").unblock()}})}return!1},load_shipping:function(b){if(!0===b||window.confirm(woocommerce_admin_meta_boxes.load_shipping)){var c=a("#customer_user").val();if(!c)return window.alert(woocommerce_admin_meta_boxes.no_customer_selected),!1;var d={user_id:c,type_to_load:"shipping",action:"woocommerce_get_customer_details",security:woocommerce_admin_meta_boxes.get_customer_details_nonce};a(this).closest("div.edit_address").block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:d,type:"POST",success:function(b){b&&a.each(b,function(b,c){a(":input#_"+b).val(c).change()}),a("div.edit_address").unblock()}})}return!1},copy_billing_to_shipping:function(){return window.confirm(woocommerce_admin_meta_boxes.copy_billing)&&a('.order_data_column :input[name^="_billing_"]').each(function(){var b=a(this).attr("name");b=b.replace("_billing_","_shipping_"),a(":input#"+b).val(a(this).val()).change()}),!1}},c={init:function(){this.stupidtable.init(),a("#woocommerce-order-items").on("click","button.add-line-item",this.add_line_item).on("click","button.refund-items",this.refund_items).on("click",".cancel-action",this.cancel).on("click","button.add-order-item",this.add_item).on("click","button.add-order-fee",this.add_fee).on("click","button.add-order-shipping",this.add_shipping).on("click","button.add-order-tax",this.add_tax).on("click","button.calculate-action",this.calculate_totals).on("click","button.save-action",this.save_line_items).on("click","a.delete-order-tax",this.delete_tax).on("click","button.calculate-tax-action",this.calculate_tax).on("click","a.edit-order-item",this.edit_item).on("click","a.delete-order-item",this.delete_item).on("click","tr.item, tr.fee, tr.shipping, tr.refund",this.select_row).on("click","tr.item :input, tr.fee :input, tr.shipping :input, tr.refund :input, tr.item a, tr.fee a, tr.shipping a, tr.refund a",this.select_row_child).on("click","button.bulk-delete-items",this.bulk_actions.do_delete).on("click","button.bulk-increase-stock",this.bulk_actions.do_increase_stock).on("click","button.bulk-decrease-stock",this.bulk_actions.do_reduce_stock).on("click",".delete_refund",this.refunds.delete_refund).on("click","button.do-api-refund, button.do-manual-refund",this.refunds.do_refund).on("change",".refund input.refund_line_total, .refund input.refund_line_tax",this.refunds.input_changed).on("change keyup",".wc-order-refund-items #refund_amount",this.refunds.amount_changed).on("change","input.refund_order_item_qty",this.refunds.refund_quantity_changed).on("change","input.quantity",this.quantity_changed).on("keyup change",".split-input :input",function(){var b=a(this).parent().prev().find(":input");b&&(""===b.val()||b.is(".match-total"))&&b.val(a(this).val()).addClass("match-total")}).on("keyup",".split-input :input",function(){a(this).removeClass("match-total")}).on("click","button.add_order_item_meta",this.item_meta.add).on("click","button.remove_order_item_meta",this.item_meta.remove),a(document.body).on("wc_backbone_modal_loaded",this.backbone.init).on("wc_backbone_modal_response",this.backbone.response)},block:function(){a("#woocommerce-order-items").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a("#woocommerce-order-items").unblock()},reload_items:function(){var d={order_id:woocommerce_admin_meta_boxes.post_id,action:"woocommerce_load_order_items",security:woocommerce_admin_meta_boxes.order_item_nonce};c.block(),a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:d,type:"POST",success:function(d){a("#woocommerce-order-items").find(".inside").empty(),a("#woocommerce-order-items").find(".inside").append(d),b.init_tiptip(),c.unblock(),c.stupidtable.init()}})},quantity_changed:function(){var b=a(this).closest("tr.item"),c=a(this).val(),d=a(this).attr("data-qty"),e=a("input.line_total",b),f=a("input.line_subtotal",b),g=accounting.unformat(e.attr("data-total"),woocommerce_admin.mon_decimal_point)/d;e.val(parseFloat(accounting.formatNumber(g*c,woocommerce_admin_meta_boxes.rounding_precision,"")).toString().replace(".",woocommerce_admin.mon_decimal_point));var h=accounting.unformat(f.attr("data-subtotal"),woocommerce_admin.mon_decimal_point)/d;f.val(parseFloat(accounting.formatNumber(h*c,woocommerce_admin_meta_boxes.rounding_precision,"")).toString().replace(".",woocommerce_admin.mon_decimal_point)),a("input.line_tax",b).each(function(){var e=a(this),f=e.data("tax_id"),g=accounting.unformat(e.attr("data-total_tax"),woocommerce_admin.mon_decimal_point)/d,h=a('input.line_subtotal_tax[data-tax_id="'+f+'"]',b),i=accounting.unformat(h.attr("data-subtotal_tax"),woocommerce_admin.mon_decimal_point)/d;00?a("#restock_refunded_items").closest("tr").show():(a("#restock_refunded_items").closest("tr").hide(),a(".woocommerce_order_items input.refund_order_item_qty").each(function(){a(this).val()>0&&a("#restock_refunded_items").closest("tr").show()})),a(this).trigger("refund_quantity_changed")}},item_meta:{add:function(){var b=a(this),d=b.closest("tr.item, tr.shipping"),e={order_item_id:d.attr("data-order_item_id"),action:"woocommerce_add_order_item_meta",security:woocommerce_admin_meta_boxes.order_item_nonce};return c.block(),a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:e,type:"POST",success:function(a){d.find("tbody.meta_items").append(a),c.unblock()}}),!1},remove:function(){if(window.confirm(woocommerce_admin_meta_boxes.remove_item_meta)){var b=a(this).closest("tr"),d={meta_id:b.attr("data-meta_id"),action:"woocommerce_remove_order_item_meta",security:woocommerce_admin_meta_boxes.order_item_nonce};c.block(),a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:d,type:"POST",success:function(){b.remove(),c.unblock()}})}return!1}},select_row:function(){var b=!1;b=a(this).is("tr")?a(this):a(this).closest("tr");var c=a(this).closest("table");b.is(".selected")?b.removeClass("selected"):b.addClass("selected");var d=c.find("tr.selected");if(d.length){a("div.wc-order-item-bulk-edit").slideDown();var e=!1;d.each(function(){a(this).is("tr.item")&&(e=!0)}),e?a(".bulk-increase-stock, .bulk-decrease-stock").show():a(".bulk-increase-stock, .bulk-decrease-stock").hide()}else a("div.wc-order-item-bulk-edit").slideUp()},select_row_child:function(a){a.stopPropagation()},bulk_actions:{do_delete:function(b){b.preventDefault();var d=a("table.woocommerce_order_items"),e=d.find("tr.selected");if(e.length&&window.confirm(woocommerce_admin_meta_boxes.remove_item_notice)){c.block();var f=[],g=[],h=[];a.map(e,function(b){var c=a(b);c.is(".refund")?g.push(parseInt(a(c).data("order_refund_id"),10)):f.push(parseInt(a(c).data("order_item_id"),10))}),f.length&&h.push(a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:{order_item_ids:f,action:"woocommerce_remove_order_item",security:woocommerce_admin_meta_boxes.order_item_nonce},type:"POST"})),g.length&&h.push(a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:{action:"woocommerce_delete_refund",refund_id:g,security:woocommerce_admin_meta_boxes.order_item_nonce},type:"POST"})),h?a.when.apply(a,h).done(function(){c.reload_items(),c.unblock()}):c.unblock()}},do_increase_stock:function(b){b.preventDefault(),c.block();var d=a("table.woocommerce_order_items"),e=d.find("tr.selected"),f={},g=a.map(e,function(b){return parseInt(a(b).data("order_item_id"),10)});e.each(function(){a(this).find("input.quantity").length&&(f[a(this).attr("data-order_item_id")]=a(this).find("input.quantity").val())});var h={order_id:woocommerce_admin_meta_boxes.post_id,order_item_ids:g,order_item_qty:f,action:"woocommerce_increase_order_item_stock",security:woocommerce_admin_meta_boxes.order_item_nonce};a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:h,type:"POST",success:function(a){window.alert(a),c.unblock()}})},do_reduce_stock:function(b){b.preventDefault(),c.block();var d=a("table.woocommerce_order_items"),e=d.find("tr.selected"),f={},g=a.map(e,function(b){return parseInt(a(b).data("order_item_id"),10)});e.each(function(){a(this).find("input.quantity").length&&(f[a(this).attr("data-order_item_id")]=a(this).find("input.quantity").val())});var h={order_id:woocommerce_admin_meta_boxes.post_id,order_item_ids:g,order_item_qty:f,action:"woocommerce_reduce_order_item_stock",security:woocommerce_admin_meta_boxes.order_item_nonce};a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:h,type:"POST",success:function(a){window.alert(a),c.unblock()}})}},backbone:{init:function(b,c){"wc-modal-add-products"===c&&a(document.body).trigger("wc-enhanced-select-init")},response:function(a,b,d){if("wc-modal-add-tax"===b){var e=d.add_order_tax,f="";d.manual_tax_rate_id&&(f=d.manual_tax_rate_id),c.backbone.add_tax(e,f)}"wc-modal-add-products"===b&&c.backbone.add_item(d.add_order_items)},add_item:function(d){if(d=d.split(",")){var e=d.length;c.block(),a.each(d,function(d,f){var g={action:"woocommerce_add_order_item",item_to_add:f,order_id:woocommerce_admin_meta_boxes.post_id,security:woocommerce_admin_meta_boxes.order_item_nonce};a.post(woocommerce_admin_meta_boxes.ajax_url,g,function(d){a("table.woocommerce_order_items tbody#order_line_items").append(d),--e||(b.init_tiptip(),c.unblock())})})}},add_tax:function(d,e){if(e&&(d=e),!d)return!1;var f=a(".order-tax-id").map(function(){return a(this).val()}).get();if(-1===a.inArray(d,f)){c.block();var g={action:"woocommerce_add_order_tax",rate_id:d,order_id:woocommerce_admin_meta_boxes.post_id,security:woocommerce_admin_meta_boxes.order_item_nonce};a.ajax({url:woocommerce_admin_meta_boxes.ajax_url,data:g,type:"POST",success:function(d){a("#woocommerce-order-items").find(".inside").empty(),a("#woocommerce-order-items").find(".inside").append(d),b.init_tiptip(),c.unblock(),c.stupidtable.init()}})}else window.alert(woocommerce_admin_meta_boxes.i18n_tax_rate_already_exists)}},stupidtable:{init:function(){a(".woocommerce_order_items").stupidtable(),a(".woocommerce_order_items").on("aftertablesort",this.add_arrows)},add_arrows:function(b,c){var d=a(this).find("th"),e="asc"===c.direction?"↑":"↓",f=c.column;d.find(".wc-arrow").remove(),d.eq(f).append(''+e+"")}}},d={init:function(){a("#woocommerce-order-notes").on("click","a.add_note",this.add_order_note).on("click","a.delete_note",this.delete_order_note)},add_order_note:function(){if(a("textarea#add_order_note").val()){a("#woocommerce-order-notes").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var b={action:"woocommerce_add_order_note",post_id:woocommerce_admin_meta_boxes.post_id,note:a("textarea#add_order_note").val(),note_type:a("select#order_note_type").val(),security:woocommerce_admin_meta_boxes.add_order_note_nonce};return a.post(woocommerce_admin_meta_boxes.ajax_url,b,function(b){a("ul.order_notes").prepend(b),a("#woocommerce-order-notes").unblock(),a("#add_order_note").val("")}),!1}},delete_order_note:function(){if(window.confirm(woocommerce_admin_meta_boxes.i18n_delete_note)){var b=a(this).closest("li.note");a(b).block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={action:"woocommerce_delete_order_note",note_id:a(b).attr("rel"),security:woocommerce_admin_meta_boxes.delete_order_note_nonce};a.post(woocommerce_admin_meta_boxes.ajax_url,c,function(){a(b).remove()})}return!1}},e={init:function(){a(".order_download_permissions").on("click","button.grant_access",this.grant_access).on("click","button.revoke_access",this.revoke_access)},grant_access:function(){var b=a("#grant_access_id").val();if(b){a(".order_download_permissions").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={action:"woocommerce_grant_access_to_download",product_ids:b,loop:a(".order_download_permissions .wc-metabox").length,order_id:woocommerce_admin_meta_boxes.post_id,security:woocommerce_admin_meta_boxes.grant_access_nonce};return a.post(woocommerce_admin_meta_boxes.ajax_url,c,function(b){b?a(".order_download_permissions .wc-metaboxes").append(b):window.alert(woocommerce_admin_meta_boxes.i18n_download_permission_fail),a(document.body).trigger("wc-init-datepickers"),a("#grant_access_id").val("").change(),a(".order_download_permissions").unblock()}),!1}},revoke_access:function(){if(window.confirm(woocommerce_admin_meta_boxes.i18n_permission_revoke)){var b=a(this).parent().parent(),c=a(this).attr("rel").split(",")[0],d=a(this).attr("rel").split(",")[1];if(c>0){a(b).block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var e={action:"woocommerce_revoke_access_to_download",product_id:c,download_id:d,order_id:woocommerce_admin_meta_boxes.post_id,security:woocommerce_admin_meta_boxes.revoke_access_nonce};a.post(woocommerce_admin_meta_boxes.ajax_url,e,function(){a(b).fadeOut("300",function(){a(b).remove()})})}else a(b).fadeOut("300",function(){a(b).remove()})}return!1}};b.init(),c.init(),d.init(),e.init()}); \ No newline at end of file diff --git a/assets/js/admin/meta-boxes-product-variation.min.js b/assets/js/admin/meta-boxes-product-variation.min.js index 9161bcea599..9adcd7cdfa4 100644 --- a/assets/js/admin/meta-boxes-product-variation.min.js +++ b/assets/js/admin/meta-boxes-product-variation.min.js @@ -1 +1 @@ -jQuery(function(a){var b={init:function(){a("#variable_product_options").on("change","input.variable_is_downloadable",this.variable_is_downloadable).on("change","input.variable_is_virtual",this.variable_is_virtual).on("change","input.variable_manage_stock",this.variable_manage_stock).on("click","button.notice-dismiss",this.notice_dismiss).on("click","h3 .sort",this.set_menu_order).on("reload",this.reload),a("input.variable_is_downloadable, input.variable_is_virtual, input.variable_manage_stock").change(),a("#woocommerce-product-data").on("woocommerce_variations_loaded",this.variations_loaded),a(document.body).on("woocommerce_variations_added",this.variation_added)},reload:function(){d.load_variations(1)},variable_is_downloadable:function(){a(this).closest(".woocommerce_variation").find(".show_if_variation_downloadable").hide(),a(this).is(":checked")&&a(this).closest(".woocommerce_variation").find(".show_if_variation_downloadable").show()},variable_is_virtual:function(){a(this).closest(".woocommerce_variation").find(".hide_if_variation_virtual").show(),a(this).is(":checked")&&a(this).closest(".woocommerce_variation").find(".hide_if_variation_virtual").hide()},variable_manage_stock:function(){a(this).closest(".woocommerce_variation").find(".show_if_variation_manage_stock").hide(),a(this).is(":checked")&&a(this).closest(".woocommerce_variation").find(".show_if_variation_manage_stock").show()},notice_dismiss:function(){a(this).closest("div.notice").remove()},variations_loaded:function(c,d){d=d||!1;var e=a("#woocommerce-product-data");d||(a("input.variable_is_downloadable, input.variable_is_virtual, input.variable_manage_stock",e).change(),a(".woocommerce_variation",e).each(function(b,c){var d=a(c),e=a(".sale_price_dates_from",d).val(),f=a(".sale_price_dates_to",d).val();""===e&&""===f||a("a.sale_schedule",d).click()}),a(".woocommerce_variations .variation-needs-update",e).removeClass("variation-needs-update"),a("button.cancel-variation-changes, button.save-variation-changes",e).attr("disabled","disabled")),a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".woocommerce_variations .tips, .woocommerce_variations .help_tip, .woocommerce_variations .woocommerce-help-tip",e).tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200}),a(".sale_price_dates_fields",e).each(function(){var b=a(this).find("input").datepicker({defaultDate:"",dateFormat:"yy-mm-dd",numberOfMonths:1,showButtonPanel:!0,onSelect:function(c){var d=a(this).is(".sale_price_dates_from")?"minDate":"maxDate",e=a(this).data("datepicker"),f=a.datepicker.parseDate(e.settings.dateFormat||a.datepicker._defaults.dateFormat,c,e.settings);b.not(this).datepicker("option",d,f),a(this).change()}})}),a(".woocommerce_variations",e).sortable({items:".woocommerce_variation",cursor:"move",axis:"y",handle:".sort",scrollSensitivity:40,forcePlaceholderSize:!0,helper:"clone",opacity:.65,stop:function(){b.variation_row_indexes()}}),a(document.body).trigger("wc-enhanced-select-init")},variation_added:function(a,c){1===c&&b.variations_loaded(null,!0)},set_menu_order:function(b){b.preventDefault();var c=a(this).closest(".woocommerce_variation").find(".variation_menu_order"),e=window.prompt(woocommerce_admin_meta_boxes_variations.i18n_enter_menu_order,c.val());null!=e&&(c.val(parseInt(e,10)).change(),d.save_variations())},variation_row_indexes:function(){var b=a("#variable_product_options").find(".woocommerce_variations"),c=parseInt(b.attr("data-page"),10),d=parseInt((c-1)*woocommerce_admin_meta_boxes_variations.variations_per_page,10);a(".woocommerce_variations .woocommerce_variation").each(function(b,c){a(".variation_menu_order",c).val(parseInt(a(c).index(".woocommerce_variations .woocommerce_variation"),10)+1+d).change()})}},c={variable_image_frame:null,setting_variation_image_id:null,setting_variation_image:null,wp_media_post_id:wp.media.model.settings.post.id,init:function(){a("#variable_product_options").on("click",".upload_image_button",this.add_image),a("a.add_media").on("click",this.restore_wp_media_post_id)},add_image:function(b){var d=a(this),e=d.attr("rel"),f=d.closest(".upload_image");if(c.setting_variation_image=f,c.setting_variation_image_id=e,b.preventDefault(),d.is(".remove"))a(".upload_image_id",c.setting_variation_image).val("").change(),c.setting_variation_image.find("img").eq(0).attr("src",woocommerce_admin_meta_boxes_variations.woocommerce_placeholder_img_src),c.setting_variation_image.find(".upload_image_button").removeClass("remove");else{if(c.variable_image_frame)return c.variable_image_frame.uploader.uploader.param("post_id",c.setting_variation_image_id),void c.variable_image_frame.open();wp.media.model.settings.post.id=c.setting_variation_image_id,c.variable_image_frame=wp.media.frames.variable_image=wp.media({title:woocommerce_admin_meta_boxes_variations.i18n_choose_image,button:{text:woocommerce_admin_meta_boxes_variations.i18n_set_image},states:[new wp.media.controller.Library({title:woocommerce_admin_meta_boxes_variations.i18n_choose_image,filterable:"all"})]}),c.variable_image_frame.on("select",function(){var b=c.variable_image_frame.state().get("selection").first().toJSON(),d=b.sizes&&b.sizes.thumbnail?b.sizes.thumbnail.url:b.url;a(".upload_image_id",c.setting_variation_image).val(b.id).change(),c.setting_variation_image.find(".upload_image_button").addClass("remove"),c.setting_variation_image.find("img").eq(0).attr("src",d),wp.media.model.settings.post.id=c.wp_media_post_id}),c.variable_image_frame.open()}},restore_wp_media_post_id:function(){wp.media.model.settings.post.id=c.wp_media_post_id}},d={init:function(){a("li.variations_tab a").on("click",this.initial_load),a("#variable_product_options").on("click","button.save-variation-changes",this.save_variations).on("click","button.cancel-variation-changes",this.cancel_variations).on("click",".remove_variation",this.remove_variation),a(document.body).on("change","#variable_product_options .woocommerce_variations :input",this.input_changed).on("change",".variations-defaults select",this.defaults_changed),a("form#post").on("submit",this.save_on_submit),a(".wc-metaboxes-wrapper").on("click","a.do_variation_action",this.do_variation_action)},check_for_changes:function(){var b=a("#variable_product_options").find(".woocommerce_variations .variation-needs-update");if(00?(c.push(b),f.variation_ids=c,f.security=woocommerce_admin_meta_boxes_variations.delete_variations_nonce,a.post(woocommerce_admin_meta_boxes_variations.ajax_url,f,function(){var b=a("#variable_product_options").find(".woocommerce_variations"),c=parseInt(b.attr("data-page"),10),d=Math.ceil((parseInt(b.attr("data-total"),10)-1)/woocommerce_admin_meta_boxes_variations.variations_per_page),f=1;a("#woocommerce-product-data").trigger("woocommerce_variations_removed"),c===d||d>=c?f=c:c>d&&0!==d&&(f=d),e.go_to_page(f,-1)})):d.unblock()}return!1},link_all_variations:function(){if(d.check_for_changes(),window.confirm(woocommerce_admin_meta_boxes_variations.i18n_link_all_variations)){d.block();var b={action:"woocommerce_link_all_variations",post_id:woocommerce_admin_meta_boxes_variations.post_id,security:woocommerce_admin_meta_boxes_variations.link_variation_nonce};a.post(woocommerce_admin_meta_boxes_variations.ajax_url,b,function(b){var c=parseInt(b,10);1===c?window.alert(c+" "+woocommerce_admin_meta_boxes_variations.i18n_variation_added):0===c||c>1?window.alert(c+" "+woocommerce_admin_meta_boxes_variations.i18n_variations_added):window.alert(woocommerce_admin_meta_boxes_variations.i18n_no_variations_added),c>0?(e.go_to_page(1,c),a("#variable_product_options").trigger("woocommerce_variations_added",c)):d.unblock()})}return!1},input_changed:function(){a(this).closest(".woocommerce_variation").addClass("variation-needs-update"),a("button.cancel-variation-changes, button.save-variation-changes").removeAttr("disabled"),a("#variable_product_options").trigger("woocommerce_variations_input_changed")},defaults_changed:function(){a(this).closest("#variable_product_options").find(".woocommerce_variation:first").addClass("variation-needs-update"),a("button.cancel-variation-changes, button.save-variation-changes").removeAttr("disabled"),a("#variable_product_options").trigger("woocommerce_variations_defaults_changed")},do_variation_action:function(){var b,c=a("select.variation_actions").val(),f={},g=0;switch(c){case"add_variation":return void d.add_variation();case"link_all_variations":return void d.link_all_variations();case"delete_all":window.confirm(woocommerce_admin_meta_boxes_variations.i18n_delete_all_variations)&&window.confirm(woocommerce_admin_meta_boxes_variations.i18n_last_warning)&&(f.allowed=!0,g=-1*parseInt(a("#variable_product_options").find(".woocommerce_variations").attr("data-total"),10));break;case"variable_regular_price_increase":case"variable_regular_price_decrease":case"variable_sale_price_increase":case"variable_sale_price_decrease":b=window.prompt(woocommerce_admin_meta_boxes_variations.i18n_enter_a_value_fixed_or_percent),null!=b&&(b.indexOf("%")>=0?f.value=accounting.unformat(b.replace(/\%/,""),woocommerce_admin.mon_decimal_point)+"%":f.value=accounting.unformat(b,woocommerce_admin.mon_decimal_point));break;case"variable_regular_price":case"variable_sale_price":case"variable_stock":case"variable_weight":case"variable_length":case"variable_width":case"variable_height":case"variable_download_limit":case"variable_download_expiry":b=window.prompt(woocommerce_admin_meta_boxes_variations.i18n_enter_a_value),null!=b&&(f.value=b);break;case"variable_sale_schedule":f.date_from=window.prompt(woocommerce_admin_meta_boxes_variations.i18n_scheduled_sale_start),f.date_to=window.prompt(woocommerce_admin_meta_boxes_variations.i18n_scheduled_sale_end),null===f.date_from&&(f.date_from=!1),null===f.date_to&&(f.date_to=!1);break;default:a("select.variation_actions").trigger(c),f=a("select.variation_actions").triggerHandler(c+"_ajax_data",f)}"delete_all"===c&&f.allowed?a("#variable_product_options").find(".variation-needs-update").removeClass("variation-needs-update"):d.check_for_changes(),d.block(),a.ajax({url:woocommerce_admin_meta_boxes_variations.ajax_url,data:{action:"woocommerce_bulk_edit_variations",security:woocommerce_admin_meta_boxes_variations.bulk_edit_variations_nonce,product_id:woocommerce_admin_meta_boxes_variations.post_id,product_type:a("#product-type").val(),bulk_action:c,data:f},type:"POST",success:function(){e.go_to_page(1,g)}})}},e={init:function(){a(document.body).on("woocommerce_variations_added",this.update_single_quantity).on("change",".variations-pagenav .page-selector",this.page_selector).on("click",".variations-pagenav .first-page",this.first_page).on("click",".variations-pagenav .prev-page",this.prev_page).on("click",".variations-pagenav .next-page",this.next_page).on("click",".variations-pagenav .last-page",this.last_page)},update_variations_count:function(b){var c=a("#variable_product_options").find(".woocommerce_variations"),d=parseInt(c.attr("data-total"),10)+b,e=a(".variations-pagenav .displaying-num");return c.attr("data-total",d),1===d?e.text(woocommerce_admin_meta_boxes_variations.i18n_variation_count_single.replace("%qty%",d)):e.text(woocommerce_admin_meta_boxes_variations.i18n_variation_count_plural.replace("%qty%",d)),d},update_single_quantity:function(b,c){if(1===c){var d=a(".variations-pagenav");e.update_variations_count(c),d.is(":hidden")&&(a("option, optgroup",".variation_actions").show(),a(".variation_actions").val("add_variation"),a("#variable_product_options").find(".toolbar").show(),d.show(),a(".pagination-links",d).hide())}},set_paginav:function(b){var c=a("#variable_product_options").find(".woocommerce_variations"),d=e.update_variations_count(b),f=a("#variable_product_options").find(".toolbar"),g=a(".variation_actions"),h=a(".variations-pagenav"),i=a(".pagination-links",h),j=Math.ceil(d/woocommerce_admin_meta_boxes_variations.variations_per_page),k="";c.attr("data-total_pages",j),a(".total-pages",h).text(j);for(var l=1;j>=l;l++)k+='";a(".page-selector",h).empty().html(k),0===d?(f.not(".toolbar-top, .toolbar-buttons").hide(),h.hide(),a("option, optgroup",g).hide(),a(".variation_actions").val("add_variation"),a('option[data-global="true"]',g).show()):(f.show(),h.show(),a("option, optgroup",g).show(),a(".variation_actions").val("add_variation"),1===j?i.hide():i.show())},check_is_enabled:function(b){return!a(b).hasClass("disabled")},change_classes:function(b,c){var d=a(".variations-pagenav .first-page"),e=a(".variations-pagenav .prev-page"),f=a(".variations-pagenav .next-page"),g=a(".variations-pagenav .last-page");1===b?(d.addClass("disabled"),e.addClass("disabled")):(d.removeClass("disabled"),e.removeClass("disabled")),c===b?(f.addClass("disabled"),g.addClass("disabled")):(f.removeClass("disabled"),g.removeClass("disabled"))},set_page:function(b){a(".variations-pagenav .page-selector").val(b).first().change()},go_to_page:function(a,b){a=a||1,b=b||0,e.set_paginav(b),e.set_page(a)},page_selector:function(){var b=parseInt(a(this).val(),10),c=a("#variable_product_options").find(".woocommerce_variations");a(".variations-pagenav .page-selector").val(b),d.check_for_changes(),e.change_classes(b,parseInt(c.attr("data-total_pages"),10)),d.load_variations(b)},first_page:function(){return e.check_is_enabled(this)&&e.set_page(1),!1},prev_page:function(){if(e.check_is_enabled(this)){var b=a("#variable_product_options").find(".woocommerce_variations"),c=parseInt(b.attr("data-page"),10)-1,d=c>0?c:1;e.set_page(d)}return!1},next_page:function(){if(e.check_is_enabled(this)){var b=a("#variable_product_options").find(".woocommerce_variations"),c=parseInt(b.attr("data-total_pages"),10),d=parseInt(b.attr("data-page"),10)+1,f=c>=d?d:c;e.set_page(f)}return!1},last_page:function(){if(e.check_is_enabled(this)){var b=a("#variable_product_options").find(".woocommerce_variations").attr("data-total_pages");e.set_page(b)}return!1}};b.init(),c.init(),d.init(),e.init()}); \ No newline at end of file +jQuery(function(a){var b={init:function(){a("#variable_product_options").on("change","input.variable_is_downloadable",this.variable_is_downloadable).on("change","input.variable_is_virtual",this.variable_is_virtual).on("change","input.variable_manage_stock",this.variable_manage_stock).on("click","button.notice-dismiss",this.notice_dismiss).on("click","h3 .sort",this.set_menu_order).on("reload",this.reload),a("input.variable_is_downloadable, input.variable_is_virtual, input.variable_manage_stock").change(),a("#woocommerce-product-data").on("woocommerce_variations_loaded",this.variations_loaded),a(document.body).on("woocommerce_variations_added",this.variation_added)},reload:function(){d.load_variations(1)},variable_is_downloadable:function(){a(this).closest(".woocommerce_variation").find(".show_if_variation_downloadable").hide(),a(this).is(":checked")&&a(this).closest(".woocommerce_variation").find(".show_if_variation_downloadable").show()},variable_is_virtual:function(){a(this).closest(".woocommerce_variation").find(".hide_if_variation_virtual").show(),a(this).is(":checked")&&a(this).closest(".woocommerce_variation").find(".hide_if_variation_virtual").hide()},variable_manage_stock:function(){a(this).closest(".woocommerce_variation").find(".show_if_variation_manage_stock").hide(),a(this).is(":checked")&&a(this).closest(".woocommerce_variation").find(".show_if_variation_manage_stock").show()},notice_dismiss:function(){a(this).closest("div.notice").remove()},variations_loaded:function(c,d){d=d||!1;var e=a("#woocommerce-product-data");d||(a("input.variable_is_downloadable, input.variable_is_virtual, input.variable_manage_stock",e).change(),a(".woocommerce_variation",e).each(function(b,c){var d=a(c),e=a(".sale_price_dates_from",d).val(),f=a(".sale_price_dates_to",d).val();""===e&&""===f||a("a.sale_schedule",d).click()}),a(".woocommerce_variations .variation-needs-update",e).removeClass("variation-needs-update"),a("button.cancel-variation-changes, button.save-variation-changes",e).attr("disabled","disabled")),a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".woocommerce_variations .tips, .woocommerce_variations .help_tip, .woocommerce_variations .woocommerce-help-tip",e).tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200}),a(".sale_price_dates_fields",e).each(function(){var b=a(this).find("input").datepicker({defaultDate:"",dateFormat:"yy-mm-dd",numberOfMonths:1,showButtonPanel:!0,onSelect:function(c){var d=a(this).is(".sale_price_dates_from")?"minDate":"maxDate",e=a(this).data("datepicker"),f=a.datepicker.parseDate(e.settings.dateFormat||a.datepicker._defaults.dateFormat,c,e.settings);b.not(this).datepicker("option",d,f),a(this).change()}})}),a(".woocommerce_variations",e).sortable({items:".woocommerce_variation",cursor:"move",axis:"y",handle:".sort",scrollSensitivity:40,forcePlaceholderSize:!0,helper:"clone",opacity:.65,stop:function(){b.variation_row_indexes()}}),a(document.body).trigger("wc-enhanced-select-init")},variation_added:function(a,c){1===c&&b.variations_loaded(null,!0)},set_menu_order:function(b){b.preventDefault();var c=a(this).closest(".woocommerce_variation").find(".variation_menu_order"),e=window.prompt(woocommerce_admin_meta_boxes_variations.i18n_enter_menu_order,c.val());null!=e&&(c.val(parseInt(e,10)).change(),d.save_variations())},variation_row_indexes:function(){var b=a("#variable_product_options").find(".woocommerce_variations"),c=parseInt(b.attr("data-page"),10),d=parseInt((c-1)*woocommerce_admin_meta_boxes_variations.variations_per_page,10);a(".woocommerce_variations .woocommerce_variation").each(function(b,c){a(".variation_menu_order",c).val(parseInt(a(c).index(".woocommerce_variations .woocommerce_variation"),10)+1+d).change()})}},c={variable_image_frame:null,setting_variation_image_id:null,setting_variation_image:null,wp_media_post_id:wp.media.model.settings.post.id,init:function(){a("#variable_product_options").on("click",".upload_image_button",this.add_image),a("a.add_media").on("click",this.restore_wp_media_post_id)},add_image:function(b){var d=a(this),e=d.attr("rel"),f=d.closest(".upload_image");if(c.setting_variation_image=f,c.setting_variation_image_id=e,b.preventDefault(),d.is(".remove"))a(".upload_image_id",c.setting_variation_image).val("").change(),c.setting_variation_image.find("img").eq(0).attr("src",woocommerce_admin_meta_boxes_variations.woocommerce_placeholder_img_src),c.setting_variation_image.find(".upload_image_button").removeClass("remove");else{if(c.variable_image_frame)return c.variable_image_frame.uploader.uploader.param("post_id",c.setting_variation_image_id),void c.variable_image_frame.open();wp.media.model.settings.post.id=c.setting_variation_image_id,c.variable_image_frame=wp.media.frames.variable_image=wp.media({title:woocommerce_admin_meta_boxes_variations.i18n_choose_image,button:{text:woocommerce_admin_meta_boxes_variations.i18n_set_image},states:[new wp.media.controller.Library({title:woocommerce_admin_meta_boxes_variations.i18n_choose_image,filterable:"all"})]}),c.variable_image_frame.on("select",function(){var b=c.variable_image_frame.state().get("selection").first().toJSON(),d=b.sizes&&b.sizes.thumbnail?b.sizes.thumbnail.url:b.url;a(".upload_image_id",c.setting_variation_image).val(b.id).change(),c.setting_variation_image.find(".upload_image_button").addClass("remove"),c.setting_variation_image.find("img").eq(0).attr("src",d),wp.media.model.settings.post.id=c.wp_media_post_id}),c.variable_image_frame.open()}},restore_wp_media_post_id:function(){wp.media.model.settings.post.id=c.wp_media_post_id}},d={init:function(){a("li.variations_tab a").on("click",this.initial_load),a("#variable_product_options").on("click","button.save-variation-changes",this.save_variations).on("click","button.cancel-variation-changes",this.cancel_variations).on("click",".remove_variation",this.remove_variation),a(document.body).on("change","#variable_product_options .woocommerce_variations :input",this.input_changed).on("change",".variations-defaults select",this.defaults_changed),a("form#post").on("submit",this.save_on_submit),a(".wc-metaboxes-wrapper").on("click","a.do_variation_action",this.do_variation_action)},check_for_changes:function(){var b=a("#variable_product_options").find(".woocommerce_variations .variation-needs-update");if(0d&&0!==d&&(f=d),e.go_to_page(f,-1)})):d.unblock()}return!1},link_all_variations:function(){if(d.check_for_changes(),window.confirm(woocommerce_admin_meta_boxes_variations.i18n_link_all_variations)){d.block();var b={action:"woocommerce_link_all_variations",post_id:woocommerce_admin_meta_boxes_variations.post_id,security:woocommerce_admin_meta_boxes_variations.link_variation_nonce};a.post(woocommerce_admin_meta_boxes_variations.ajax_url,b,function(b){var c=parseInt(b,10);1===c?window.alert(c+" "+woocommerce_admin_meta_boxes_variations.i18n_variation_added):0===c||c>1?window.alert(c+" "+woocommerce_admin_meta_boxes_variations.i18n_variations_added):window.alert(woocommerce_admin_meta_boxes_variations.i18n_no_variations_added),c>0?(e.go_to_page(1,c),a("#variable_product_options").trigger("woocommerce_variations_added",c)):d.unblock()})}return!1},input_changed:function(){a(this).closest(".woocommerce_variation").addClass("variation-needs-update"),a("button.cancel-variation-changes, button.save-variation-changes").removeAttr("disabled"),a("#variable_product_options").trigger("woocommerce_variations_input_changed")},defaults_changed:function(){a(this).closest("#variable_product_options").find(".woocommerce_variation:first").addClass("variation-needs-update"),a("button.cancel-variation-changes, button.save-variation-changes").removeAttr("disabled"),a("#variable_product_options").trigger("woocommerce_variations_defaults_changed")},do_variation_action:function(){var b,c=a("select.variation_actions").val(),f={},g=0;switch(c){case"add_variation":return void d.add_variation();case"link_all_variations":return void d.link_all_variations();case"delete_all":window.confirm(woocommerce_admin_meta_boxes_variations.i18n_delete_all_variations)&&window.confirm(woocommerce_admin_meta_boxes_variations.i18n_last_warning)&&(f.allowed=!0,g=parseInt(a("#variable_product_options").find(".woocommerce_variations").attr("data-total"),10)*-1);break;case"variable_regular_price_increase":case"variable_regular_price_decrease":case"variable_sale_price_increase":case"variable_sale_price_decrease":b=window.prompt(woocommerce_admin_meta_boxes_variations.i18n_enter_a_value_fixed_or_percent),null!=b&&(b.indexOf("%")>=0?f.value=accounting.unformat(b.replace(/\%/,""),woocommerce_admin.mon_decimal_point)+"%":f.value=accounting.unformat(b,woocommerce_admin.mon_decimal_point));break;case"variable_regular_price":case"variable_sale_price":case"variable_stock":case"variable_weight":case"variable_length":case"variable_width":case"variable_height":case"variable_download_limit":case"variable_download_expiry":b=window.prompt(woocommerce_admin_meta_boxes_variations.i18n_enter_a_value),null!=b&&(f.value=b);break;case"variable_sale_schedule":f.date_from=window.prompt(woocommerce_admin_meta_boxes_variations.i18n_scheduled_sale_start),f.date_to=window.prompt(woocommerce_admin_meta_boxes_variations.i18n_scheduled_sale_end),null===f.date_from&&(f.date_from=!1),null===f.date_to&&(f.date_to=!1);break;default:a("select.variation_actions").trigger(c),f=a("select.variation_actions").triggerHandler(c+"_ajax_data",f)}"delete_all"===c&&f.allowed?a("#variable_product_options").find(".variation-needs-update").removeClass("variation-needs-update"):d.check_for_changes(),d.block(),a.ajax({url:woocommerce_admin_meta_boxes_variations.ajax_url,data:{action:"woocommerce_bulk_edit_variations",security:woocommerce_admin_meta_boxes_variations.bulk_edit_variations_nonce,product_id:woocommerce_admin_meta_boxes_variations.post_id,product_type:a("#product-type").val(),bulk_action:c,data:f},type:"POST",success:function(){e.go_to_page(1,g)}})}},e={init:function(){a(document.body).on("woocommerce_variations_added",this.update_single_quantity).on("change",".variations-pagenav .page-selector",this.page_selector).on("click",".variations-pagenav .first-page",this.first_page).on("click",".variations-pagenav .prev-page",this.prev_page).on("click",".variations-pagenav .next-page",this.next_page).on("click",".variations-pagenav .last-page",this.last_page)},update_variations_count:function(b){var c=a("#variable_product_options").find(".woocommerce_variations"),d=parseInt(c.attr("data-total"),10)+b,e=a(".variations-pagenav .displaying-num");return c.attr("data-total",d),1===d?e.text(woocommerce_admin_meta_boxes_variations.i18n_variation_count_single.replace("%qty%",d)):e.text(woocommerce_admin_meta_boxes_variations.i18n_variation_count_plural.replace("%qty%",d)),d},update_single_quantity:function(b,c){if(1===c){var d=a(".variations-pagenav");e.update_variations_count(c),d.is(":hidden")&&(a("option, optgroup",".variation_actions").show(),a(".variation_actions").val("add_variation"),a("#variable_product_options").find(".toolbar").show(),d.show(),a(".pagination-links",d).hide())}},set_paginav:function(b){var c=a("#variable_product_options").find(".woocommerce_variations"),d=e.update_variations_count(b),f=a("#variable_product_options").find(".toolbar"),g=a(".variation_actions"),h=a(".variations-pagenav"),i=a(".pagination-links",h),j=Math.ceil(d/woocommerce_admin_meta_boxes_variations.variations_per_page),k="";c.attr("data-total_pages",j),a(".total-pages",h).text(j);for(var l=1;l<=j;l++)k+='";a(".page-selector",h).empty().html(k),0===d?(f.not(".toolbar-top, .toolbar-buttons").hide(),h.hide(),a("option, optgroup",g).hide(),a(".variation_actions").val("add_variation"),a('option[data-global="true"]',g).show()):(f.show(),h.show(),a("option, optgroup",g).show(),a(".variation_actions").val("add_variation"),1===j?i.hide():i.show())},check_is_enabled:function(b){return!a(b).hasClass("disabled")},change_classes:function(b,c){var d=a(".variations-pagenav .first-page"),e=a(".variations-pagenav .prev-page"),f=a(".variations-pagenav .next-page"),g=a(".variations-pagenav .last-page");1===b?(d.addClass("disabled"),e.addClass("disabled")):(d.removeClass("disabled"),e.removeClass("disabled")),c===b?(f.addClass("disabled"),g.addClass("disabled")):(f.removeClass("disabled"),g.removeClass("disabled"))},set_page:function(b){a(".variations-pagenav .page-selector").val(b).first().change()},go_to_page:function(a,b){a=a||1,b=b||0,e.set_paginav(b),e.set_page(a)},page_selector:function(){var b=parseInt(a(this).val(),10),c=a("#variable_product_options").find(".woocommerce_variations");a(".variations-pagenav .page-selector").val(b),d.check_for_changes(),e.change_classes(b,parseInt(c.attr("data-total_pages"),10)),d.load_variations(b)},first_page:function(){return e.check_is_enabled(this)&&e.set_page(1),!1},prev_page:function(){if(e.check_is_enabled(this)){var b=a("#variable_product_options").find(".woocommerce_variations"),c=parseInt(b.attr("data-page"),10)-1,d=0=d?d:c;e.set_page(f)}return!1},last_page:function(){if(e.check_is_enabled(this)){var b=a("#variable_product_options").find(".woocommerce_variations").attr("data-total_pages");e.set_page(b)}return!1}};b.init(),c.init(),d.init(),e.init()}); \ No newline at end of file diff --git a/assets/js/admin/meta-boxes-product.min.js b/assets/js/admin/meta-boxes-product.min.js index d97e29431bf..839ffdf9bbd 100644 --- a/assets/js/admin/meta-boxes-product.min.js +++ b/assets/js/admin/meta-boxes-product.min.js @@ -1 +1 @@ -jQuery(function(a){function b(){var b=a("select#product-type").val(),c=a("input#_virtual:checked").length,d=a("input#_downloadable:checked").length,e=".hide_if_downloadable, .hide_if_virtual",f=".show_if_downloadable, .show_if_virtual";a.each(woocommerce_admin_meta_boxes.product_types,function(a,b){e=e+", .hide_if_"+b,f=f+", .show_if_"+b}),a(e).show(),a(f).hide(),d&&a(".show_if_downloadable").show(),c&&a(".show_if_virtual").show(),a(".show_if_"+b).show(),d&&a(".hide_if_downloadable").hide(),c&&a(".hide_if_virtual").hide(),a(".hide_if_"+b).hide(),a("input#_manage_stock").change(),a(".woocommerce_options_panel").each(function(){var b=a(this).children(".options_group");if(0!==b.length){var c=b.filter(function(){return"none"===a(this).css("display")});if(c.length===b.length){var d=a(this).prop("id");a(".product_data_tabs").find('li a[href="#'+d+'"]').parent().hide()}}})}function c(){a(".product_attributes .woocommerce_attribute").each(function(b,c){a(".attribute_position",c).val(parseInt(a(c).index(".product_attributes .woocommerce_attribute"),10))})}a(function(){a('[id$="-all"] > ul.categorychecklist').each(function(){var b=a(this),c=b.find(":checked").first();if(c.length){var d=b.find("input").position().top,e=c.position().top;b.closest(".tabs-panel").scrollTop(e-d+5)}})}),a("#upsell_product_data").bind("keypress",function(a){return 13===a.keyCode?!1:void 0}),a(".type_box").appendTo("#woocommerce-product-data .hndle span"),a(function(){a("#woocommerce-product-data").find(".hndle").unbind("click.postboxes"),a("#woocommerce-product-data").on("click",".hndle",function(b){a(b.target).filter("input, option, label, select").length||a("#woocommerce-product-data").toggleClass("closed")})}),a("#catalog-visibility").find(".edit-catalog-visibility").click(function(){return a("#catalog-visibility-select").is(":hidden")&&(a("#catalog-visibility-select").slideDown("fast"),a(this).hide()),!1}),a("#catalog-visibility").find(".save-post-visibility").click(function(){a("#catalog-visibility-select").slideUp("fast"),a("#catalog-visibility").find(".edit-catalog-visibility").show();var b=a("input[name=_visibility]:checked").attr("data-label");return a("input[name=_featured]").is(":checked")&&(b=b+", "+woocommerce_admin_meta_boxes.featured_label,a("input[name=_featured]").attr("checked","checked")),a("#catalog-visibility-display").text(b),!1}),a("#catalog-visibility").find(".cancel-post-visibility").click(function(){a("#catalog-visibility-select").slideUp("fast"),a("#catalog-visibility").find(".edit-catalog-visibility").show();var b=a("#current_visibility").val(),c=a("#current_featured").val();a("input[name=_visibility]").removeAttr("checked"),a("input[name=_visibility][value="+b+"]").attr("checked","checked");var d=a("input[name=_visibility]:checked").attr("data-label");return"yes"===c?(d=d+", "+woocommerce_admin_meta_boxes.featured_label,a("input[name=_featured]").attr("checked","checked")):a("input[name=_featured]").removeAttr("checked"),a("#catalog-visibility-display").text(d),!1}),a("select#product-type").change(function(){var c=a(this).val();"variable"===c?(a("input#_manage_stock").change(),a("input#_downloadable").prop("checked",!1),a("input#_virtual").removeAttr("checked")):"grouped"===c?(a("input#_downloadable").prop("checked",!1),a("input#_virtual").removeAttr("checked")):"external"===c&&(a("input#_downloadable").prop("checked",!1),a("input#_virtual").removeAttr("checked")),b(),a("ul.wc-tabs li:visible").eq(0).find("a").click(),a(document.body).trigger("woocommerce-product-type-change",c,a(this))}).change(),a(document.body).on("woocommerce-product-type-change",function(b,c){"variable"!==c&&0d?-1:d>e?1:0}),a(d).each(function(b,c){a(".product_attributes").append(c)}),a(".product_attributes .woocommerce_attribute").each(function(b,c){"none"!==a(c).css("display")&&a(c).is(".taxonomy")&&a("select.attribute_taxonomy").find('option[value="'+a(c).data("taxonomy")+'"]').attr("disabled","disabled")}),a("button.add_attribute").on("click",function(){var b=a(".product_attributes .woocommerce_attribute").length,d=a("select.attribute_taxonomy").val(),e=a(this).closest("#product_attributes"),f=e.find(".product_attributes"),g=a("select#product-type").val(),h={action:"woocommerce_add_attribute",taxonomy:d,i:b,security:woocommerce_admin_meta_boxes.add_attribute_nonce};return e.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),a.post(woocommerce_admin_meta_boxes.ajax_url,h,function(b){f.append(b),"variable"!==g&&f.find(".enable_variation").hide(),a(document.body).trigger("wc-enhanced-select-init"),c(),e.unblock(),a(document.body).trigger("woocommerce_added_attribute")}),d&&(a("select.attribute_taxonomy").find('option[value="'+d+'"]').attr("disabled","disabled"),a("select.attribute_taxonomy").val("")),!1}),a(".product_attributes").on("blur","input.attribute_name",function(){a(this).closest(".woocommerce_attribute").find("strong.attribute_name").text(a(this).val())}),a(".product_attributes").on("click","button.select_all_attributes",function(){return a(this).closest("td").find("select option").attr("selected","selected"),a(this).closest("td").find("select").change(),!1}),a(".product_attributes").on("click","button.select_no_attributes",function(){return a(this).closest("td").find("select option").removeAttr("selected"),a(this).closest("td").find("select").change(),!1}),a(".product_attributes").on("click",".remove_row",function(){if(window.confirm(woocommerce_admin_meta_boxes.remove_attribute)){var b=a(this).parent().parent();b.is(".taxonomy")?(b.find("select, input[type=text]").val(""),b.hide(),a("select.attribute_taxonomy").find('option[value="'+b.data("taxonomy")+'"]').removeAttr("disabled")):(b.find("select, input[type=text]").val(""),b.hide(),c())}return!1}),a(".product_attributes").sortable({items:".woocommerce_attribute",cursor:"move",axis:"y",handle:"h3",scrollSensitivity:40,forcePlaceholderSize:!0,helper:"clone",opacity:.65,placeholder:"wc-metabox-sortable-placeholder",start:function(a,b){b.item.css("background-color","#f6f6f6")},stop:function(a,b){b.item.removeAttr("style"),c()}}),a(".product_attributes").on("click","button.add_new_attribute",function(){a(".product_attributes").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var b=a(this).closest(".woocommerce_attribute"),c=b.data("taxonomy"),d=window.prompt(woocommerce_admin_meta_boxes.new_attribute_prompt);if(d){var e={action:"woocommerce_add_new_attribute",taxonomy:c,term:d,security:woocommerce_admin_meta_boxes.add_attribute_nonce};a.post(woocommerce_admin_meta_boxes.ajax_url,e,function(c){c.error?window.alert(c.error):c.slug&&(b.find("select.attribute_values").append('"),b.find("select.attribute_values").change()),a(".product_attributes").unblock()})}else a(".product_attributes").unblock();return!1}),a(".save_attributes").on("click",function(){a("#woocommerce-product-data").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var b={post_id:woocommerce_admin_meta_boxes.post_id,data:a(".product_attributes").find("input, select, textarea").serialize(),action:"woocommerce_save_attributes",security:woocommerce_admin_meta_boxes.save_attributes_nonce};a.post(woocommerce_admin_meta_boxes.ajax_url,b,function(){var b=window.location.toString();b=b.replace("post-new.php?","post.php?post="+woocommerce_admin_meta_boxes.post_id+"&action=edit&"),a("#variable_product_options").load(b+" #variable_product_options_inner",function(){a("#variable_product_options").trigger("reload")})})});var e,f;a(document.body).on("click",".upload_file_button",function(b){var c=a(this);if(f=c.closest("tr").find("td.file_url input"),b.preventDefault(),e)return void e.open();var d=[new wp.media.controller.Library({library:wp.media.query(),multiple:!0,title:c.data("choose"),priority:20,filterable:"uploaded"})];e=wp.media.frames.downloadable_file=wp.media({title:c.data("choose"),library:{type:""},button:{text:c.data("update")},multiple:!0,states:d}),e.on("select",function(){var a="",b=e.state().get("selection");b.map(function(b){b=b.toJSON(),b.url&&(a=b.url)}),f.val(a).change()}),e.on("ready",function(){e.uploader.options.uploader.params={type:"downloadable_product"}}),e.open()}),a(".downloadable_files tbody").sortable({items:"tr",cursor:"move",axis:"y",handle:"td.sort",scrollSensitivity:40,forcePlaceholderSize:!0,helper:"clone",opacity:.65});var g,h=a("#product_image_gallery"),i=a("#product_images_container").find("ul.product_images");a(".add_product_images").on("click","a",function(b){var c=a(this);return b.preventDefault(),g?void g.open():(g=wp.media.frames.product_gallery=wp.media({title:c.data("choose"),button:{text:c.data("update")},states:[new wp.media.controller.Library({title:c.data("choose"),filterable:"all",multiple:!0})]}),g.on("select",function(){var a=g.state().get("selection"),b=h.val();a.map(function(a){if(a=a.toJSON(),a.id){b=b?b+","+a.id:a.id;var d=a.sizes&&a.sizes.thumbnail?a.sizes.thumbnail.url:a.url;i.append('
  • ")}}),h.val(b)}),void g.open())}),i.sortable({items:"li.image",cursor:"move",scrollSensitivity:40,forcePlaceholderSize:!0,forceHelperSize:!1,helper:"clone",opacity:.65,placeholder:"wc-metabox-sortable-placeholder",start:function(a,b){b.item.css("background-color","#f6f6f6")},stop:function(a,b){b.item.removeAttr("style")},update:function(){var b="";a("#product_images_container").find("ul li.image").css("cursor","default").each(function(){var c=a(this).attr("data-attachment_id");b=b+c+","}),h.val(b)}}),a("#product_images_container").on("click","a.delete",function(){a(this).closest("li.image").remove();var b="";return a("#product_images_container").find("ul li.image").css("cursor","default").each(function(){var c=a(this).attr("data-attachment_id");b=b+c+","}),h.val(b),a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),!1})}); \ No newline at end of file +jQuery(function(a){function b(){var b=a("select#product-type").val(),c=a("input#_virtual:checked").length,d=a("input#_downloadable:checked").length,e=".hide_if_downloadable, .hide_if_virtual",f=".show_if_downloadable, .show_if_virtual";a.each(woocommerce_admin_meta_boxes.product_types,function(a,b){e=e+", .hide_if_"+b,f=f+", .show_if_"+b}),a(e).show(),a(f).hide(),d&&a(".show_if_downloadable").show(),c&&a(".show_if_virtual").show(),a(".show_if_"+b).show(),d&&a(".hide_if_downloadable").hide(),c&&a(".hide_if_virtual").hide(),a(".hide_if_"+b).hide(),a("input#_manage_stock").change(),a(".woocommerce_options_panel").each(function(){var b=a(this).children(".options_group");if(0!==b.length){var c=b.filter(function(){return"none"===a(this).css("display")});if(c.length===b.length){var d=a(this).prop("id");a(".product_data_tabs").find('li a[href="#'+d+'"]').parent().hide()}}})}function c(){a(".product_attributes .woocommerce_attribute").each(function(b,c){a(".attribute_position",c).val(parseInt(a(c).index(".product_attributes .woocommerce_attribute"),10))})}a(function(){a('[id$="-all"] > ul.categorychecklist').each(function(){var b=a(this),c=b.find(":checked").first();if(c.length){var d=b.find("input").position().top,e=c.position().top;b.closest(".tabs-panel").scrollTop(e-d+5)}})}),a("#upsell_product_data").bind("keypress",function(a){if(13===a.keyCode)return!1}),a(".type_box").appendTo("#woocommerce-product-data .hndle span"),a(function(){a("#woocommerce-product-data").find(".hndle").unbind("click.postboxes"),a("#woocommerce-product-data").on("click",".hndle",function(b){a(b.target).filter("input, option, label, select").length||a("#woocommerce-product-data").toggleClass("closed")})}),a("#catalog-visibility").find(".edit-catalog-visibility").click(function(){return a("#catalog-visibility-select").is(":hidden")&&(a("#catalog-visibility-select").slideDown("fast"),a(this).hide()),!1}),a("#catalog-visibility").find(".save-post-visibility").click(function(){a("#catalog-visibility-select").slideUp("fast"),a("#catalog-visibility").find(".edit-catalog-visibility").show();var b=a("input[name=_visibility]:checked").attr("data-label");return a("input[name=_featured]").is(":checked")&&(b=b+", "+woocommerce_admin_meta_boxes.featured_label,a("input[name=_featured]").attr("checked","checked")),a("#catalog-visibility-display").text(b),!1}),a("#catalog-visibility").find(".cancel-post-visibility").click(function(){a("#catalog-visibility-select").slideUp("fast"),a("#catalog-visibility").find(".edit-catalog-visibility").show();var b=a("#current_visibility").val(),c=a("#current_featured").val();a("input[name=_visibility]").removeAttr("checked"),a("input[name=_visibility][value="+b+"]").attr("checked","checked");var d=a("input[name=_visibility]:checked").attr("data-label");return"yes"===c?(d=d+", "+woocommerce_admin_meta_boxes.featured_label,a("input[name=_featured]").attr("checked","checked")):a("input[name=_featured]").removeAttr("checked"),a("#catalog-visibility-display").text(d),!1}),a("select#product-type").change(function(){var c=a(this).val();"variable"===c?(a("input#_manage_stock").change(),a("input#_downloadable").prop("checked",!1),a("input#_virtual").removeAttr("checked")):"grouped"===c?(a("input#_downloadable").prop("checked",!1),a("input#_virtual").removeAttr("checked")):"external"===c&&(a("input#_downloadable").prop("checked",!1),a("input#_virtual").removeAttr("checked")),b(),a("ul.wc-tabs li:visible").eq(0).find("a").click(),a(document.body).trigger("woocommerce-product-type-change",c,a(this))}).change(),a(document.body).on("woocommerce-product-type-change",function(b,c){"variable"!==c&&0e?1:0}),a(d).each(function(b,c){a(".product_attributes").append(c)}),a(".product_attributes .woocommerce_attribute").each(function(b,c){"none"!==a(c).css("display")&&a(c).is(".taxonomy")&&a("select.attribute_taxonomy").find('option[value="'+a(c).data("taxonomy")+'"]').attr("disabled","disabled")}),a("button.add_attribute").on("click",function(){var b=a(".product_attributes .woocommerce_attribute").length,d=a("select.attribute_taxonomy").val(),e=a(this).closest("#product_attributes"),f=e.find(".product_attributes"),g=a("select#product-type").val(),h={action:"woocommerce_add_attribute",taxonomy:d,i:b,security:woocommerce_admin_meta_boxes.add_attribute_nonce};return e.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),a.post(woocommerce_admin_meta_boxes.ajax_url,h,function(b){f.append(b),"variable"!==g&&f.find(".enable_variation").hide(),a(document.body).trigger("wc-enhanced-select-init"),c(),e.unblock(),a(document.body).trigger("woocommerce_added_attribute")}),d&&(a("select.attribute_taxonomy").find('option[value="'+d+'"]').attr("disabled","disabled"),a("select.attribute_taxonomy").val("")),!1}),a(".product_attributes").on("blur","input.attribute_name",function(){a(this).closest(".woocommerce_attribute").find("strong.attribute_name").text(a(this).val())}),a(".product_attributes").on("click","button.select_all_attributes",function(){return a(this).closest("td").find("select option").attr("selected","selected"),a(this).closest("td").find("select").change(),!1}),a(".product_attributes").on("click","button.select_no_attributes",function(){return a(this).closest("td").find("select option").removeAttr("selected"),a(this).closest("td").find("select").change(),!1}),a(".product_attributes").on("click",".remove_row",function(){if(window.confirm(woocommerce_admin_meta_boxes.remove_attribute)){var b=a(this).parent().parent();b.is(".taxonomy")?(b.find("select, input[type=text]").val(""),b.hide(),a("select.attribute_taxonomy").find('option[value="'+b.data("taxonomy")+'"]').removeAttr("disabled")):(b.find("select, input[type=text]").val(""),b.hide(),c())}return!1}),a(".product_attributes").sortable({items:".woocommerce_attribute",cursor:"move",axis:"y",handle:"h3",scrollSensitivity:40,forcePlaceholderSize:!0,helper:"clone",opacity:.65,placeholder:"wc-metabox-sortable-placeholder",start:function(a,b){b.item.css("background-color","#f6f6f6")},stop:function(a,b){b.item.removeAttr("style"),c()}}),a(".product_attributes").on("click","button.add_new_attribute",function(){a(".product_attributes").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var b=a(this).closest(".woocommerce_attribute"),c=b.data("taxonomy"),d=window.prompt(woocommerce_admin_meta_boxes.new_attribute_prompt);if(d){var e={action:"woocommerce_add_new_attribute",taxonomy:c,term:d,security:woocommerce_admin_meta_boxes.add_attribute_nonce};a.post(woocommerce_admin_meta_boxes.ajax_url,e,function(c){c.error?window.alert(c.error):c.slug&&(b.find("select.attribute_values").append('"),b.find("select.attribute_values").change()),a(".product_attributes").unblock()})}else a(".product_attributes").unblock();return!1}),a(".save_attributes").on("click",function(){a("#woocommerce-product-data").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var b={post_id:woocommerce_admin_meta_boxes.post_id,data:a(".product_attributes").find("input, select, textarea").serialize(),action:"woocommerce_save_attributes",security:woocommerce_admin_meta_boxes.save_attributes_nonce};a.post(woocommerce_admin_meta_boxes.ajax_url,b,function(){var b=window.location.toString();b=b.replace("post-new.php?","post.php?post="+woocommerce_admin_meta_boxes.post_id+"&action=edit&"),a("#variable_product_options").load(b+" #variable_product_options_inner",function(){a("#variable_product_options").trigger("reload")})})});var e,f;a(document.body).on("click",".upload_file_button",function(b){var c=a(this);if(f=c.closest("tr").find("td.file_url input"),b.preventDefault(),e)return void e.open();var d=[new wp.media.controller.Library({library:wp.media.query(),multiple:!0,title:c.data("choose"),priority:20,filterable:"uploaded"})];e=wp.media.frames.downloadable_file=wp.media({title:c.data("choose"),library:{type:""},button:{text:c.data("update")},multiple:!0,states:d}),e.on("select",function(){var a="",b=e.state().get("selection");b.map(function(b){b=b.toJSON(),b.url&&(a=b.url)}),f.val(a).change()}),e.on("ready",function(){e.uploader.options.uploader.params={type:"downloadable_product"}}),e.open()}),a(".downloadable_files tbody").sortable({items:"tr",cursor:"move",axis:"y",handle:"td.sort",scrollSensitivity:40,forcePlaceholderSize:!0,helper:"clone",opacity:.65});var g,h=a("#product_image_gallery"),i=a("#product_images_container").find("ul.product_images");a(".add_product_images").on("click","a",function(b){var c=a(this);return b.preventDefault(),g?void g.open():(g=wp.media.frames.product_gallery=wp.media({title:c.data("choose"),button:{text:c.data("update")},states:[new wp.media.controller.Library({title:c.data("choose"),filterable:"all",multiple:!0})]}),g.on("select",function(){var a=g.state().get("selection"),b=h.val();a.map(function(a){if(a=a.toJSON(),a.id){b=b?b+","+a.id:a.id;var d=a.sizes&&a.sizes.thumbnail?a.sizes.thumbnail.url:a.url;i.append('
  • ")}}),h.val(b)}),void g.open())}),i.sortable({items:"li.image",cursor:"move",scrollSensitivity:40,forcePlaceholderSize:!0,forceHelperSize:!1,helper:"clone",opacity:.65,placeholder:"wc-metabox-sortable-placeholder",start:function(a,b){b.item.css("background-color","#f6f6f6")},stop:function(a,b){b.item.removeAttr("style")},update:function(){var b="";a("#product_images_container").find("ul li.image").css("cursor","default").each(function(){var c=a(this).attr("data-attachment_id");b=b+c+","}),h.val(b)}}),a("#product_images_container").on("click","a.delete",function(){a(this).closest("li.image").remove();var b="";return a("#product_images_container").find("ul li.image").css("cursor","default").each(function(){var c=a(this).attr("data-attachment_id");b=b+c+","}),h.val(b),a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),!1})}); \ No newline at end of file diff --git a/assets/js/admin/meta-boxes.min.js b/assets/js/admin/meta-boxes.min.js index 2c8b16c9a51..69d1ef2aa6e 100644 --- a/assets/js/admin/meta-boxes.min.js +++ b/assets/js/admin/meta-boxes.min.js @@ -1 +1 @@ -jQuery(function(a){function b(){a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200})}b(),a("#titlediv").find("#title").keyup(function(b){var c=b.keyCode||b.which;return"9"===c&&a("#woocommerce-coupon-description").length>0?(b.stopPropagation(),a("#woocommerce-coupon-description").focus(),!1):void 0}),a(".wc-metaboxes-wrapper").on("click",".wc-metabox > h3",function(){a(this).parent(".wc-metabox").toggleClass("closed").toggleClass("open")}),a(document.body).on("wc-init-tabbed-panels",function(){a("ul.wc-tabs").show(),a("ul.wc-tabs a").click(function(b){b.preventDefault();var c=a(this).closest("div.panel-wrap");a("ul.wc-tabs li",c).removeClass("active"),a(this).parent().addClass("active"),a("div.panel",c).hide(),a(a(this).attr("href")).show()}),a("div.panel-wrap").each(function(){a(this).find("ul.wc-tabs li").eq(0).find("a").click()})}).trigger("wc-init-tabbed-panels"),a(document.body).on("wc-init-datepickers",function(){a(".date-picker-field, .date-picker").datepicker({dateFormat:"yy-mm-dd",numberOfMonths:1,showButtonPanel:!0})}).trigger("wc-init-datepickers"),a(".wc-metaboxes-wrapper").on("click",".wc-metabox h3",function(b){a(b.target).filter(":input, option, .sort").length||a(this).next(".wc-metabox-content").stop().slideToggle()}).on("click",".expand_all",function(){return a(this).closest(".wc-metaboxes-wrapper").find(".wc-metabox > .wc-metabox-content").show(),!1}).on("click",".close_all",function(){return a(this).closest(".wc-metaboxes-wrapper").find(".wc-metabox > .wc-metabox-content").hide(),!1}),a(".wc-metabox.closed").each(function(){a(this).find(".wc-metabox-content").hide()})}); \ No newline at end of file +jQuery(function(a){function b(){a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200})}b(),a("#titlediv").find("#title").keyup(function(b){var c=b.keyCode||b.which;if("9"===c&&a("#woocommerce-coupon-description").length>0)return b.stopPropagation(),a("#woocommerce-coupon-description").focus(),!1}),a(".wc-metaboxes-wrapper").on("click",".wc-metabox > h3",function(){a(this).parent(".wc-metabox").toggleClass("closed").toggleClass("open")}),a(document.body).on("wc-init-tabbed-panels",function(){a("ul.wc-tabs").show(),a("ul.wc-tabs a").click(function(b){b.preventDefault();var c=a(this).closest("div.panel-wrap");a("ul.wc-tabs li",c).removeClass("active"),a(this).parent().addClass("active"),a("div.panel",c).hide(),a(a(this).attr("href")).show()}),a("div.panel-wrap").each(function(){a(this).find("ul.wc-tabs li").eq(0).find("a").click()})}).trigger("wc-init-tabbed-panels"),a(document.body).on("wc-init-datepickers",function(){a(".date-picker-field, .date-picker").datepicker({dateFormat:"yy-mm-dd",numberOfMonths:1,showButtonPanel:!0})}).trigger("wc-init-datepickers"),a(".wc-metaboxes-wrapper").on("click",".wc-metabox h3",function(b){a(b.target).filter(":input, option, .sort").length||a(this).next(".wc-metabox-content").stop().slideToggle()}).on("click",".expand_all",function(){return a(this).closest(".wc-metaboxes-wrapper").find(".wc-metabox > .wc-metabox-content").show(),!1}).on("click",".close_all",function(){return a(this).closest(".wc-metaboxes-wrapper").find(".wc-metabox > .wc-metabox-content").hide(),!1}),a(".wc-metabox.closed").each(function(){a(this).find(".wc-metabox-content").hide()})}); \ No newline at end of file diff --git a/assets/js/admin/reports.min.js b/assets/js/admin/reports.min.js index 0e239a9e3ca..511913e1bce 100644 --- a/assets/js/admin/reports.min.js +++ b/assets/js/admin/reports.min.js @@ -1 +1 @@ -jQuery(function(a){function b(b,c,d){a('
    '+d+"
    ").css({top:c-16,left:b+20}).appendTo("body").fadeIn(200)}var c=null,d=null;a(".chart-placeholder").bind("plothover",function(e,f,g){if(g){if((c!==g.dataIndex||d!==g.seriesIndex)&&(c=g.dataIndex,d=g.seriesIndex,a(".chart-tooltip").remove(),g.series.points.show||g.series.enable_tooltip)){var h=g.series.data[g.dataIndex][1],i="";g.series.prepend_label&&(i=i+g.series.label+": "),g.series.prepend_tooltip&&(i+=g.series.prepend_tooltip),i+=h,g.series.append_tooltip&&(i+=g.series.append_tooltip),g.series.pie.show?b(f.pageX,f.pageY,i):b(g.pageX,g.pageY,i)}}else a(".chart-tooltip").remove(),c=null}),a(".wc_sparkline.bars").each(function(){var b=a(this).data("sparkline"),c={grid:{show:!1}},d=[{data:b,color:a(this).data("color"),bars:{fillColor:a(this).data("color"),fill:!0,show:!0,lineWidth:1,barWidth:a(this).data("barwidth"),align:"center"},shadowSize:0}];a.plot(a(this),d,c)}),a(".wc_sparkline.lines").each(function(){var b=a(this).data("sparkline"),c={grid:{show:!1}},d=[{data:b,color:a(this).data("color"),lines:{fill:!1,show:!0,lineWidth:1,align:"center"},shadowSize:0}];a.plot(a(this),d,c)});var e=a(".range_datepicker").datepicker({changeMonth:!0,changeYear:!0,defaultDate:"",dateFormat:"yy-mm-dd",numberOfMonths:1,maxDate:"+0D",showButtonPanel:!0,showOn:"focus",buttonImageOnly:!0,onSelect:function(b){var c=a(this).is(".from")?"minDate":"maxDate",d=a(this).data("datepicker"),f=a.datepicker.parseDate(d.settings.dateFormat||a.datepicker._defaults.dateFormat,b,d.settings);e.not(this).datepicker("option",c,f)}}),f=document.createElement("a");"undefined"==typeof f.download&&a(".export_csv").hide(),a(".export_csv").click(function(){var b=a(this).data("exclude_series")||"";b=b.toString(),b=b.split(",");var c,d,e,f=a(this).data("xaxes"),g=a(this).data("groupby"),h=a(this).data("export"),i="data:application/csv;charset=utf-8,";if("table"===h)a(this).offsetParent().find("thead tr,tbody tr").each(function(){a(this).find("th, td").each(function(){var b=a(this).text();b=b.replace("[?]",""),i+='"'+b+'",'}),i=i.substring(0,i.length-1),i+="\n"}),a(this).offsetParent().find("tfoot tr").each(function(){a(this).find("th, td").each(function(){var b=a(this).text();if(b=b.replace("[?]",""),i+='"'+b+'",',a(this).attr("colspan")>0)for(m=1;m'+d+"").css({top:c-16,left:b+20}).appendTo("body").fadeIn(200)}var c=null,d=null;a(".chart-placeholder").bind("plothover",function(e,f,g){if(g){if((c!==g.dataIndex||d!==g.seriesIndex)&&(c=g.dataIndex,d=g.seriesIndex,a(".chart-tooltip").remove(),g.series.points.show||g.series.enable_tooltip)){var h=g.series.data[g.dataIndex][1],i="";g.series.prepend_label&&(i=i+g.series.label+": "),g.series.prepend_tooltip&&(i+=g.series.prepend_tooltip),i+=h,g.series.append_tooltip&&(i+=g.series.append_tooltip),g.series.pie.show?b(f.pageX,f.pageY,i):b(g.pageX,g.pageY,i)}}else a(".chart-tooltip").remove(),c=null}),a(".wc_sparkline.bars").each(function(){var b=a(this).data("sparkline"),c={grid:{show:!1}},d=[{data:b,color:a(this).data("color"),bars:{fillColor:a(this).data("color"),fill:!0,show:!0,lineWidth:1,barWidth:a(this).data("barwidth"),align:"center"},shadowSize:0}];a.plot(a(this),d,c)}),a(".wc_sparkline.lines").each(function(){var b=a(this).data("sparkline"),c={grid:{show:!1}},d=[{data:b,color:a(this).data("color"),lines:{fill:!1,show:!0,lineWidth:1,align:"center"},shadowSize:0}];a.plot(a(this),d,c)});var e=a(".range_datepicker").datepicker({changeMonth:!0,changeYear:!0,defaultDate:"",dateFormat:"yy-mm-dd",numberOfMonths:1,maxDate:"+0D",showButtonPanel:!0,showOn:"focus",buttonImageOnly:!0,onSelect:function(b){var c=a(this).is(".from")?"minDate":"maxDate",d=a(this).data("datepicker"),f=a.datepicker.parseDate(d.settings.dateFormat||a.datepicker._defaults.dateFormat,b,d.settings);e.not(this).datepicker("option",c,f)}}),f=document.createElement("a");"undefined"==typeof f.download&&a(".export_csv").hide(),a(".export_csv").click(function(){var b=a(this).data("exclude_series")||"";b=b.toString(),b=b.split(",");var c,d,e,f=a(this).data("xaxes"),g=a(this).data("groupby"),h=a(this).data("export"),i="data:application/csv;charset=utf-8,";if("table"===h)a(this).offsetParent().find("thead tr,tbody tr").each(function(){a(this).find("th, td").each(function(){var b=a(this).text();b=b.replace("[?]",""),i+='"'+b+'",'}),i=i.substring(0,i.length-1),i+="\n"}),a(this).offsetParent().find("tfoot tr").each(function(){a(this).find("th, td").each(function(){var b=a(this).text();if(b=b.replace("[?]",""),i+='"'+b+'",',a(this).attr("colspan")>0)for(m=1;m0?"&":"?")+"action=woocommerce_tax_rates_save_changes",data:{current_class:b.current_class,wc_tax_nonce:b.wc_tax_nonce,changes:a.changes},success:function(b,c){"success"===c&&(p.set("rates",b.data.rates),p.trigger("change:rates"),p.changes={},p.trigger("saved:rates"),q.render()),a.unblock()}})}}),o=Backbone.View.extend({rowTemplate:e,per_page:b.limit,page:b.page,initialize:function(){var c=Math.ceil(_.toArray(this.model.get("rates")).length/this.per_page);this.qty_pages=0===c?1:c,this.page=this.sanitizePage(b.page),this.listenTo(this.model,"change:rates",this.setUnloadConfirmation),this.listenTo(this.model,"saved:rates",this.clearUnloadConfirmation),i.on("change autocompletechange",":input",{view:this},this.updateModelOnChange),i.on("sortupdate",{view:this},this.updateModelOnSort),l.on("keyup search",{view:this},this.onSearchField),k.on("click","a",{view:this},this.onPageChange),k.on("change","input",{view:this},this.onPageChange),a(window).on("beforeunload",{view:this},this.unloadConfirmation),m.on("click",{view:this},this.onSubmit),j.attr("disabled","disabled"),h.find(".insert").on("click",{view:this},this.onAddNewRow),h.find(".remove_tax_rates").on("click",{view:this},this.onDeleteRow),h.find(".export").on("click",{view:this},this.onExport)},render:function(){var c=this.model.getFilteredRates(),d=_.size(c),e=Math.ceil(d/this.per_page),h=0===d?0:this.per_page*(this.page-1),j=this.per_page*this.page,m=_.toArray(c).slice(h,j),n=this;this.$el.empty(),m.length?a.each(m,function(a,b){n.$el.append(n.rowTemplate(b))}):n.$el.append(f()),this.$el.find("td.country input").autocomplete({source:b.countries,minLength:2}),this.$el.find("td.state input").autocomplete({source:b.states,minLength:3}),this.$el.find("td.postcode input, td.city input").change(function(){a(this).attr("name",a(this).data("name"))}),e>1?k.html(g({qty_rates:d,current_page:this.page,qty_pages:e})):(k.empty(),n.page=1),l.val()?i.sortable("disable"):i.sortable("enable")},updateUrl:function(){if(window.history.replaceState){var a=b.base_url,c=l.val();1e}),g=_.map(f,function(a){return a.tax_rate_order++,l[a.tax_rate_id]=_.extend(l[a.tax_rate_id]||{},{tax_rate_order:a.tax_rate_order}),a})):(n.tax_rate_order=1+_.max(_.pluck(k,"tax_rate_order"),function(a){return parseInt(a,10)}),h.page=h.qty_pages),k[n.tax_rate_id]=n,l[n.tax_rate_id]=n,j.set("rates",k),j.logChanges(l),h.render()},onDeleteRow:function(c){var d,e,f=c.data.view,g=f.model,h=_.indexBy(g.get("rates"),"tax_rate_id"),j={};c.preventDefault(),(d=i.children(".current"))?(d.each(function(){e=a(this).data("id"),delete h[e],j[e]=_.extend(j[e]||{},{deleted:"deleted"})}),g.set("rates",h),g.logChanges(j),f.render()):window.alert(b.strings.no_rows_selected)},onSearchField:function(a){a.data.view.updateUrl(),a.data.view.render()},onPageChange:function(b){var c=a(b.currentTarget);b.preventDefault(),b.data.view.page=c.data("goto")?c.data("goto"):c.val(),b.data.view.render(),b.data.view.updateUrl()},onExport:function(c){var d="data:application/csv;charset=utf-8,"+b.strings.csv_data_cols.join(",")+"\n";return a.each(c.data.view.model.getFilteredRates(),function(a,c){var e="";e+=c.tax_rate_country+",",e+=c.tax_rate_state+",",e+=(c.postcode?c.postcode.join("; "):"")+",",e+=(c.city?c.city.join("; "):"")+",",e+=c.tax_rate+",",e+=c.tax_rate_name+",",e+=c.tax_rate_priority+",",e+=c.tax_rate_compound+",",e+=c.tax_rate_shipping+",",e+=b.current_class,d+=e+"\n"}),a(this).attr("href",encodeURI(d)),!0},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,j.removeAttr("disabled")},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,j.attr("disabled","disabled")},unloadConfirmation:function(a){return a.data.view.needsUnloadConfirm?(a.returnValue=b.strings.unload_confirmation_msg,window.event.returnValue=b.strings.unload_confirmation_msg,b.strings.unload_confirmation_msg):void 0},updateModelOnChange:function(b){var c=b.data.view.model,d=a(b.target),e=d.closest("tr").data("id"),f=d.data("attribute"),g=d.val();"city"!==f&&"postcode"!==f||(g=g.split(";"),g=a.map(g,function(a){return a.trim()})),"tax_rate_compound"!==f&&"tax_rate_shipping"!==f||(g=d.is(":checked")?1:0),c.setRateAttribute(e,f,g)},updateModelOnSort:function(a){var b=a.data.view,c=b.model,d=_.indexBy(c.get("rates"),"tax_rate_id"),e={};_.each(d,function(a){var c=0,d=parseInt(a.tax_rate_order,10);c=h.find('tr[data-id="'+a.tax_rate_id+'"]').length?parseInt(h.find('tr[data-id="'+a.tax_rate_id+'"]').index(),10)+parseInt((b.page-1)*b.per_page,10):d,d!==c&&(e[a.tax_rate_id]=_.extend(e[a.tax_rate_id]||{},{tax_rate_order:c}))}),_.size(e)&&c.logChanges(e)},sanitizePage:function(a){return a=parseInt(a,10),1>a?a=1:a>this.qty_pages&&(a=this.qty_pages),a}}),p=new n({rates:b.rates}),q=new o({model:p,el:"#rates"});q.render()})}(jQuery,htmlSettingsTaxLocalizeScript,wp,ajaxurl); \ No newline at end of file +!function(a,b,c,d){a(function(){String.prototype.trim||(String.prototype.trim=function(){return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")});var e=c.template("wc-tax-table-row"),f=c.template("wc-tax-table-row-empty"),g=c.template("wc-tax-table-pagination"),h=a(".wc_tax_rates"),i=a("#rates"),j=a('input[name="save"]'),k=a("#rates-pagination"),l=a("#rates-search .wc-tax-rates-search-field"),m=a(".submit .button-primary[type=submit]"),n=Backbone.Model.extend({changes:{},setRateAttribute:function(a,b,c){var d=_.indexBy(this.get("rates"),"tax_rate_id"),e={};d[a][b]!==c&&(e[a]={},e[a][b]=c,d[a][b]=c),this.logChanges(e)},logChanges:function(a){var b=this.changes||{};_.each(a,function(a,c){b[c]=_.extend(b[c]||{tax_rate_id:c},a)}),this.changes=b,this.trigger("change:rates")},getFilteredRates:function(){var a=this.get("rates"),b=l.val().toLowerCase();return b.length&&(a=_.filter(a,function(a){var c=_.toArray(a).join(" ").toLowerCase();return-1!==c.indexOf(b)})),a=_.sortBy(a,function(a){return parseInt(a.tax_rate_order,10)})},block:function(){a(".wc_tax_rates").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a(".wc_tax_rates").unblock()},save:function(){var a=this;a.block(),Backbone.ajax({method:"POST",dataType:"json",url:d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_tax_rates_save_changes",data:{current_class:b.current_class,wc_tax_nonce:b.wc_tax_nonce,changes:a.changes},success:function(b,c){"success"===c&&(p.set("rates",b.data.rates),p.trigger("change:rates"),p.changes={},p.trigger("saved:rates"),q.render()),a.unblock()}})}}),o=Backbone.View.extend({rowTemplate:e,per_page:b.limit,page:b.page,initialize:function(){var c=Math.ceil(_.toArray(this.model.get("rates")).length/this.per_page);this.qty_pages=0===c?1:c,this.page=this.sanitizePage(b.page),this.listenTo(this.model,"change:rates",this.setUnloadConfirmation),this.listenTo(this.model,"saved:rates",this.clearUnloadConfirmation),i.on("change autocompletechange",":input",{view:this},this.updateModelOnChange),i.on("sortupdate",{view:this},this.updateModelOnSort),l.on("keyup search",{view:this},this.onSearchField),k.on("click","a",{view:this},this.onPageChange),k.on("change","input",{view:this},this.onPageChange),a(window).on("beforeunload",{view:this},this.unloadConfirmation),m.on("click",{view:this},this.onSubmit),j.attr("disabled","disabled"),h.find(".insert").on("click",{view:this},this.onAddNewRow),h.find(".remove_tax_rates").on("click",{view:this},this.onDeleteRow),h.find(".export").on("click",{view:this},this.onExport)},render:function(){var c=this.model.getFilteredRates(),d=_.size(c),e=Math.ceil(d/this.per_page),h=0===d?0:this.per_page*(this.page-1),j=this.per_page*this.page,m=_.toArray(c).slice(h,j),n=this;this.$el.empty(),m.length?a.each(m,function(a,b){n.$el.append(n.rowTemplate(b))}):n.$el.append(f()),this.$el.find("td.country input").autocomplete({source:b.countries,minLength:2}),this.$el.find("td.state input").autocomplete({source:b.states,minLength:3}),this.$el.find("td.postcode input, td.city input").change(function(){a(this).attr("name",a(this).data("name"))}),e>1?k.html(g({qty_rates:d,current_page:this.page,qty_pages:e})):(k.empty(),n.page=1),l.val()?i.sortable("disable"):i.sortable("enable")},updateUrl:function(){if(window.history.replaceState){var a=b.base_url,c=l.val();1e}),g=_.map(f,function(a){return a.tax_rate_order++,l[a.tax_rate_id]=_.extend(l[a.tax_rate_id]||{},{tax_rate_order:a.tax_rate_order}),a})):(n.tax_rate_order=1+_.max(_.pluck(k,"tax_rate_order"),function(a){return parseInt(a,10)}),h.page=h.qty_pages),k[n.tax_rate_id]=n,l[n.tax_rate_id]=n,j.set("rates",k),j.logChanges(l),h.render()},onDeleteRow:function(c){var d,e,f=c.data.view,g=f.model,h=_.indexBy(g.get("rates"),"tax_rate_id"),j={};c.preventDefault(),(d=i.children(".current"))?(d.each(function(){e=a(this).data("id"),delete h[e],j[e]=_.extend(j[e]||{},{deleted:"deleted"})}),g.set("rates",h),g.logChanges(j),f.render()):window.alert(b.strings.no_rows_selected)},onSearchField:function(a){a.data.view.updateUrl(),a.data.view.render()},onPageChange:function(b){var c=a(b.currentTarget);b.preventDefault(),b.data.view.page=c.data("goto")?c.data("goto"):c.val(),b.data.view.render(),b.data.view.updateUrl()},onExport:function(c){var d="data:application/csv;charset=utf-8,"+b.strings.csv_data_cols.join(",")+"\n";return a.each(c.data.view.model.getFilteredRates(),function(a,c){var e="";e+=c.tax_rate_country+",",e+=c.tax_rate_state+",",e+=(c.postcode?c.postcode.join("; "):"")+",",e+=(c.city?c.city.join("; "):"")+",",e+=c.tax_rate+",",e+=c.tax_rate_name+",",e+=c.tax_rate_priority+",",e+=c.tax_rate_compound+",",e+=c.tax_rate_shipping+",",e+=b.current_class,d+=e+"\n"}),a(this).attr("href",encodeURI(d)),!0},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,j.removeAttr("disabled")},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,j.attr("disabled","disabled")},unloadConfirmation:function(a){if(a.data.view.needsUnloadConfirm)return a.returnValue=b.strings.unload_confirmation_msg,window.event.returnValue=b.strings.unload_confirmation_msg,b.strings.unload_confirmation_msg},updateModelOnChange:function(b){var c=b.data.view.model,d=a(b.target),e=d.closest("tr").data("id"),f=d.data("attribute"),g=d.val();"city"!==f&&"postcode"!==f||(g=g.split(";"),g=a.map(g,function(a){return a.trim()})),"tax_rate_compound"!==f&&"tax_rate_shipping"!==f||(g=d.is(":checked")?1:0),c.setRateAttribute(e,f,g)},updateModelOnSort:function(a){var b=a.data.view,c=b.model,d=_.indexBy(c.get("rates"),"tax_rate_id"),e={};_.each(d,function(a){var c=0,d=parseInt(a.tax_rate_order,10);c=h.find('tr[data-id="'+a.tax_rate_id+'"]').length?parseInt(h.find('tr[data-id="'+a.tax_rate_id+'"]').index(),10)+parseInt((b.page-1)*b.per_page,10):d,d!==c&&(e[a.tax_rate_id]=_.extend(e[a.tax_rate_id]||{},{tax_rate_order:c}))}),_.size(e)&&c.logChanges(e)},sanitizePage:function(a){return a=parseInt(a,10),a<1?a=1:a>this.qty_pages&&(a=this.qty_pages),a}}),p=new n({rates:b.rates}),q=new o({model:p,el:"#rates"});q.render()})}(jQuery,htmlSettingsTaxLocalizeScript,wp,ajaxurl); \ No newline at end of file diff --git a/assets/js/admin/wc-shipping-classes.min.js b/assets/js/admin/wc-shipping-classes.min.js index a0e0b09b2d5..d083a48efc5 100644 --- a/assets/js/admin/wc-shipping-classes.min.js +++ b/assets/js/admin/wc-shipping-classes.min.js @@ -1 +1 @@ -!function(a,b,c,d){a(function(){var e=a(".wc-shipping-class-rows"),f=a(".wc-shipping-class-save"),g=c.template("wc-shipping-class-row"),h=c.template("wc-shipping-class-row-blank"),i=Backbone.Model.extend({changes:{},logChanges:function(a){var b=this.changes||{};_.each(a,function(a,c){b[c]=_.extend(b[c]||{term_id:c},a)}),this.changes=b,this.trigger("change:classes")},save:function(){_.size(this.changes)?a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_classes_save_changes",{wc_shipping_classes_nonce:b.wc_shipping_classes_nonce,changes:this.changes},this.onSaveResponse,"json"):k.trigger("saved:classes")},discardChanges:function(a){var b=this.changes||{};delete b[a],0===_.size(this.changes)&&l.clearUnloadConfirmation()},onSaveResponse:function(a,c){"success"===c&&(a.success?(k.set("classes",a.data.shipping_classes),k.trigger("change:classes"),k.changes={},k.trigger("saved:classes")):a.data?window.alert(a.data):window.alert(b.strings.save_failed)),l.unblock()}}),j=Backbone.View.extend({rowTemplate:g,initialize:function(){this.listenTo(this.model,"change:classes",this.setUnloadConfirmation),this.listenTo(this.model,"saved:classes",this.clearUnloadConfirmation),this.listenTo(this.model,"saved:classes",this.render),e.on("change",{view:this},this.updateModelOnChange),a(window).on("beforeunload",{view:this},this.unloadConfirmation),f.on("click",{view:this},this.onSubmit),a(document.body).on("click",".wc-shipping-class-add",{view:this},this.onAddNewRow),a(document.body).on("click",".wc-shipping-class-save-changes",{view:this},this.onSubmit)},block:function(){a(this.el).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a(this.el).unblock()},render:function(){var b=_.indexBy(this.model.get("classes"),"term_id"),c=this;this.$el.empty(),this.unblock(),_.size(b)?(b=_.sortBy(b,function(a){return a.name}),a.each(b,function(a,b){c.renderRow(b)})):c.$el.append(h)},renderRow:function(a){var b=this;b.$el.append(b.rowTemplate(a)),b.initRow(a)},initRow:function(b){var c=this,d=c.$el.find('tr[data-id="'+b.term_id+'"]');d.find("select").each(function(){var c=a(this).data("attribute");a(this).find('option[value="'+b[c]+'"]').prop("selected",!0)}),d.find(".view").show(),d.find(".edit").hide(),d.find(".wc-shipping-class-edit").on("click",{view:this},this.onEditRow),d.find(".wc-shipping-class-delete").on("click",{view:this},this.onDeleteRow),d.find(".editing .wc-shipping-class-edit").trigger("click"),d.find(".wc-shipping-class-cancel-edit").on("click",{view:this},this.onCancelEditRow),!0===b.editing&&(d.addClass("editing"),d.find(".wc-shipping-class-edit").trigger("click"))},onSubmit:function(a){a.data.view.block(),a.data.view.model.save(),a.preventDefault()},onAddNewRow:function(c){c.preventDefault();var d=c.data.view,e=d.model,f=_.indexBy(e.get("classes"),"term_id"),g={},h=_.size(f),i=_.extend({},b.default_class,{term_id:"new-"+h+"-"+Date.now(),editing:!0,newRow:!0});g[i.term_id]=i,e.logChanges(g),d.renderRow(i),a(".wc-shipping-classes-blank-state").remove()},onEditRow:function(b){b.preventDefault(),a(this).closest("tr").addClass("editing"),a(this).closest("tr").find(".view").hide(),a(this).closest("tr").find(".edit").show(),b.data.view.model.trigger("change:classes")},onDeleteRow:function(b){var c=b.data.view,d=c.model,e=_.indexBy(d.get("classes"),"term_id"),f={},g=a(this).closest("tr").data("id");b.preventDefault(),e[g]&&(delete e[g],f[g]=_.extend(f[g]||{},{deleted:"deleted"}),d.set("classes",e),d.logChanges(f)),c.render()},onCancelEditRow:function(b){var c=b.data.view,d=c.model,e=a(this).closest("tr"),f=a(this).closest("tr").data("id"),g=_.indexBy(d.get("classes"),"term_id");b.preventDefault(),d.discardChanges(f),g[f]&&(g[f].editing=!1,e.after(c.rowTemplate(g[f])),c.initRow(g[f])),e.remove()},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,f.removeAttr("disabled")},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,f.attr("disabled","disabled")},unloadConfirmation:function(a){return a.data.view.needsUnloadConfirm?(a.returnValue=b.strings.unload_confirmation_msg,window.event.returnValue=b.strings.unload_confirmation_msg,b.strings.unload_confirmation_msg):void 0},updateModelOnChange:function(b){var c=b.data.view.model,d=a(b.target),e=d.closest("tr").data("id"),f=d.data("attribute"),g=d.val(),h=_.indexBy(c.get("classes"),"term_id"),i={};h[e]&&h[e][f]===g||(i[e]={},i[e][f]=g),c.logChanges(i)}}),k=new i({classes:b.classes}),l=new j({model:k,el:e});l.render()})}(jQuery,shippingClassesLocalizeScript,wp,ajaxurl); \ No newline at end of file +!function(a,b,c,d){a(function(){var e=a(".wc-shipping-class-rows"),f=a(".wc-shipping-class-save"),g=c.template("wc-shipping-class-row"),h=c.template("wc-shipping-class-row-blank"),i=Backbone.Model.extend({changes:{},logChanges:function(a){var b=this.changes||{};_.each(a,function(a,c){b[c]=_.extend(b[c]||{term_id:c},a)}),this.changes=b,this.trigger("change:classes")},save:function(){_.size(this.changes)?a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_classes_save_changes",{wc_shipping_classes_nonce:b.wc_shipping_classes_nonce,changes:this.changes},this.onSaveResponse,"json"):k.trigger("saved:classes")},discardChanges:function(a){var b=this.changes||{};delete b[a],0===_.size(this.changes)&&l.clearUnloadConfirmation()},onSaveResponse:function(a,c){"success"===c&&(a.success?(k.set("classes",a.data.shipping_classes),k.trigger("change:classes"),k.changes={},k.trigger("saved:classes")):a.data?window.alert(a.data):window.alert(b.strings.save_failed)),l.unblock()}}),j=Backbone.View.extend({rowTemplate:g,initialize:function(){this.listenTo(this.model,"change:classes",this.setUnloadConfirmation),this.listenTo(this.model,"saved:classes",this.clearUnloadConfirmation),this.listenTo(this.model,"saved:classes",this.render),e.on("change",{view:this},this.updateModelOnChange),a(window).on("beforeunload",{view:this},this.unloadConfirmation),f.on("click",{view:this},this.onSubmit),a(document.body).on("click",".wc-shipping-class-add",{view:this},this.onAddNewRow),a(document.body).on("click",".wc-shipping-class-save-changes",{view:this},this.onSubmit)},block:function(){a(this.el).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a(this.el).unblock()},render:function(){var b=_.indexBy(this.model.get("classes"),"term_id"),c=this;this.$el.empty(),this.unblock(),_.size(b)?(b=_.sortBy(b,function(a){return a.name}),a.each(b,function(a,b){c.renderRow(b)})):c.$el.append(h)},renderRow:function(a){var b=this;b.$el.append(b.rowTemplate(a)),b.initRow(a)},initRow:function(b){var c=this,d=c.$el.find('tr[data-id="'+b.term_id+'"]');d.find("select").each(function(){var c=a(this).data("attribute");a(this).find('option[value="'+b[c]+'"]').prop("selected",!0)}),d.find(".view").show(),d.find(".edit").hide(),d.find(".wc-shipping-class-edit").on("click",{view:this},this.onEditRow),d.find(".wc-shipping-class-delete").on("click",{view:this},this.onDeleteRow),d.find(".editing .wc-shipping-class-edit").trigger("click"),d.find(".wc-shipping-class-cancel-edit").on("click",{view:this},this.onCancelEditRow),!0===b.editing&&(d.addClass("editing"),d.find(".wc-shipping-class-edit").trigger("click"))},onSubmit:function(a){a.data.view.block(),a.data.view.model.save(),a.preventDefault()},onAddNewRow:function(c){c.preventDefault();var d=c.data.view,e=d.model,f=_.indexBy(e.get("classes"),"term_id"),g={},h=_.size(f),i=_.extend({},b.default_class,{term_id:"new-"+h+"-"+Date.now(),editing:!0,newRow:!0});g[i.term_id]=i,e.logChanges(g),d.renderRow(i),a(".wc-shipping-classes-blank-state").remove()},onEditRow:function(b){b.preventDefault(),a(this).closest("tr").addClass("editing"),a(this).closest("tr").find(".view").hide(),a(this).closest("tr").find(".edit").show(),b.data.view.model.trigger("change:classes")},onDeleteRow:function(b){var c=b.data.view,d=c.model,e=_.indexBy(d.get("classes"),"term_id"),f={},g=a(this).closest("tr").data("id");b.preventDefault(),e[g]&&(delete e[g],f[g]=_.extend(f[g]||{},{deleted:"deleted"}),d.set("classes",e),d.logChanges(f)),c.render()},onCancelEditRow:function(b){var c=b.data.view,d=c.model,e=a(this).closest("tr"),f=a(this).closest("tr").data("id"),g=_.indexBy(d.get("classes"),"term_id");b.preventDefault(),d.discardChanges(f),g[f]&&(g[f].editing=!1,e.after(c.rowTemplate(g[f])),c.initRow(g[f])),e.remove()},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,f.removeAttr("disabled")},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,f.attr("disabled","disabled")},unloadConfirmation:function(a){if(a.data.view.needsUnloadConfirm)return a.returnValue=b.strings.unload_confirmation_msg,window.event.returnValue=b.strings.unload_confirmation_msg,b.strings.unload_confirmation_msg},updateModelOnChange:function(b){var c=b.data.view.model,d=a(b.target),e=d.closest("tr").data("id"),f=d.data("attribute"),g=d.val(),h=_.indexBy(c.get("classes"),"term_id"),i={};h[e]&&h[e][f]===g||(i[e]={},i[e][f]=g),c.logChanges(i)}}),k=new i({classes:b.classes}),l=new j({model:k,el:e});l.render()})}(jQuery,shippingClassesLocalizeScript,wp,ajaxurl); \ No newline at end of file diff --git a/assets/js/admin/wc-shipping-zone-methods.min.js b/assets/js/admin/wc-shipping-zone-methods.min.js index 0fcad420067..5c980bfa46d 100644 --- a/assets/js/admin/wc-shipping-zone-methods.min.js +++ b/assets/js/admin/wc-shipping-zone-methods.min.js @@ -1 +1 @@ -!function(a,b,c,d){a(function(){var e=a(".wc-shipping-zone-methods"),f=a(".wc-shipping-zone-method-rows"),g=a(".wc-shipping-zone-method-save"),h=c.template("wc-shipping-zone-method-row"),i=c.template("wc-shipping-zone-method-row-blank"),j=Backbone.Model.extend({changes:{},logChanges:function(a){var b=this.changes||{};_.each(a,function(a,c){b[c]=_.extend(b[c]||{instance_id:c},a)}),this.changes=b,this.trigger("change:methods")},save:function(){_.size(this.changes)?a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zone_methods_save_changes",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,changes:this.changes,zone_id:b.zone_id},this.onSaveResponse,"json"):l.trigger("saved:methods")},onSaveResponse:function(a,c){"success"===c&&(a.success?(l.set("methods",a.data.methods),l.trigger("change:methods"),l.changes={},l.trigger("saved:methods")):window.alert(b.strings.save_failed))}}),k=Backbone.View.extend({rowTemplate:h,initialize:function(){this.listenTo(this.model,"change:methods",this.setUnloadConfirmation),this.listenTo(this.model,"saved:methods",this.clearUnloadConfirmation),this.listenTo(this.model,"saved:methods",this.render),f.on("change",{view:this},this.updateModelOnChange),f.on("sortupdate",{view:this},this.updateModelOnSort),a(window).on("beforeunload",{view:this},this.unloadConfirmation),g.on("click",{view:this},this.onSubmit),a(document.body).on("click",".wc-shipping-zone-method-settings",{view:this},this.onConfigureShippingMethod),a(document.body).on("click",".wc-shipping-zone-add-method",{view:this},this.onAddShippingMethod),a(document.body).on("wc_backbone_modal_response",this.onConfigureShippingMethodSubmitted),a(document.body).on("wc_backbone_modal_response",this.onAddShippingMethodSubmitted),a(document.body).on("change",".wc-shipping-zone-method-selector select",this.onChangeShippingMethodSelector)},block:function(){a(this.el).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a(this.el).unblock()},render:function(){var c=_.indexBy(this.model.get("methods"),"instance_id"),d=this;this.$el.empty(),this.unblock(),_.size(c)?(c=_.sortBy(c,function(a){return parseInt(a.method_order,10)}),a.each(c,function(a,c){"yes"===c.enabled?c.enabled_icon=''+b.strings.yes+"":c.enabled_icon=''+b.strings.no+"",d.$el.append(d.rowTemplate(c));var e=d.$el.find('tr[data-id="'+c.instance_id+'"]');c.has_settings||(e.find(".wc-shipping-zone-method-title a").replaceWith(e.find(".wc-shipping-zone-method-title").text()),e.find(".wc-shipping-zone-method-settings").remove())}),this.$el.find(".wc-shipping-zone-method-delete").on("click",{view:this},this.onDeleteRow),this.$el.find(".wc-shipping-zone-method-enabled a").on("click",{view:this},this.onToggleEnabled)):d.$el.append(i),this.initTooltips()},initTooltips:function(){a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:50})},onSubmit:function(a){a.data.view.block(),a.data.view.model.save(),a.preventDefault()},onDeleteRow:function(b){var c=b.data.view,d=c.model,e=_.indexBy(d.get("methods"),"instance_id"),f={},g=a(this).closest("tr").data("id");b.preventDefault(),delete e[g],f[g]=_.extend(f[g]||{},{deleted:"deleted"}),d.set("methods",e),d.logChanges(f),c.render()},onToggleEnabled:function(b){var c=b.data.view,d=a(b.target),e=c.model,f=_.indexBy(e.get("methods"),"instance_id"),g=d.closest("tr").data("id"),h="yes"===d.closest("tr").data("enabled")?"no":"yes",i={};b.preventDefault(),f[g].enabled=h,i[g]=_.extend(i[g]||{},{enabled:h}),e.set("methods",f),e.logChanges(i),c.render()},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,g.removeAttr("disabled")},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,g.attr("disabled","disabled")},unloadConfirmation:function(a){return a.data.view.needsUnloadConfirm?(a.returnValue=b.strings.unload_confirmation_msg,window.event.returnValue=b.strings.unload_confirmation_msg,b.strings.unload_confirmation_msg):void 0},updateModelOnChange:function(b){var c=b.data.view.model,d=a(b.target),e=d.closest("tr").data("id"),f=d.data("attribute"),g=d.val(),h=_.indexBy(c.get("methods"),"instance_id"),i={};h[e][f]!==g&&(i[e]={},i[e][f]=g,h[e][f]=g),c.logChanges(i)},updateModelOnSort:function(a){var b=a.data.view,c=b.model,d=_.indexBy(c.get("methods"),"instance_id"),f={};_.each(d,function(a){var b=parseInt(a.method_order,10),c=parseInt(e.find('tr[data-id="'+a.instance_id+'"]').index()+1,10);b!==c&&(f[a.instance_id]=_.extend(f[a.instance_id]||{},{method_order:c}))}),_.size(f)&&c.logChanges(f)},onConfigureShippingMethod:function(b){var c=a(this).closest("tr").data("id"),d=b.data.view.model,e=_.indexBy(d.get("methods"),"instance_id"),f=e[c];return f.settings_html?(b.preventDefault(),a(this).WCBackboneModal({template:"wc-modal-shipping-method-settings",variable:{instance_id:c,method:f},data:{instance_id:c,method:f}}),void a(document.body).trigger("init_tooltips")):!0},onConfigureShippingMethodSubmitted:function(c,e,f){"wc-modal-shipping-method-settings"===e&&(m.block(),a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zone_methods_save_settings",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,instance_id:f.instance_id,data:f},function(c,d){"success"===d&&c.success?(a("table.wc-shipping-zone-methods").parent().find("#woocommerce_errors").remove(),c.data.errors.length>0&&this.showErrors(c.data.errors),_.size(m.model.changes)?m.model.save():m.model.onSaveResponse(c,d)):(window.alert(b.strings.save_failed),m.unblock())},"json"))},showErrors:function(b){var c='
    ';a(b).each(function(a,b){c=c+"

    "+b+"

    "}),c+="
    ",a("table.wc-shipping-zone-methods").before(c)},onAddShippingMethod:function(c){c.preventDefault(),a(this).WCBackboneModal({template:"wc-modal-add-shipping-method",variable:{zone_id:b.zone_id}}),a(".wc-shipping-zone-method-selector select").change()},onAddShippingMethodSubmitted:function(c,e,f){"wc-modal-add-shipping-method"===e&&(m.block(),a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zone_add_method",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,method_id:f.add_method_id,zone_id:b.zone_id},function(a,b){"success"===b&&a.success&&(_.size(m.model.changes)?m.model.save():(m.model.set("methods",a.data.methods),m.model.trigger("change:methods"),m.model.changes={},m.model.trigger("saved:methods"))),m.unblock()},"json"))},onChangeShippingMethodSelector:function(){var b=a(this).find("option:selected").data("description");a(this).parent().find(".wc-shipping-zone-method-description").remove(),a(this).after('

    '+b+"

    "),a(this).closest("article").height(a(this).parent().height())}}),l=new j({methods:b.methods}),m=new k({model:l,el:f});m.render(),f.sortable({items:"tr",cursor:"move",axis:"y",handle:"td.wc-shipping-zone-method-sort",scrollSensitivity:40})})}(jQuery,shippingZoneMethodsLocalizeScript,wp,ajaxurl); \ No newline at end of file +!function(a,b,c,d){a(function(){var e=a(".wc-shipping-zone-methods"),f=a(".wc-shipping-zone-method-rows"),g=a(".wc-shipping-zone-method-save"),h=c.template("wc-shipping-zone-method-row"),i=c.template("wc-shipping-zone-method-row-blank"),j=Backbone.Model.extend({changes:{},logChanges:function(a){var b=this.changes||{};_.each(a,function(a,c){b[c]=_.extend(b[c]||{instance_id:c},a)}),this.changes=b,this.trigger("change:methods")},save:function(){_.size(this.changes)?a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zone_methods_save_changes",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,changes:this.changes,zone_id:b.zone_id},this.onSaveResponse,"json"):l.trigger("saved:methods")},onSaveResponse:function(a,c){"success"===c&&(a.success?(l.set("methods",a.data.methods),l.trigger("change:methods"),l.changes={},l.trigger("saved:methods")):window.alert(b.strings.save_failed))}}),k=Backbone.View.extend({rowTemplate:h,initialize:function(){this.listenTo(this.model,"change:methods",this.setUnloadConfirmation),this.listenTo(this.model,"saved:methods",this.clearUnloadConfirmation),this.listenTo(this.model,"saved:methods",this.render),f.on("change",{view:this},this.updateModelOnChange),f.on("sortupdate",{view:this},this.updateModelOnSort),a(window).on("beforeunload",{view:this},this.unloadConfirmation),g.on("click",{view:this},this.onSubmit),a(document.body).on("click",".wc-shipping-zone-method-settings",{view:this},this.onConfigureShippingMethod),a(document.body).on("click",".wc-shipping-zone-add-method",{view:this},this.onAddShippingMethod),a(document.body).on("wc_backbone_modal_response",this.onConfigureShippingMethodSubmitted),a(document.body).on("wc_backbone_modal_response",this.onAddShippingMethodSubmitted),a(document.body).on("change",".wc-shipping-zone-method-selector select",this.onChangeShippingMethodSelector)},block:function(){a(this.el).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a(this.el).unblock()},render:function(){var c=_.indexBy(this.model.get("methods"),"instance_id"),d=this;this.$el.empty(),this.unblock(),_.size(c)?(c=_.sortBy(c,function(a){return parseInt(a.method_order,10)}),a.each(c,function(a,c){"yes"===c.enabled?c.enabled_icon=''+b.strings.yes+"":c.enabled_icon=''+b.strings.no+"",d.$el.append(d.rowTemplate(c));var e=d.$el.find('tr[data-id="'+c.instance_id+'"]');c.has_settings||(e.find(".wc-shipping-zone-method-title a").replaceWith(e.find(".wc-shipping-zone-method-title").text()),e.find(".wc-shipping-zone-method-settings").remove())}),this.$el.find(".wc-shipping-zone-method-delete").on("click",{view:this},this.onDeleteRow),this.$el.find(".wc-shipping-zone-method-enabled a").on("click",{view:this},this.onToggleEnabled)):d.$el.append(i),this.initTooltips()},initTooltips:function(){a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:50})},onSubmit:function(a){a.data.view.block(),a.data.view.model.save(),a.preventDefault()},onDeleteRow:function(b){var c=b.data.view,d=c.model,e=_.indexBy(d.get("methods"),"instance_id"),f={},g=a(this).closest("tr").data("id");b.preventDefault(),delete e[g],f[g]=_.extend(f[g]||{},{deleted:"deleted"}),d.set("methods",e),d.logChanges(f),c.render()},onToggleEnabled:function(b){var c=b.data.view,d=a(b.target),e=c.model,f=_.indexBy(e.get("methods"),"instance_id"),g=d.closest("tr").data("id"),h="yes"===d.closest("tr").data("enabled")?"no":"yes",i={};b.preventDefault(),f[g].enabled=h,i[g]=_.extend(i[g]||{},{enabled:h}),e.set("methods",f),e.logChanges(i),c.render()},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,g.removeAttr("disabled")},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,g.attr("disabled","disabled")},unloadConfirmation:function(a){if(a.data.view.needsUnloadConfirm)return a.returnValue=b.strings.unload_confirmation_msg,window.event.returnValue=b.strings.unload_confirmation_msg,b.strings.unload_confirmation_msg},updateModelOnChange:function(b){var c=b.data.view.model,d=a(b.target),e=d.closest("tr").data("id"),f=d.data("attribute"),g=d.val(),h=_.indexBy(c.get("methods"),"instance_id"),i={};h[e][f]!==g&&(i[e]={},i[e][f]=g,h[e][f]=g),c.logChanges(i)},updateModelOnSort:function(a){var b=a.data.view,c=b.model,d=_.indexBy(c.get("methods"),"instance_id"),f={};_.each(d,function(a){var b=parseInt(a.method_order,10),c=parseInt(e.find('tr[data-id="'+a.instance_id+'"]').index()+1,10);b!==c&&(f[a.instance_id]=_.extend(f[a.instance_id]||{},{method_order:c}))}),_.size(f)&&c.logChanges(f)},onConfigureShippingMethod:function(b){var c=a(this).closest("tr").data("id"),d=b.data.view.model,e=_.indexBy(d.get("methods"),"instance_id"),f=e[c];return!f.settings_html||(b.preventDefault(),a(this).WCBackboneModal({template:"wc-modal-shipping-method-settings",variable:{instance_id:c,method:f},data:{instance_id:c,method:f}}),void a(document.body).trigger("init_tooltips"))},onConfigureShippingMethodSubmitted:function(c,e,f){"wc-modal-shipping-method-settings"===e&&(m.block(),a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zone_methods_save_settings",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,instance_id:f.instance_id,data:f},function(c,d){"success"===d&&c.success?(a("table.wc-shipping-zone-methods").parent().find("#woocommerce_errors").remove(),c.data.errors.length>0&&this.showErrors(c.data.errors),_.size(m.model.changes)?m.model.save():m.model.onSaveResponse(c,d)):(window.alert(b.strings.save_failed),m.unblock())},"json"))},showErrors:function(b){var c='
    ';a(b).each(function(a,b){c=c+"

    "+b+"

    "}),c+="
    ",a("table.wc-shipping-zone-methods").before(c)},onAddShippingMethod:function(c){c.preventDefault(),a(this).WCBackboneModal({template:"wc-modal-add-shipping-method",variable:{zone_id:b.zone_id}}),a(".wc-shipping-zone-method-selector select").change()},onAddShippingMethodSubmitted:function(c,e,f){"wc-modal-add-shipping-method"===e&&(m.block(),a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zone_add_method",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,method_id:f.add_method_id,zone_id:b.zone_id},function(a,b){"success"===b&&a.success&&(_.size(m.model.changes)?m.model.save():(m.model.set("methods",a.data.methods),m.model.trigger("change:methods"),m.model.changes={},m.model.trigger("saved:methods"))),m.unblock()},"json"))},onChangeShippingMethodSelector:function(){var b=a(this).find("option:selected").data("description");a(this).parent().find(".wc-shipping-zone-method-description").remove(),a(this).after('

    '+b+"

    "),a(this).closest("article").height(a(this).parent().height())}}),l=new j({methods:b.methods}),m=new k({model:l,el:f});m.render(),f.sortable({items:"tr",cursor:"move",axis:"y",handle:"td.wc-shipping-zone-method-sort",scrollSensitivity:40})})}(jQuery,shippingZoneMethodsLocalizeScript,wp,ajaxurl); \ No newline at end of file diff --git a/assets/js/admin/wc-shipping-zones.min.js b/assets/js/admin/wc-shipping-zones.min.js index c98edd47462..048cf4d44ec 100644 --- a/assets/js/admin/wc-shipping-zones.min.js +++ b/assets/js/admin/wc-shipping-zones.min.js @@ -1 +1 @@ -!function(a,b,c,d){a(function(){function e(){var a={formatMatches:function(a){return 1===a?wc_enhanced_select_params.i18n_matches_1:wc_enhanced_select_params.i18n_matches_n.replace("%qty%",a)},formatNoMatches:function(){return wc_enhanced_select_params.i18n_no_matches},formatAjaxError:function(){return wc_enhanced_select_params.i18n_ajax_error},formatInputTooShort:function(a,b){var c=b-a.length;return 1===c?wc_enhanced_select_params.i18n_input_too_short_1:wc_enhanced_select_params.i18n_input_too_short_n.replace("%qty%",c)},formatInputTooLong:function(a,b){var c=a.length-b;return 1===c?wc_enhanced_select_params.i18n_input_too_long_1:wc_enhanced_select_params.i18n_input_too_long_n.replace("%qty%",c)},formatSelectionTooBig:function(a){return 1===a?wc_enhanced_select_params.i18n_selection_too_long_1:wc_enhanced_select_params.i18n_selection_too_long_n.replace("%qty%",a)},formatLoadMore:function(){return wc_enhanced_select_params.i18n_load_more},formatSearching:function(){return wc_enhanced_select_params.i18n_searching}};return a}var f=a(".wc-shipping-zones"),g=a(".wc-shipping-zone-rows"),h=a(".wc-shipping-zone-save"),i=c.template("wc-shipping-zone-row"),j=c.template("wc-shipping-zone-row-blank"),k=a.extend({minimumResultsForSearch:10,allowClear:!!a(this).data("allow_clear"),placeholder:a(this).data("placeholder"),matcher:function(a,b,c){return b.toUpperCase().indexOf(a.toUpperCase())>=0||c.attr("alt").toUpperCase().indexOf(a.toUpperCase())>=0}},e()),l=Backbone.Model.extend({changes:{},logChanges:function(a){var b=this.changes||{};_.each(a,function(a,c){b[c]=_.extend(b[c]||{zone_id:c},a)}),this.changes=b,this.trigger("change:zones")},discardChanges:function(a){var b=this.changes||{},c=null,d=_.indexBy(this.get("zones"),"zone_id");b[a]&&void 0!==b[a].zone_order&&(c=b[a].zone_order),delete b[a],null!==c&&d[a]&&d[a].zone_order!==c&&(b[a]=_.extend(b[a]||{},{zone_id:a,zone_order:c})),this.changes=b,0===_.size(this.changes)&&o.clearUnloadConfirmation()},save:function(){_.size(this.changes)?a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zones_save_changes",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,changes:this.changes},this.onSaveResponse,"json"):n.trigger("saved:zones")},onSaveResponse:function(a,c){"success"===c&&(a.success?(n.set("zones",a.data.zones),n.trigger("change:zones"),n.changes={},n.trigger("saved:zones")):window.alert(b.strings.save_failed))}}),m=Backbone.View.extend({rowTemplate:i,initialize:function(){this.listenTo(this.model,"change:zones",this.setUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.clearUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.render),g.on("change",{view:this},this.updateModelOnChange),g.on("sortupdate",{view:this},this.updateModelOnSort),a(window).on("beforeunload",{view:this},this.unloadConfirmation),h.on("click",{view:this},this.onSubmit),a(document.body).on("click",".add_shipping_method:not(.disabled)",{view:this},this.onAddShippingMethod),a(document.body).on("click",".wc-shipping-zone-add",{view:this},this.onAddNewRow),a(document.body).on("wc_backbone_modal_response",this.onAddShippingMethodSubmitted),a(document.body).on("change",".wc-shipping-zone-method-selector select",this.onChangeShippingMethodSelector)},block:function(){a(this.el).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a(this.el).unblock()},render:function(){var b=_.indexBy(this.model.get("zones"),"zone_id"),c=this;c.$el.empty(),c.unblock(),_.size(b)?(b=_.sortBy(b,function(a){return parseInt(a.zone_order,10)}),a.each(b,function(a,b){c.renderRow(b)})):c.$el.append(j),c.initRows()},renderRow:function(a){var b=this;b.$el.append(b.rowTemplate(a)),b.initRow(a)},initRow:function(a){var b=this,c=b.$el.find('tr[data-id="'+a.zone_id+'"]');_.each(a.zone_locations,function(a){if("string"===jQuery.type(a))c.find('option[value="'+a+'"]').prop("selected",!0);else if("postcode"===a.type){var b=c.find(".wc-shipping-zone-postcodes :input");b.val()?b.val(b.val()+"\n"+a.code):b.val(a.code),c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()}else c.find('option[value="'+a.type+":"+a.code+'"]').prop("selected",!0)}),a.zone_postcodes&&_.each(a.zone_postcodes,function(a){var b=c.find(".wc-shipping-zone-postcodes :input");b.val()?b.val(b.val()+"\n"+a.code):b.val(a.code),c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()}),b.renderShippingMethods(a.zone_id,a.shipping_methods),c.find(".view").show(),c.find(".edit").hide(),c.find(".wc-shipping-zone-edit").on("click",{view:this},this.onEditRow),c.find(".wc-shipping-zone-cancel-edit").on("click",{view:this},this.onCancelEditRow),c.find(".wc-shipping-zone-delete").on("click",{view:this},this.onDeleteRow),c.find(".wc-shipping-zone-postcodes-toggle").on("click",{view:this},this.onTogglePostcodes),!0===a.editing&&(c.addClass("editing"),c.find(".wc-shipping-zone-edit").trigger("click"))},initRows:function(){0===a("tbody.wc-shipping-zone-rows tr").length%2?f.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").addClass("odd"):f.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").removeClass("odd"),a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:50})},renderShippingMethods:function(c,d){var e=a('.wc-shipping-zones tr[data-id="'+c+'"]'),f=e.find(".wc-shipping-zone-methods ul");f.find(".wc-shipping-zone-method").remove(),_.size(d)?_.each(d,function(a,b){var c="method_disabled";"yes"===a.enabled&&(c="method_enabled"),f.prepend('
  • '+a.title+"
  • ")}):f.prepend('
  • '+b.strings.no_shipping_methods_offered+"
  • ")},onSubmit:function(a){a.data.view.block(),a.data.view.model.save(),a.preventDefault()},onAddNewRow:function(c){c.preventDefault();var d=c.data.view,e=d.model,f=_.indexBy(e.get("zones"),"zone_id"),g={},h=_.size(f),i=_.extend({},b.default_zone,{zone_id:"new-"+h+"-"+Date.now(),editing:!0});a(".wc-shipping-zones-blank-state").closest("tr").remove(),i.zone_order=1+_.max(_.pluck(f,"zone_order"),function(a){return parseInt(a,10)}),g[i.zone_id]=i,e.logChanges(g),d.renderRow(i),d.initRows()},onTogglePostcodes:function(b){b.preventDefault();var c=a(this).closest("tr");c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()},onEditRow:function(b){b.preventDefault(),b.data.view.model.trigger("change:zones"),a(this).closest("tr").addClass("editing"),a(this).closest("tr").find(".view").hide(),a(this).closest("tr").find(".edit").show(),a(".wc-shipping-zone-region-select:not(.enhanced)").select2(k),a(".wc-shipping-zone-region-select:not(.enhanced)").addClass("enhanced");var c=a(this).closest("tr").find(".add_shipping_method");c.addClass("disabled"),c.tipTip({attribute:"data-disabled-tip",fadeIn:50,fadeOut:50,delay:50})},onCancelEditRow:function(b){var c=b.data.view,d=c.model,e=a(this).closest("tr"),f=e.data("id"),g=_.indexBy(d.get("zones"),"zone_id");b.preventDefault(),d.discardChanges(f),g[f]&&(g[f].editing=!1,e.after(c.rowTemplate(g[f])),c.initRow(g[f])),e.remove(),c.initRows()},onDeleteRow:function(b){var c=b.data.view,d=c.model,e=_.indexBy(d.get("zones"),"zone_id"),f={},g=a(this).closest("tr"),h=a(this).closest("tr").data("id");b.preventDefault(),e[h]&&(delete e[h],f[h]=_.extend(f[h]||{},{deleted:"deleted"}),d.set("zones",e),d.logChanges(f)),g.remove(),c.initRows()},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,h.prop("disabled",!1)},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,h.prop("disabled",!0)},unloadConfirmation:function(a){return a.data.view.needsUnloadConfirm?(a.returnValue=b.strings.unload_confirmation_msg,window.event.returnValue=b.strings.unload_confirmation_msg,b.strings.unload_confirmation_msg):void 0},updateModelOnChange:function(b){var c=b.data.view.model,d=a(b.target),e=d.closest("tr").data("id"),f=d.data("attribute"),g=d.val(),h=_.indexBy(c.get("zones"),"zone_id"),i={};h[e]&&h[e][f]===g||(i[e]={},i[e][f]=g),c.logChanges(i)},updateModelOnSort:function(b){var c=b.data.view,d=c.model,e=_.indexBy(d.get("zones"),"zone_id"),f=a("tbody.wc-shipping-zone-rows tr"),g={};_.each(f,function(b){var c=a(b).data("id"),d=null,f=parseInt(a(b).index(),10);e[c]&&(d=parseInt(e[c].zone_order,10)),d!==f&&(g[c]=_.extend(g[c]||{},{zone_order:f}))}),_.size(g)&&d.logChanges(g)},onAddShippingMethod:function(b){var c=a(this).closest("tr").data("id");b.preventDefault(),a(this).WCBackboneModal({template:"wc-modal-add-shipping-method",variable:{zone_id:c}}),a(".wc-shipping-zone-method-selector select").change()},onAddShippingMethodSubmitted:function(c,e,f){"wc-modal-add-shipping-method"===e&&(o.block(),a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zone_add_method",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,method_id:f.add_method_id,zone_id:f.zone_id},function(a,b){"success"===b&&a.success&&o.renderShippingMethods(f.zone_id,a.data.methods),o.unblock()},"json"))},onChangeShippingMethodSelector:function(){var b=a(this).find("option:selected").data("description");a(this).parent().find(".wc-shipping-zone-method-description").remove(),a(this).after('

    '+b+"

    "),a(this).closest("article").height(a(this).parent().height())}}),n=new l({zones:b.zones}),o=new m({model:n,el:g});o.render(),g.sortable({items:"tr",cursor:"move",axis:"y",handle:"td.wc-shipping-zone-sort",scrollSensitivity:40})})}(jQuery,shippingZonesLocalizeScript,wp,ajaxurl); \ No newline at end of file +!function(a,b,c,d){a(function(){function e(){var a={formatMatches:function(a){return 1===a?wc_enhanced_select_params.i18n_matches_1:wc_enhanced_select_params.i18n_matches_n.replace("%qty%",a)},formatNoMatches:function(){return wc_enhanced_select_params.i18n_no_matches},formatAjaxError:function(){return wc_enhanced_select_params.i18n_ajax_error},formatInputTooShort:function(a,b){var c=b-a.length;return 1===c?wc_enhanced_select_params.i18n_input_too_short_1:wc_enhanced_select_params.i18n_input_too_short_n.replace("%qty%",c)},formatInputTooLong:function(a,b){var c=a.length-b;return 1===c?wc_enhanced_select_params.i18n_input_too_long_1:wc_enhanced_select_params.i18n_input_too_long_n.replace("%qty%",c)},formatSelectionTooBig:function(a){return 1===a?wc_enhanced_select_params.i18n_selection_too_long_1:wc_enhanced_select_params.i18n_selection_too_long_n.replace("%qty%",a)},formatLoadMore:function(){return wc_enhanced_select_params.i18n_load_more},formatSearching:function(){return wc_enhanced_select_params.i18n_searching}};return a}var f=a(".wc-shipping-zones"),g=a(".wc-shipping-zone-rows"),h=a(".wc-shipping-zone-save"),i=c.template("wc-shipping-zone-row"),j=c.template("wc-shipping-zone-row-blank"),k=a.extend({minimumResultsForSearch:10,allowClear:!!a(this).data("allow_clear"),placeholder:a(this).data("placeholder"),matcher:function(a,b,c){return b.toUpperCase().indexOf(a.toUpperCase())>=0||c.attr("alt").toUpperCase().indexOf(a.toUpperCase())>=0}},e()),l=Backbone.Model.extend({changes:{},logChanges:function(a){var b=this.changes||{};_.each(a,function(a,c){b[c]=_.extend(b[c]||{zone_id:c},a)}),this.changes=b,this.trigger("change:zones")},discardChanges:function(a){var b=this.changes||{},c=null,d=_.indexBy(this.get("zones"),"zone_id");b[a]&&void 0!==b[a].zone_order&&(c=b[a].zone_order),delete b[a],null!==c&&d[a]&&d[a].zone_order!==c&&(b[a]=_.extend(b[a]||{},{zone_id:a,zone_order:c})),this.changes=b,0===_.size(this.changes)&&o.clearUnloadConfirmation()},save:function(){_.size(this.changes)?a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zones_save_changes",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,changes:this.changes},this.onSaveResponse,"json"):n.trigger("saved:zones")},onSaveResponse:function(a,c){"success"===c&&(a.success?(n.set("zones",a.data.zones),n.trigger("change:zones"),n.changes={},n.trigger("saved:zones")):window.alert(b.strings.save_failed))}}),m=Backbone.View.extend({rowTemplate:i,initialize:function(){this.listenTo(this.model,"change:zones",this.setUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.clearUnloadConfirmation),this.listenTo(this.model,"saved:zones",this.render),g.on("change",{view:this},this.updateModelOnChange),g.on("sortupdate",{view:this},this.updateModelOnSort),a(window).on("beforeunload",{view:this},this.unloadConfirmation),h.on("click",{view:this},this.onSubmit),a(document.body).on("click",".add_shipping_method:not(.disabled)",{view:this},this.onAddShippingMethod),a(document.body).on("click",".wc-shipping-zone-add",{view:this},this.onAddNewRow),a(document.body).on("wc_backbone_modal_response",this.onAddShippingMethodSubmitted),a(document.body).on("change",".wc-shipping-zone-method-selector select",this.onChangeShippingMethodSelector)},block:function(){a(this.el).block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},unblock:function(){a(this.el).unblock()},render:function(){var b=_.indexBy(this.model.get("zones"),"zone_id"),c=this;c.$el.empty(),c.unblock(),_.size(b)?(b=_.sortBy(b,function(a){return parseInt(a.zone_order,10)}),a.each(b,function(a,b){c.renderRow(b)})):c.$el.append(j),c.initRows()},renderRow:function(a){var b=this;b.$el.append(b.rowTemplate(a)),b.initRow(a)},initRow:function(a){var b=this,c=b.$el.find('tr[data-id="'+a.zone_id+'"]');_.each(a.zone_locations,function(a){if("string"===jQuery.type(a))c.find('option[value="'+a+'"]').prop("selected",!0);else if("postcode"===a.type){var b=c.find(".wc-shipping-zone-postcodes :input");b.val()?b.val(b.val()+"\n"+a.code):b.val(a.code),c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()}else c.find('option[value="'+a.type+":"+a.code+'"]').prop("selected",!0)}),a.zone_postcodes&&_.each(a.zone_postcodes,function(a){var b=c.find(".wc-shipping-zone-postcodes :input");b.val()?b.val(b.val()+"\n"+a.code):b.val(a.code),c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()}),b.renderShippingMethods(a.zone_id,a.shipping_methods),c.find(".view").show(),c.find(".edit").hide(),c.find(".wc-shipping-zone-edit").on("click",{view:this},this.onEditRow),c.find(".wc-shipping-zone-cancel-edit").on("click",{view:this},this.onCancelEditRow),c.find(".wc-shipping-zone-delete").on("click",{view:this},this.onDeleteRow),c.find(".wc-shipping-zone-postcodes-toggle").on("click",{view:this},this.onTogglePostcodes),!0===a.editing&&(c.addClass("editing"),c.find(".wc-shipping-zone-edit").trigger("click"))},initRows:function(){0===a("tbody.wc-shipping-zone-rows tr").length%2?f.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").addClass("odd"):f.find("tbody.wc-shipping-zone-rows").next("tbody").find("tr").removeClass("odd"),a("#tiptip_holder").removeAttr("style"),a("#tiptip_arrow").removeAttr("style"),a(".tips").tipTip({attribute:"data-tip",fadeIn:50,fadeOut:50,delay:50})},renderShippingMethods:function(c,d){var e=a('.wc-shipping-zones tr[data-id="'+c+'"]'),f=e.find(".wc-shipping-zone-methods ul");f.find(".wc-shipping-zone-method").remove(),_.size(d)?_.each(d,function(a,b){var c="method_disabled";"yes"===a.enabled&&(c="method_enabled"),f.prepend('
  • '+a.title+"
  • ")}):f.prepend('
  • '+b.strings.no_shipping_methods_offered+"
  • ")},onSubmit:function(a){a.data.view.block(),a.data.view.model.save(),a.preventDefault()},onAddNewRow:function(c){c.preventDefault();var d=c.data.view,e=d.model,f=_.indexBy(e.get("zones"),"zone_id"),g={},h=_.size(f),i=_.extend({},b.default_zone,{zone_id:"new-"+h+"-"+Date.now(),editing:!0});a(".wc-shipping-zones-blank-state").closest("tr").remove(),i.zone_order=1+_.max(_.pluck(f,"zone_order"),function(a){return parseInt(a,10)}),g[i.zone_id]=i,e.logChanges(g),d.renderRow(i),d.initRows()},onTogglePostcodes:function(b){b.preventDefault();var c=a(this).closest("tr");c.find(".wc-shipping-zone-postcodes").show(),c.find(".wc-shipping-zone-postcodes-toggle").hide()},onEditRow:function(b){b.preventDefault(),b.data.view.model.trigger("change:zones"),a(this).closest("tr").addClass("editing"),a(this).closest("tr").find(".view").hide(),a(this).closest("tr").find(".edit").show(),a(".wc-shipping-zone-region-select:not(.enhanced)").select2(k),a(".wc-shipping-zone-region-select:not(.enhanced)").addClass("enhanced");var c=a(this).closest("tr").find(".add_shipping_method");c.addClass("disabled"),c.tipTip({attribute:"data-disabled-tip",fadeIn:50,fadeOut:50,delay:50})},onCancelEditRow:function(b){var c=b.data.view,d=c.model,e=a(this).closest("tr"),f=e.data("id"),g=_.indexBy(d.get("zones"),"zone_id");b.preventDefault(),d.discardChanges(f),g[f]&&(g[f].editing=!1,e.after(c.rowTemplate(g[f])),c.initRow(g[f])),e.remove(),c.initRows()},onDeleteRow:function(b){var c=b.data.view,d=c.model,e=_.indexBy(d.get("zones"),"zone_id"),f={},g=a(this).closest("tr"),h=a(this).closest("tr").data("id");b.preventDefault(),e[h]&&(delete e[h],f[h]=_.extend(f[h]||{},{deleted:"deleted"}),d.set("zones",e),d.logChanges(f)),g.remove(),c.initRows()},setUnloadConfirmation:function(){this.needsUnloadConfirm=!0,h.prop("disabled",!1)},clearUnloadConfirmation:function(){this.needsUnloadConfirm=!1,h.prop("disabled",!0)},unloadConfirmation:function(a){if(a.data.view.needsUnloadConfirm)return a.returnValue=b.strings.unload_confirmation_msg,window.event.returnValue=b.strings.unload_confirmation_msg,b.strings.unload_confirmation_msg},updateModelOnChange:function(b){var c=b.data.view.model,d=a(b.target),e=d.closest("tr").data("id"),f=d.data("attribute"),g=d.val(),h=_.indexBy(c.get("zones"),"zone_id"),i={};h[e]&&h[e][f]===g||(i[e]={},i[e][f]=g),c.logChanges(i)},updateModelOnSort:function(b){var c=b.data.view,d=c.model,e=_.indexBy(d.get("zones"),"zone_id"),f=a("tbody.wc-shipping-zone-rows tr"),g={};_.each(f,function(b){var c=a(b).data("id"),d=null,f=parseInt(a(b).index(),10);e[c]&&(d=parseInt(e[c].zone_order,10)),d!==f&&(g[c]=_.extend(g[c]||{},{zone_order:f}))}),_.size(g)&&d.logChanges(g)},onAddShippingMethod:function(b){var c=a(this).closest("tr").data("id");b.preventDefault(),a(this).WCBackboneModal({template:"wc-modal-add-shipping-method",variable:{zone_id:c}}),a(".wc-shipping-zone-method-selector select").change()},onAddShippingMethodSubmitted:function(c,e,f){"wc-modal-add-shipping-method"===e&&(o.block(),a.post(d+(d.indexOf("?")>0?"&":"?")+"action=woocommerce_shipping_zone_add_method",{wc_shipping_zones_nonce:b.wc_shipping_zones_nonce,method_id:f.add_method_id,zone_id:f.zone_id},function(a,b){"success"===b&&a.success&&o.renderShippingMethods(f.zone_id,a.data.methods),o.unblock()},"json"))},onChangeShippingMethodSelector:function(){var b=a(this).find("option:selected").data("description");a(this).parent().find(".wc-shipping-zone-method-description").remove(),a(this).after('

    '+b+"

    "),a(this).closest("article").height(a(this).parent().height())}}),n=new l({zones:b.zones}),o=new m({model:n,el:g});o.render(),g.sortable({items:"tr",cursor:"move",axis:"y",handle:"td.wc-shipping-zone-sort",scrollSensitivity:40})})}(jQuery,shippingZonesLocalizeScript,wp,ajaxurl); \ No newline at end of file diff --git a/assets/js/admin/woocommerce_admin.min.js b/assets/js/admin/woocommerce_admin.min.js index 10ffe17373d..aadf5f85787 100644 --- a/assets/js/admin/woocommerce_admin.min.js +++ b/assets/js/admin/woocommerce_admin.min.js @@ -1 +1 @@ -jQuery(function(a){a(document.body).on("wc_add_error_tip",function(b,c,d){var e=c.position();0===c.parent().find(".wc_error_tip").length&&(c.after('
    '+woocommerce_admin[d]+"
    "),c.parent().find(".wc_error_tip").css("left",e.left+c.width()-c.width()/2-a(".wc_error_tip").width()/2).css("top",e.top+c.height()).fadeIn("100"))}).on("wc_remove_error_tip",function(b,c,d){c.parent().find(".wc_error_tip."+d).fadeOut("100",function(){a(this).remove()})}).on("click",function(){a(".wc_error_tip").fadeOut("100",function(){a(this).remove()})}).on("blur",".wc_input_decimal[type=text], .wc_input_price[type=text], .wc_input_country_iso[type=text]",function(){a(".wc_error_tip").fadeOut("100",function(){a(this).remove()})}).on("change",".wc_input_price[type=text], .wc_input_decimal[type=text], .wc-order-totals #refund_amount[type=text]",function(){var b;b=a(this).is(".wc_input_price")||a(this).is("#refund_amount")?new RegExp("[^-0-9%\\"+woocommerce_admin.mon_decimal_point+"]+","gi"):new RegExp("[^-0-9%\\"+woocommerce_admin.decimal_point+"]+","gi");var c=a(this).val(),d=c.replace(b,"");c!==d&&a(this).val(d)}).on("keyup",".wc_input_price[type=text], .wc_input_decimal[type=text], .wc_input_country_iso[type=text], .wc-order-totals #refund_amount[type=text]",function(){var b,c;a(this).is(".wc_input_price")||a(this).is("#refund_amount")?(b=new RegExp("[^-0-9%\\"+woocommerce_admin.mon_decimal_point+"]+","gi"),c="i18n_mon_decimal_error"):a(this).is(".wc_input_country_iso")?(b=new RegExp("([^A-Z])+|(.){3,}","im"),c="i18n_country_iso_error"):(b=new RegExp("[^-0-9%\\"+woocommerce_admin.decimal_point+"]+","gi"),c="i18n_decimal_error");var d=a(this).val(),e=d.replace(b,"");d!==e?a(document.body).triggerHandler("wc_add_error_tip",[a(this),c]):a(document.body).triggerHandler("wc_remove_error_tip",[a(this),c])}).on("change","#_sale_price.wc_input_price[type=text], .wc_input_price[name^=variable_sale_price]",function(){var b,c=a(this);b=-1!==c.attr("name").indexOf("variable")?c.parents(".variable_pricing").find(".wc_input_price[name^=variable_regular_price]"):a("#_regular_price");var d=parseFloat(window.accounting.unformat(c.val(),woocommerce_admin.mon_decimal_point)),e=parseFloat(window.accounting.unformat(b.val(),woocommerce_admin.mon_decimal_point));d>=e&&a(this).val("")}).on("keyup","#_sale_price.wc_input_price[type=text], .wc_input_price[name^=variable_sale_price]",function(){var b,c=a(this);b=-1!==c.attr("name").indexOf("variable")?c.parents(".variable_pricing").find(".wc_input_price[name^=variable_regular_price]"):a("#_regular_price");var d=parseFloat(window.accounting.unformat(c.val(),woocommerce_admin.mon_decimal_point)),e=parseFloat(window.accounting.unformat(b.val(),woocommerce_admin.mon_decimal_point));d>=e?a(document.body).triggerHandler("wc_add_error_tip",[a(this),"i18_sale_less_than_regular_error"]):a(document.body).triggerHandler("wc_remove_error_tip",[a(this),"i18_sale_less_than_regular_error"])}).on("init_tooltips",function(){var b={attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200};a(".tips, .help_tip, .woocommerce-help-tip").tipTip(b),a(".parent-tips").each(function(){a(this).closest("a, th").attr("data-tip",a(this).data("tip")).tipTip(b).css("cursor","help")})}),a(document.body).trigger("init_tooltips"),a(".wc_input_table.sortable tbody").sortable({items:"tr",cursor:"move",axis:"y",scrollSensitivity:40,forcePlaceholderSize:!0,helper:"clone",opacity:.65,placeholder:"wc-metabox-sortable-placeholder",start:function(a,b){b.item.css("background-color","#f6f6f6")},stop:function(a,b){b.item.removeAttr("style")}}),a(".wc_input_table .remove_rows").click(function(){var b=a(this).closest(".wc_input_table").find("tbody");if(b.find("tr.current").length>0){var c=b.find("tr.current");c.each(function(){a(this).remove()})}return!1});var b=!1,c=!1,d=!1;a(document.body).bind("keyup keydown",function(a){c=a.shiftKey,b=a.ctrlKey||a.metaKey}),a(".wc_input_table").on("focus click","input",function(e){var f=a(this).closest("table, tbody"),g=a(this).closest("tr");("focus"===e.type&&d!==g.index()||"click"===e.type&&a(this).is(":focus"))&&(d=g.index(),c||b?c?(a("tr",f).removeClass("current"),g.addClass("selected_now").addClass("current"),a("tr.last_selected",f).length>0&&(g.index()>a("tr.last_selected",f).index()?a("tr",f).slice(a("tr.last_selected",f).index(),g.index()).addClass("current"):a("tr",f).slice(g.index(),a("tr.last_selected",f).index()+1).addClass("current")),a("tr",f).removeClass("last_selected"),g.addClass("last_selected")):(a("tr",f).removeClass("last_selected"),b&&a(this).closest("tr").is(".current")?g.removeClass("current"):g.addClass("current").addClass("last_selected")):(a("tr",f).removeClass("current").removeClass("last_selected"),g.addClass("current").addClass("last_selected")),a("tr",f).removeClass("selected_now"))}).on("blur","input",function(){d=!1}),a(".woocommerce_page_wc-settings .shippingrows tbody tr:even, table.attributes-table tbody tr:nth-child(odd)").addClass("alternate"),a(document.body).on("click",".show_order_items",function(){return a(this).closest("td").find("table").toggle(),!1}),a("select.availability").change(function(){"all"===a(this).val()?a(this).closest("tr").next("tr").hide():a(this).closest("tr").next("tr").show()}).change(),a(".hide_options_if_checked").each(function(){a(this).find("input:eq(0)").change(function(){a(this).is(":checked")?a(this).closest("fieldset, tr").nextUntil(".hide_options_if_checked, .show_options_if_checked",".hidden_option").hide():a(this).closest("fieldset, tr").nextUntil(".hide_options_if_checked, .show_options_if_checked",".hidden_option").show()}).change()}),a(".show_options_if_checked").each(function(){a(this).find("input:eq(0)").change(function(){a(this).is(":checked")?a(this).closest("fieldset, tr").nextUntil(".hide_options_if_checked, .show_options_if_checked",".hidden_option").show():a(this).closest("fieldset, tr").nextUntil(".hide_options_if_checked, .show_options_if_checked",".hidden_option").hide()}).change()}),a("input#woocommerce_demo_store").change(function(){a(this).is(":checked")?a("#woocommerce_demo_store_notice").closest("tr").show():a("#woocommerce_demo_store_notice").closest("tr").hide()}).change(),a("table.attributes-table tbody tr:nth-child(odd)").addClass("alternate"),a("#contextual-help-link").on("click",function(){var b=a("#tab-panel-woocommerce_101_tab iframe");b.attr("src",b.data("src"))})}); \ No newline at end of file +jQuery(function(a){a(document.body).on("wc_add_error_tip",function(b,c,d){var e=c.position();0===c.parent().find(".wc_error_tip").length&&(c.after('
    '+woocommerce_admin[d]+"
    "),c.parent().find(".wc_error_tip").css("left",e.left+c.width()-c.width()/2-a(".wc_error_tip").width()/2).css("top",e.top+c.height()).fadeIn("100"))}).on("wc_remove_error_tip",function(b,c,d){c.parent().find(".wc_error_tip."+d).fadeOut("100",function(){a(this).remove()})}).on("click",function(){a(".wc_error_tip").fadeOut("100",function(){a(this).remove()})}).on("blur",".wc_input_decimal[type=text], .wc_input_price[type=text], .wc_input_country_iso[type=text]",function(){a(".wc_error_tip").fadeOut("100",function(){a(this).remove()})}).on("change",".wc_input_price[type=text], .wc_input_decimal[type=text], .wc-order-totals #refund_amount[type=text]",function(){var b;b=a(this).is(".wc_input_price")||a(this).is("#refund_amount")?new RegExp("[^-0-9%\\"+woocommerce_admin.mon_decimal_point+"]+","gi"):new RegExp("[^-0-9%\\"+woocommerce_admin.decimal_point+"]+","gi");var c=a(this).val(),d=c.replace(b,"");c!==d&&a(this).val(d)}).on("keyup",".wc_input_price[type=text], .wc_input_decimal[type=text], .wc_input_country_iso[type=text], .wc-order-totals #refund_amount[type=text]",function(){var b,c;a(this).is(".wc_input_price")||a(this).is("#refund_amount")?(b=new RegExp("[^-0-9%\\"+woocommerce_admin.mon_decimal_point+"]+","gi"),c="i18n_mon_decimal_error"):a(this).is(".wc_input_country_iso")?(b=new RegExp("([^A-Z])+|(.){3,}","im"),c="i18n_country_iso_error"):(b=new RegExp("[^-0-9%\\"+woocommerce_admin.decimal_point+"]+","gi"),c="i18n_decimal_error");var d=a(this).val(),e=d.replace(b,"");d!==e?a(document.body).triggerHandler("wc_add_error_tip",[a(this),c]):a(document.body).triggerHandler("wc_remove_error_tip",[a(this),c])}).on("change","#_sale_price.wc_input_price[type=text], .wc_input_price[name^=variable_sale_price]",function(){var b,c=a(this);b=c.attr("name").indexOf("variable")!==-1?c.parents(".variable_pricing").find(".wc_input_price[name^=variable_regular_price]"):a("#_regular_price");var d=parseFloat(window.accounting.unformat(c.val(),woocommerce_admin.mon_decimal_point)),e=parseFloat(window.accounting.unformat(b.val(),woocommerce_admin.mon_decimal_point));d>=e&&a(this).val("")}).on("keyup","#_sale_price.wc_input_price[type=text], .wc_input_price[name^=variable_sale_price]",function(){var b,c=a(this);b=c.attr("name").indexOf("variable")!==-1?c.parents(".variable_pricing").find(".wc_input_price[name^=variable_regular_price]"):a("#_regular_price");var d=parseFloat(window.accounting.unformat(c.val(),woocommerce_admin.mon_decimal_point)),e=parseFloat(window.accounting.unformat(b.val(),woocommerce_admin.mon_decimal_point));d>=e?a(document.body).triggerHandler("wc_add_error_tip",[a(this),"i18_sale_less_than_regular_error"]):a(document.body).triggerHandler("wc_remove_error_tip",[a(this),"i18_sale_less_than_regular_error"])}).on("init_tooltips",function(){var b={attribute:"data-tip",fadeIn:50,fadeOut:50,delay:200};a(".tips, .help_tip, .woocommerce-help-tip").tipTip(b),a(".parent-tips").each(function(){a(this).closest("a, th").attr("data-tip",a(this).data("tip")).tipTip(b).css("cursor","help")})}),a(document.body).trigger("init_tooltips"),a(".wc_input_table.sortable tbody").sortable({items:"tr",cursor:"move",axis:"y",scrollSensitivity:40,forcePlaceholderSize:!0,helper:"clone",opacity:.65,placeholder:"wc-metabox-sortable-placeholder",start:function(a,b){b.item.css("background-color","#f6f6f6")},stop:function(a,b){b.item.removeAttr("style")}}),a(".wc_input_table .remove_rows").click(function(){var b=a(this).closest(".wc_input_table").find("tbody");if(b.find("tr.current").length>0){var c=b.find("tr.current");c.each(function(){a(this).remove()})}return!1});var b=!1,c=!1,d=!1;a(document.body).bind("keyup keydown",function(a){c=a.shiftKey,b=a.ctrlKey||a.metaKey}),a(".wc_input_table").on("focus click","input",function(e){var f=a(this).closest("table, tbody"),g=a(this).closest("tr");("focus"===e.type&&d!==g.index()||"click"===e.type&&a(this).is(":focus"))&&(d=g.index(),c||b?c?(a("tr",f).removeClass("current"),g.addClass("selected_now").addClass("current"),a("tr.last_selected",f).length>0&&(g.index()>a("tr.last_selected",f).index()?a("tr",f).slice(a("tr.last_selected",f).index(),g.index()).addClass("current"):a("tr",f).slice(g.index(),a("tr.last_selected",f).index()+1).addClass("current")),a("tr",f).removeClass("last_selected"),g.addClass("last_selected")):(a("tr",f).removeClass("last_selected"),b&&a(this).closest("tr").is(".current")?g.removeClass("current"):g.addClass("current").addClass("last_selected")):(a("tr",f).removeClass("current").removeClass("last_selected"),g.addClass("current").addClass("last_selected")),a("tr",f).removeClass("selected_now"))}).on("blur","input",function(){d=!1}),a(".woocommerce_page_wc-settings .shippingrows tbody tr:even, table.attributes-table tbody tr:nth-child(odd)").addClass("alternate"),a(document.body).on("click",".show_order_items",function(){return a(this).closest("td").find("table").toggle(),!1}),a("select.availability").change(function(){"all"===a(this).val()?a(this).closest("tr").next("tr").hide():a(this).closest("tr").next("tr").show()}).change(),a(".hide_options_if_checked").each(function(){a(this).find("input:eq(0)").change(function(){a(this).is(":checked")?a(this).closest("fieldset, tr").nextUntil(".hide_options_if_checked, .show_options_if_checked",".hidden_option").hide():a(this).closest("fieldset, tr").nextUntil(".hide_options_if_checked, .show_options_if_checked",".hidden_option").show()}).change()}),a(".show_options_if_checked").each(function(){a(this).find("input:eq(0)").change(function(){a(this).is(":checked")?a(this).closest("fieldset, tr").nextUntil(".hide_options_if_checked, .show_options_if_checked",".hidden_option").show():a(this).closest("fieldset, tr").nextUntil(".hide_options_if_checked, .show_options_if_checked",".hidden_option").hide()}).change()}),a("input#woocommerce_demo_store").change(function(){a(this).is(":checked")?a("#woocommerce_demo_store_notice").closest("tr").show():a("#woocommerce_demo_store_notice").closest("tr").hide()}).change(),a("table.attributes-table tbody tr:nth-child(odd)").addClass("alternate"),a("#contextual-help-link").on("click",function(){var b=a("#tab-panel-woocommerce_101_tab iframe");b.attr("src",b.data("src"))})}); \ No newline at end of file diff --git a/assets/js/frontend/add-payment-method.min.js b/assets/js/frontend/add-payment-method.min.js index 0cb8d8de885..b77e5d7b04b 100644 --- a/assets/js/frontend/add-payment-method.min.js +++ b/assets/js/frontend/add-payment-method.min.js @@ -1 +1 @@ -jQuery(function(a){return"undefined"==typeof woocommerce_params?!1:(a("#add_payment_method").on("click init_add_payment_method",".payment_methods input.input-radio",function(){if(a(".payment_methods input.input-radio").length>1){var b=a("div.payment_box."+a(this).attr("ID"));a(this).is(":checked")&&!b.is(":visible")&&(a("div.payment_box").filter(":visible").slideUp(250),a(this).is(":checked")&&a("div.payment_box."+a(this).attr("ID")).slideDown(250))}else a("div.payment_box").show()}).find("input[name=payment_method]:checked").click(),a("#add_payment_method").submit(function(){a("#add_payment_method").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})}),void a(document.body).trigger("init_add_payment_method"))}); \ No newline at end of file +jQuery(function(a){return"undefined"!=typeof woocommerce_params&&(a("#add_payment_method").on("click init_add_payment_method",".payment_methods input.input-radio",function(){if(a(".payment_methods input.input-radio").length>1){var b=a("div.payment_box."+a(this).attr("ID"));a(this).is(":checked")&&!b.is(":visible")&&(a("div.payment_box").filter(":visible").slideUp(250),a(this).is(":checked")&&a("div.payment_box."+a(this).attr("ID")).slideDown(250))}else a("div.payment_box").show()}).find("input[name=payment_method]:checked").click(),a("#add_payment_method").submit(function(){a("#add_payment_method").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})}),void a(document.body).trigger("init_add_payment_method"))}); \ No newline at end of file diff --git a/assets/js/frontend/add-to-cart.min.js b/assets/js/frontend/add-to-cart.min.js index 521046305b0..74c565f30c7 100644 --- a/assets/js/frontend/add-to-cart.min.js +++ b/assets/js/frontend/add-to-cart.min.js @@ -1,4 +1,4 @@ /*! * WooCommerce Add to Cart JS */ -jQuery(function(a){return"undefined"==typeof wc_add_to_cart_params?!1:void a(document).on("click",".add_to_cart_button",function(){var b=a(this);if(b.is(".ajax_add_to_cart")){if(!b.attr("data-product_id"))return!0;b.removeClass("added"),b.addClass("loading");var c={};return a.each(b.data(),function(a,b){c[a]=b}),a(document.body).trigger("adding_to_cart",[b,c]),a.post(wc_add_to_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","add_to_cart"),c,function(c){if(c){var d=window.location.toString();if(d=d.replace("add-to-cart","added-to-cart"),c.error&&c.product_url)return void(window.location=c.product_url);if("yes"===wc_add_to_cart_params.cart_redirect_after_add)return void(window.location=wc_add_to_cart_params.cart_url);b.removeClass("loading");var e=c.fragments,f=c.cart_hash;e&&a.each(e,function(b){a(b).addClass("updating")}),a(".shop_table.cart, .updating, .cart_totals").fadeTo("400","0.6").block({message:null,overlayCSS:{opacity:.6}}),b.addClass("added"),wc_add_to_cart_params.is_cart||0!==b.parent().find(".added_to_cart").length||b.after(' '+wc_add_to_cart_params.i18n_view_cart+""),e&&a.each(e,function(b,c){a(b).replaceWith(c)}),a(".widget_shopping_cart, .updating").stop(!0).css("opacity","1").unblock(),a(".shop_table.cart").load(d+" .shop_table.cart:eq(0) > *",function(){a(".shop_table.cart").stop(!0).css("opacity","1").unblock(),a(document.body).trigger("cart_page_refreshed")}),a(".cart_totals").load(d+" .cart_totals:eq(0) > *",function(){a(".cart_totals").stop(!0).css("opacity","1").unblock()}),a(document.body).trigger("added_to_cart",[e,f,b])}}),!1}return!0})}); \ No newline at end of file +jQuery(function(a){return"undefined"!=typeof wc_add_to_cart_params&&void a(document).on("click",".add_to_cart_button",function(){var b=a(this);if(b.is(".ajax_add_to_cart")){if(!b.attr("data-product_id"))return!0;b.removeClass("added"),b.addClass("loading");var c={};return a.each(b.data(),function(a,b){c[a]=b}),a(document.body).trigger("adding_to_cart",[b,c]),a.post(wc_add_to_cart_params.wc_ajax_url.toString().replace("%%endpoint%%","add_to_cart"),c,function(c){if(c){var d=window.location.toString();if(d=d.replace("add-to-cart","added-to-cart"),c.error&&c.product_url)return void(window.location=c.product_url);if("yes"===wc_add_to_cart_params.cart_redirect_after_add)return void(window.location=wc_add_to_cart_params.cart_url);b.removeClass("loading");var e=c.fragments,f=c.cart_hash;e&&a.each(e,function(b){a(b).addClass("updating")}),a(".shop_table.cart, .updating, .cart_totals").fadeTo("400","0.6").block({message:null,overlayCSS:{opacity:.6}}),b.addClass("added"),wc_add_to_cart_params.is_cart||0!==b.parent().find(".added_to_cart").length||b.after(' '+wc_add_to_cart_params.i18n_view_cart+""),e&&a.each(e,function(b,c){a(b).replaceWith(c)}),a(".widget_shopping_cart, .updating").stop(!0).css("opacity","1").unblock(),a(".shop_table.cart").load(d+" .shop_table.cart:eq(0) > *",function(){a(".shop_table.cart").stop(!0).css("opacity","1").unblock(),a(document.body).trigger("cart_page_refreshed")}),a(".cart_totals").load(d+" .cart_totals:eq(0) > *",function(){a(".cart_totals").stop(!0).css("opacity","1").unblock()}),a(document.body).trigger("added_to_cart",[e,f,b])}}),!1}return!0})}); \ No newline at end of file diff --git a/assets/js/frontend/cart-fragments.min.js b/assets/js/frontend/cart-fragments.min.js index 745b88e995a..9610e92e8fe 100644 --- a/assets/js/frontend/cart-fragments.min.js +++ b/assets/js/frontend/cart-fragments.min.js @@ -1 +1 @@ -jQuery(function(a){function b(){e&&sessionStorage.setItem("wc_cart_created",(new Date).getTime())}function c(a){e&&(localStorage.setItem(f,a),sessionStorage.setItem(f,a))}function d(){a.ajax(h)}if("undefined"==typeof wc_cart_fragments_params)return!1;var e,f=wc_cart_fragments_params.ajax_url.toString()+"-wc_cart_hash";try{e="sessionStorage"in window&&null!==window.sessionStorage,window.sessionStorage.setItem("wc","test"),window.sessionStorage.removeItem("wc"),window.localStorage.setItem("wc","test"),window.localStorage.removeItem("wc")}catch(g){e=!1}var h={url:wc_cart_fragments_params.wc_ajax_url.toString().replace("%%endpoint%%","get_refreshed_fragments"),type:"POST",success:function(d){d&&d.fragments&&(a.each(d.fragments,function(b,c){a(b).replaceWith(c)}),e&&(sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(d.fragments)),c(d.cart_hash),d.cart_hash&&b()),a(document.body).trigger("wc_fragments_refreshed"))}};if(e){var i=null,j=864e5;a(document.body).bind("wc_fragment_refresh updated_wc_div",function(){d()}),a(document.body).bind("added_to_cart",function(a,d,e){var g=sessionStorage.getItem(f);null!==g&&void 0!==g&&""!==g||b(),sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(d)),c(e)}),a(document.body).bind("wc_fragments_refreshed",function(){clearTimeout(i),i=setTimeout(d,j)}),a(window).on("storage onstorage",function(a){f===a.originalEvent.key&&localStorage.getItem(f)!==sessionStorage.getItem(f)&&d()});try{var k=a.parseJSON(sessionStorage.getItem(wc_cart_fragments_params.fragment_name)),l=sessionStorage.getItem(f),m=a.cookie("woocommerce_cart_hash"),n=sessionStorage.getItem("wc_cart_created");if(null!==l&&void 0!==l&&""!==l||(l=""),null!==m&&void 0!==m&&""!==m||(m=""),l&&(null===n||void 0===n||""===n))throw"No cart_created";if(n){var o=1*n+j,p=(new Date).getTime();if(p>o)throw"Fragment expired";i=setTimeout(d,o-p)}if(!k||!k["div.widget_shopping_cart_content"]||l!==m)throw"No fragment";a.each(k,function(b,c){a(b).replaceWith(c)}),a(document.body).trigger("wc_fragments_loaded")}catch(g){d()}}else d();a.cookie("woocommerce_items_in_cart")>0?a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").show():a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").hide(),a(document.body).bind("adding_to_cart",function(){a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").show()})}); \ No newline at end of file +jQuery(function(a){function b(){e&&sessionStorage.setItem("wc_cart_created",(new Date).getTime())}function c(a){e&&(localStorage.setItem(f,a),sessionStorage.setItem(f,a))}function d(){a.ajax(h)}if("undefined"==typeof wc_cart_fragments_params)return!1;var e,f=wc_cart_fragments_params.ajax_url.toString()+"-wc_cart_hash";try{e="sessionStorage"in window&&null!==window.sessionStorage,window.sessionStorage.setItem("wc","test"),window.sessionStorage.removeItem("wc"),window.localStorage.setItem("wc","test"),window.localStorage.removeItem("wc")}catch(g){e=!1}var h={url:wc_cart_fragments_params.wc_ajax_url.toString().replace("%%endpoint%%","get_refreshed_fragments"),type:"POST",success:function(d){d&&d.fragments&&(a.each(d.fragments,function(b,c){a(b).replaceWith(c)}),e&&(sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(d.fragments)),c(d.cart_hash),d.cart_hash&&b()),a(document.body).trigger("wc_fragments_refreshed"))}};if(e){var i=null,j=864e5;a(document.body).bind("wc_fragment_refresh updated_wc_div",function(){d()}),a(document.body).bind("added_to_cart",function(a,d,e){var g=sessionStorage.getItem(f);null!==g&&void 0!==g&&""!==g||b(),sessionStorage.setItem(wc_cart_fragments_params.fragment_name,JSON.stringify(d)),c(e)}),a(document.body).bind("wc_fragments_refreshed",function(){clearTimeout(i),i=setTimeout(d,j)}),a(window).on("storage onstorage",function(a){f===a.originalEvent.key&&localStorage.getItem(f)!==sessionStorage.getItem(f)&&d()});try{var k=a.parseJSON(sessionStorage.getItem(wc_cart_fragments_params.fragment_name)),l=sessionStorage.getItem(f),m=a.cookie("woocommerce_cart_hash"),n=sessionStorage.getItem("wc_cart_created");if(null!==l&&void 0!==l&&""!==l||(l=""),null!==m&&void 0!==m&&""!==m||(m=""),l&&(null===n||void 0===n||""===n))throw"No cart_created";if(n){var o=1*n+j,p=(new Date).getTime();if(o0?a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").show():a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").hide(),a(document.body).bind("adding_to_cart",function(){a(".hide_cart_widget_if_empty").closest(".widget_shopping_cart").show()})}); \ No newline at end of file diff --git a/assets/js/frontend/cart.min.js b/assets/js/frontend/cart.min.js index dd959fb69c6..95c9cc6e6c6 100644 --- a/assets/js/frontend/cart.min.js +++ b/assets/js/frontend/cart.min.js @@ -1 +1 @@ -jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")||a.parents(".processing").length},d=function(a){c(a)||a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a(".shop_table.cart",c).closest("form"),e=a(".cart_totals",c),f=a(".woocommerce-error",c),i=a(".woocommerce-message",c);if(a(".woocommerce-error, .woocommerce-message").remove(),0===d.length){if(a(".woocommerce-checkout").length)return void window.location.reload();var j=a(".cart-empty",c).closest(".woocommerce");a(".shop_table.cart").closest(".woocommerce").replaceWith(j),f.length>0?h(f,a(".cart-empty").closest(".woocommerce")):i.length>0&&h(i,a(".cart-empty").closest(".woocommerce"))}else a(".woocommerce-checkout").length&&a(document.body).trigger("update_checkout"),a(".shop_table.cart").closest("form").replaceWith(d),a(".shop_table.cart").closest("form").find('input[name="update_cart"]').prop("disabled",!0),f.length>0?h(f):i.length>0&&h(i),g(e);a(document.body).trigger("updated_wc_div")},g=function(b){a(".cart_totals").replaceWith(b),a(document.body).trigger("updated_cart_totals")},h=function(b,c){c||(c=a(".shop_table.cart").closest("form")),a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)},i={init:function(b){this.cart=b,this.toggle_shipping=this.toggle_shipping.bind(this),this.shipping_method_selected=this.shipping_method_selected.bind(this),this.shipping_calculator_submit=this.shipping_calculator_submit.bind(this),a(document).on("click",".shipping-calculator-button",this.toggle_shipping),a(document).on("change","select.shipping_method, input[name^=shipping_method]",this.shipping_method_selected),a(document).on("submit","form.woocommerce-shipping-calculator",this.shipping_calculator_submit),a(".shipping-calculator-form").hide()},toggle_shipping:function(){return a(".shipping-calculator-form").slideToggle("slow"),!1},shipping_method_selected:function(c){var f=c.currentTarget,h={};a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){h[a(f).data("index")]=a(f).val()}),d(a("div.cart_totals"));var i={security:wc_cart_params.update_shipping_method_nonce,shipping_method:h};a.ajax({type:"post",url:b("update_shipping_method"),data:i,dataType:"html",success:function(a){g(a)},complete:function(){e(a("div.cart_totals")),a(document.body).trigger("updated_shipping_method")}})},shipping_calculator_submit:function(b){b.preventDefault();var c=a(b.currentTarget);d(a("div.cart_totals")),d(c),a("").attr("type","hidden").attr("name","calc_shipping").attr("value","x").appendTo(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:function(a){f(a)},complete:function(){e(c),e(a("div.cart_totals"))}})}},j={init:function(){this.update_cart_totals=this.update_cart_totals.bind(this),this.cart_submit=this.cart_submit.bind(this),this.submit_click=this.submit_click.bind(this),this.apply_coupon=this.apply_coupon.bind(this),this.remove_coupon_clicked=this.remove_coupon_clicked.bind(this),this.quantity_update=this.quantity_update.bind(this),this.item_remove_clicked=this.item_remove_clicked.bind(this),this.update_cart=this.update_cart.bind(this),a(document).on("wc_update_cart",this.update_cart),a(document).on("click","div.woocommerce > form input[type=submit]",this.submit_click),a(document).on("submit","div.woocommerce > form",this.cart_submit),a(document).on("click","a.woocommerce-remove-coupon",this.remove_coupon_clicked),a(document).on("click","td.product-remove > a",this.item_remove_clicked),a(document).on("change input","div.woocommerce > form .cart_item :input",this.input_changed),a('div.woocommerce > form input[name="update_cart"]').prop("disabled",!0)},input_changed:function(){a('div.woocommerce > form input[name="update_cart"]').prop("disabled",!1)},update_cart:function(){var b=a(".shop_table.cart").closest("form");d(b),d(a("div.cart_totals")),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:function(a){f(a)},complete:function(){e(b),e(a("div.cart_totals"))}})},update_cart_totals:function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(a){g(a)},complete:function(){e(a("div.cart_totals"))}})},cart_submit:function(b){var d=a(b.currentTarget),e=a(document.activeElement),f=a("input[type=submit][clicked=true]");return 0===d.find(".shop_table.cart").length?!1:c(d)?!1:void(f.is('[name="update_cart"]')||e.is("input.qty")?(b.preventDefault(),this.quantity_update(d)):(f.is('[name="apply_coupon"]')||e.is("#coupon_code"))&&(b.preventDefault(),this.apply_coupon(d)))},submit_click:function(b){a("input[type=submit]",a(b.target).parents("form")).removeAttr("clicked"),a(b.target).attr("clicked","true")},apply_coupon:function(c){d(c);var f=this,g=a("#coupon_code"),i=g.val(),j={security:wc_cart_params.apply_coupon_nonce,coupon_code:i};a.ajax({type:"POST",url:b("apply_coupon"),data:j,dataType:"html",success:function(b){h(b),a(document.body).trigger("applied_coupon")},complete:function(){e(c),g.val(""),f.update_cart_totals()}})},remove_coupon_clicked:function(c){c.preventDefault();var f=this,g=a(c.currentTarget).parents("tr"),i=a(c.currentTarget).attr("data-coupon");d(g.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(b){h(b),a(document.body).trigger("removed_coupon"),e(g.parents("table"))},complete:function(){f.update_cart_totals()}})},quantity_update:function(b){a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(b),d(b),d(a("div.cart_totals")),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:f,complete:function(){e(b),e(a("div.cart_totals"))}})},item_remove_clicked:function(b){b.preventDefault();var c=a(b.currentTarget),g=c.parents("form");d(g),d(a("div.cart_totals")),a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f,complete:function(){e(g),e(a("div.cart_totals"))}})}};i.init(j),j.init()}); \ No newline at end of file +jQuery(function(a){if("undefined"==typeof wc_cart_params)return!1;var b=function(a){return wc_cart_params.wc_ajax_url.toString().replace("%%endpoint%%",a)},c=function(a){return a.is(".processing")||a.parents(".processing").length},d=function(a){c(a)||a.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}})},e=function(a){a.removeClass("processing").unblock()},f=function(b){var c=a.parseHTML(b),d=a(".shop_table.cart",c).closest("form"),e=a(".cart_totals",c),f=a(".woocommerce-error",c),i=a(".woocommerce-message",c);if(a(".woocommerce-error, .woocommerce-message").remove(),0===d.length){if(a(".woocommerce-checkout").length)return void window.location.reload();var j=a(".cart-empty",c).closest(".woocommerce");a(".shop_table.cart").closest(".woocommerce").replaceWith(j),f.length>0?h(f,a(".cart-empty").closest(".woocommerce")):i.length>0&&h(i,a(".cart-empty").closest(".woocommerce"))}else a(".woocommerce-checkout").length&&a(document.body).trigger("update_checkout"),a(".shop_table.cart").closest("form").replaceWith(d),a(".shop_table.cart").closest("form").find('input[name="update_cart"]').prop("disabled",!0),f.length>0?h(f):i.length>0&&h(i),g(e);a(document.body).trigger("updated_wc_div")},g=function(b){a(".cart_totals").replaceWith(b),a(document.body).trigger("updated_cart_totals")},h=function(b,c){c||(c=a(".shop_table.cart").closest("form")),a(".woocommerce-error, .woocommerce-message").remove(),c.before(b)},i={init:function(b){this.cart=b,this.toggle_shipping=this.toggle_shipping.bind(this),this.shipping_method_selected=this.shipping_method_selected.bind(this),this.shipping_calculator_submit=this.shipping_calculator_submit.bind(this),a(document).on("click",".shipping-calculator-button",this.toggle_shipping),a(document).on("change","select.shipping_method, input[name^=shipping_method]",this.shipping_method_selected),a(document).on("submit","form.woocommerce-shipping-calculator",this.shipping_calculator_submit),a(".shipping-calculator-form").hide()},toggle_shipping:function(){return a(".shipping-calculator-form").slideToggle("slow"),!1},shipping_method_selected:function(c){var f=c.currentTarget,h={};a("select.shipping_method, input[name^=shipping_method][type=radio]:checked, input[name^=shipping_method][type=hidden]").each(function(){h[a(f).data("index")]=a(f).val()}),d(a("div.cart_totals"));var i={security:wc_cart_params.update_shipping_method_nonce,shipping_method:h};a.ajax({type:"post",url:b("update_shipping_method"),data:i,dataType:"html",success:function(a){g(a)},complete:function(){e(a("div.cart_totals")),a(document.body).trigger("updated_shipping_method")}})},shipping_calculator_submit:function(b){b.preventDefault();var c=a(b.currentTarget);d(a("div.cart_totals")),d(c),a("").attr("type","hidden").attr("name","calc_shipping").attr("value","x").appendTo(c),a.ajax({type:c.attr("method"),url:c.attr("action"),data:c.serialize(),dataType:"html",success:function(a){f(a)},complete:function(){e(c),e(a("div.cart_totals"))}})}},j={init:function(){this.update_cart_totals=this.update_cart_totals.bind(this),this.cart_submit=this.cart_submit.bind(this),this.submit_click=this.submit_click.bind(this),this.apply_coupon=this.apply_coupon.bind(this),this.remove_coupon_clicked=this.remove_coupon_clicked.bind(this),this.quantity_update=this.quantity_update.bind(this),this.item_remove_clicked=this.item_remove_clicked.bind(this),this.update_cart=this.update_cart.bind(this),a(document).on("wc_update_cart",this.update_cart),a(document).on("click","div.woocommerce > form input[type=submit]",this.submit_click),a(document).on("submit","div.woocommerce > form",this.cart_submit),a(document).on("click","a.woocommerce-remove-coupon",this.remove_coupon_clicked),a(document).on("click","td.product-remove > a",this.item_remove_clicked),a(document).on("change input","div.woocommerce > form .cart_item :input",this.input_changed),a('div.woocommerce > form input[name="update_cart"]').prop("disabled",!0)},input_changed:function(){a('div.woocommerce > form input[name="update_cart"]').prop("disabled",!1)},update_cart:function(){var b=a(".shop_table.cart").closest("form");d(b),d(a("div.cart_totals")),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:function(a){f(a)},complete:function(){e(b),e(a("div.cart_totals"))}})},update_cart_totals:function(){d(a("div.cart_totals")),a.ajax({url:b("get_cart_totals"),dataType:"html",success:function(a){g(a)},complete:function(){e(a("div.cart_totals"))}})},cart_submit:function(b){var d=a(b.currentTarget),e=a(document.activeElement),f=a("input[type=submit][clicked=true]");return 0!==d.find(".shop_table.cart").length&&(!c(d)&&void(f.is('[name="update_cart"]')||e.is("input.qty")?(b.preventDefault(),this.quantity_update(d)):(f.is('[name="apply_coupon"]')||e.is("#coupon_code"))&&(b.preventDefault(),this.apply_coupon(d))))},submit_click:function(b){a("input[type=submit]",a(b.target).parents("form")).removeAttr("clicked"),a(b.target).attr("clicked","true")},apply_coupon:function(c){d(c);var f=this,g=a("#coupon_code"),i=g.val(),j={security:wc_cart_params.apply_coupon_nonce,coupon_code:i};a.ajax({type:"POST",url:b("apply_coupon"),data:j,dataType:"html",success:function(b){h(b),a(document.body).trigger("applied_coupon")},complete:function(){e(c),g.val(""),f.update_cart_totals()}})},remove_coupon_clicked:function(c){c.preventDefault();var f=this,g=a(c.currentTarget).parents("tr"),i=a(c.currentTarget).attr("data-coupon");d(g.parents("table"));var j={security:wc_cart_params.remove_coupon_nonce,coupon:i};a.ajax({type:"POST",url:b("remove_coupon"),data:j,dataType:"html",success:function(b){h(b),a(document.body).trigger("removed_coupon"),e(g.parents("table"))},complete:function(){f.update_cart_totals()}})},quantity_update:function(b){a("").attr("type","hidden").attr("name","update_cart").attr("value","Update Cart").appendTo(b),d(b),d(a("div.cart_totals")),a.ajax({type:b.attr("method"),url:b.attr("action"),data:b.serialize(),dataType:"html",success:f,complete:function(){e(b),e(a("div.cart_totals"))}})},item_remove_clicked:function(b){b.preventDefault();var c=a(b.currentTarget),g=c.parents("form");d(g),d(a("div.cart_totals")),a.ajax({type:"GET",url:c.attr("href"),dataType:"html",success:f,complete:function(){e(g),e(a("div.cart_totals"))}})}};i.init(j),j.init()}); \ No newline at end of file diff --git a/assets/js/frontend/checkout.min.js b/assets/js/frontend/checkout.min.js index 338826e03cc..8d2f95faee9 100644 --- a/assets/js/frontend/checkout.min.js +++ b/assets/js/frontend/checkout.min.js @@ -1 +1 @@ -jQuery(function(a){if("undefined"==typeof wc_checkout_params)return!1;a.blockUI.defaults.overlayCSS.cursor="default";var b={updateTimer:!1,dirtyInput:!1,xhr:!1,$order_review:a("#order_review"),$checkout_form:a("form.checkout"),init:function(){a(document.body).bind("update_checkout",this.update_checkout),a(document.body).bind("init_checkout",this.init_checkout),this.$checkout_form.on("click",'input[name="payment_method"]',this.payment_method_selected),a(document.body).hasClass("woocommerce-order-pay")&&this.$order_review.on("click",'input[name="payment_method"]',this.payment_method_selected),this.$checkout_form.on("submit",this.submit),this.$checkout_form.on("blur change",".input-text, select",this.validate_field),this.$checkout_form.on("update",this.trigger_update_checkout),this.$checkout_form.on("change",'select.shipping_method, input[name^="shipping_method"], #ship-to-different-address input, .update_totals_on_change select, .update_totals_on_change input[type="radio"]',this.trigger_update_checkout),this.$checkout_form.on("change",".address-field select",this.input_changed),this.$checkout_form.on("change",".address-field input.input-text, .update_totals_on_change input.input-text",this.maybe_input_changed),this.$checkout_form.on("change keydown",".address-field input.input-text, .update_totals_on_change input.input-text",this.queue_update_checkout),this.$checkout_form.on("change","#ship-to-different-address input",this.ship_to_different_address),this.$checkout_form.find("#ship-to-different-address input").change(),this.init_payment_methods(),"1"===wc_checkout_params.is_checkout&&a(document.body).trigger("init_checkout"),"yes"===wc_checkout_params.option_guest_checkout&&a("input#createaccount").change(this.toggle_create_account).change()},init_payment_methods:function(){var b=a(".woocommerce-checkout").find('input[name="payment_method"]');1===b.length&&b.eq(0).hide(),0===b.filter(":checked").length&&b.eq(0).prop("checked",!0),b.filter(":checked").eq(0).trigger("click")},get_payment_method:function(){return b.$order_review.find('input[name="payment_method"]:checked').val()},payment_method_selected:function(){if(a(".payment_methods input.input-radio").length>1){var b=a("div.payment_box."+a(this).attr("ID"));a(this).is(":checked")&&!b.is(":visible")&&(a("div.payment_box").filter(":visible").slideUp(250),a(this).is(":checked")&&a("div.payment_box."+a(this).attr("ID")).slideDown(250))}else a("div.payment_box").show();a(this).data("order_button_text")?a("#place_order").val(a(this).data("order_button_text")):a("#place_order").val(a("#place_order").data("value"))},toggle_create_account:function(){a("div.create-account").hide(),a(this).is(":checked")&&a("div.create-account").slideDown()},init_checkout:function(){a("#billing_country, #shipping_country, .country_to_state").change(),a(document.body).trigger("update_checkout")},maybe_input_changed:function(a){b.dirtyInput&&b.input_changed(a)},input_changed:function(a){b.dirtyInput=a.target,b.maybe_update_checkout()},queue_update_checkout:function(a){var c=a.keyCode||a.which||0;return 9===c?!0:(b.dirtyInput=this,b.reset_update_checkout_timer(),void(b.updateTimer=setTimeout(b.maybe_update_checkout,"1000")))},trigger_update_checkout:function(){b.reset_update_checkout_timer(),b.dirtyInput=!1,a(document.body).trigger("update_checkout")},maybe_update_checkout:function(){var c=!0;if(a(b.dirtyInput).length){var d=a(b.dirtyInput).closest("div").find(".address-field.validate-required");d.length&&d.each(function(){""===a(this).find("input.input-text").val()&&(c=!1)})}c&&b.trigger_update_checkout()},ship_to_different_address:function(){a("div.shipping_address").hide(),a(this).is(":checked")&&a("div.shipping_address").slideDown()},reset_update_checkout_timer:function(){clearTimeout(b.updateTimer)},validate_field:function(){var b=a(this),c=b.closest(".form-row"),d=!0;if(c.is(".validate-required")&&("checkbox"!==b.attr("type")||b.is(":checked")?""===b.val()&&(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-required-field"),d=!1):(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-required-field"),d=!1)),c.is(".validate-email")&&b.val()){var e=new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);e.test(b.val())||(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-email"),d=!1)}d&&c.removeClass("woocommerce-invalid woocommerce-invalid-required-field").addClass("woocommerce-validated")},update_checkout:function(a,c){b.reset_update_checkout_timer(),b.updateTimer=setTimeout(b.update_checkout_action,"5",c)},update_checkout_action:function(c){if(b.xhr&&b.xhr.abort(),0!==a("form.checkout").length){c="undefined"!=typeof c?c:{update_shipping_method:!0};var d=a("#billing_country").val(),e=a("#billing_state").val(),f=a("input#billing_postcode").val(),g=a("#billing_city").val(),h=a("input#billing_address_1").val(),i=a("input#billing_address_2").val(),j=d,k=e,l=f,m=g,n=h,o=i;a("#ship-to-different-address").find("input").is(":checked")&&(j=a("#shipping_country").val(),k=a("#shipping_state").val(),l=a("input#shipping_postcode").val(),m=a("#shipping_city").val(),n=a("input#shipping_address_1").val(),o=a("input#shipping_address_2").val());var p={security:wc_checkout_params.update_order_review_nonce,payment_method:b.get_payment_method(),country:d,state:e,postcode:f,city:g,address:h,address_2:i,s_country:j,s_state:k,s_postcode:l,s_city:m,s_address:n,s_address_2:o,post_data:a("form.checkout").serialize()};if(!1!==c.update_shipping_method){var q={};a('select.shipping_method, input[name^="shipping_method"][type="radio"]:checked, input[name^="shipping_method"][type="hidden"]').each(function(){q[a(this).data("index")]=a(this).val()}),p.shipping_method=q}a(".woocommerce-checkout-payment, .woocommerce-checkout-review-order-table").block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),b.xhr=a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","update_order_review"),data:p,success:function(c){if("true"===c.reload)return void window.location.reload();a(".woocommerce-NoticeGroup-updateOrderReview").remove();var d=a("#terms").prop("checked");if(c&&c.fragments&&a.each(c.fragments,function(b,c){a(b).replaceWith(c),a(b).unblock()}),d&&a("#terms").prop("checked",!0),"failure"===c.result){var e=a("form.checkout");a(".woocommerce-error, .woocommerce-message").remove(),c.messages?e.prepend('
    '+c.messages+"
    "):e.prepend(c),e.find(".input-text, select").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3)}b.init_payment_methods(),a(document.body).trigger("updated_checkout")}})}},submit:function(){b.reset_update_checkout_timer();var c=a(this);if(c.is(".processing"))return!1;if(c.triggerHandler("checkout_place_order")!==!1&&c.triggerHandler("checkout_place_order_"+b.get_payment_method())!==!1){c.addClass("processing");var d=c.data();1!==d["blockUI.isBlocked"]&&c.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),a.ajaxSetup({dataFilter:function(b,c){if("json"!==c)return b;try{var d=a.parseJSON(b);if(d&&"object"==typeof d)return b}catch(e){var f=b.match(/{"result.*"}/);null===f?console.log("Unable to fix malformed JSON"):(console.log("Fixed malformed JSON. Original:"),console.log(b),b=f[0])}return b}}),a.ajax({type:"POST",url:wc_checkout_params.checkout_url,data:c.serialize(),dataType:"json",success:function(c){try{if("success"!==c.result)throw"failure"===c.result?"Result failure":"Invalid response";-1===c.redirect.indexOf("https://")||-1===c.redirect.indexOf("http://")?window.location=c.redirect:window.location=decodeURI(c.redirect)}catch(d){if("true"===c.reload)return void window.location.reload();"true"===c.refresh&&a(document.body).trigger("update_checkout"),c.messages?b.submit_error(c.messages):b.submit_error('
    '+wc_checkout_params.i18n_checkout_error+"
    ")}},error:function(a,c,d){b.submit_error('
    '+d+"
    ")}})}return!1},submit_error:function(c){a(".woocommerce-error, .woocommerce-message").remove(),b.$checkout_form.prepend(c),b.$checkout_form.removeClass("processing").unblock(),b.$checkout_form.find(".input-text, select").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3),a(document.body).trigger("checkout_error")}},c={init:function(){a(document.body).on("click","a.showcoupon",this.show_coupon_form),a(document.body).on("click",".woocommerce-remove-coupon",this.remove_coupon),a("form.checkout_coupon").hide().submit(this.submit)},show_coupon_form:function(){return a(".checkout_coupon").slideToggle(400,function(){a(".checkout_coupon").find(":input:eq(0)").focus()}),!1},submit:function(){var b=a(this);if(b.is(".processing"))return!1;b.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={security:wc_checkout_params.apply_coupon_nonce,coupon_code:b.find('input[name="coupon_code"]').val()};return a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),data:c,success:function(c){a(".woocommerce-error, .woocommerce-message").remove(),b.removeClass("processing").unblock(),c&&(b.before(c),b.slideUp(),a(document.body).trigger("update_checkout",{update_shipping_method:!1}))},dataType:"html"}),!1},remove_coupon:function(b){b.preventDefault();var c=a(this).parents(".woocommerce-checkout-review-order"),d=a(this).data("coupon");c.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var e={security:wc_checkout_params.remove_coupon_nonce,coupon:d};a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","remove_coupon"),data:e,success:function(b){a(".woocommerce-error, .woocommerce-message").remove(),c.removeClass("processing").unblock(),b&&(a("form.woocommerce-checkout").before(b),a(document.body).trigger("update_checkout",{update_shipping_method:!1}),a("form.checkout_coupon").find('input[name="coupon_code"]').val(""))},error:function(a){wc_checkout_params.debug_mode&&console.log(a.responseText)},dataType:"html"})}},d={init:function(){a(document.body).on("click","a.showlogin",this.show_login_form)},show_login_form:function(){return a("form.login").slideToggle(),!1}};b.init(),c.init(),d.init()}); \ No newline at end of file +jQuery(function(a){if("undefined"==typeof wc_checkout_params)return!1;a.blockUI.defaults.overlayCSS.cursor="default";var b={updateTimer:!1,dirtyInput:!1,xhr:!1,$order_review:a("#order_review"),$checkout_form:a("form.checkout"),init:function(){a(document.body).bind("update_checkout",this.update_checkout),a(document.body).bind("init_checkout",this.init_checkout),this.$checkout_form.on("click",'input[name="payment_method"]',this.payment_method_selected),a(document.body).hasClass("woocommerce-order-pay")&&this.$order_review.on("click",'input[name="payment_method"]',this.payment_method_selected),this.$checkout_form.on("submit",this.submit),this.$checkout_form.on("blur change",".input-text, select",this.validate_field),this.$checkout_form.on("update",this.trigger_update_checkout),this.$checkout_form.on("change",'select.shipping_method, input[name^="shipping_method"], #ship-to-different-address input, .update_totals_on_change select, .update_totals_on_change input[type="radio"]',this.trigger_update_checkout),this.$checkout_form.on("change",".address-field select",this.input_changed),this.$checkout_form.on("change",".address-field input.input-text, .update_totals_on_change input.input-text",this.maybe_input_changed),this.$checkout_form.on("change keydown",".address-field input.input-text, .update_totals_on_change input.input-text",this.queue_update_checkout),this.$checkout_form.on("change","#ship-to-different-address input",this.ship_to_different_address),this.$checkout_form.find("#ship-to-different-address input").change(),this.init_payment_methods(),"1"===wc_checkout_params.is_checkout&&a(document.body).trigger("init_checkout"),"yes"===wc_checkout_params.option_guest_checkout&&a("input#createaccount").change(this.toggle_create_account).change()},init_payment_methods:function(){var b=a(".woocommerce-checkout").find('input[name="payment_method"]');1===b.length&&b.eq(0).hide(),0===b.filter(":checked").length&&b.eq(0).prop("checked",!0),b.filter(":checked").eq(0).trigger("click")},get_payment_method:function(){return b.$order_review.find('input[name="payment_method"]:checked').val()},payment_method_selected:function(){if(a(".payment_methods input.input-radio").length>1){var b=a("div.payment_box."+a(this).attr("ID"));a(this).is(":checked")&&!b.is(":visible")&&(a("div.payment_box").filter(":visible").slideUp(250),a(this).is(":checked")&&a("div.payment_box."+a(this).attr("ID")).slideDown(250))}else a("div.payment_box").show();a(this).data("order_button_text")?a("#place_order").val(a(this).data("order_button_text")):a("#place_order").val(a("#place_order").data("value"))},toggle_create_account:function(){a("div.create-account").hide(),a(this).is(":checked")&&a("div.create-account").slideDown()},init_checkout:function(){a("#billing_country, #shipping_country, .country_to_state").change(),a(document.body).trigger("update_checkout")},maybe_input_changed:function(a){b.dirtyInput&&b.input_changed(a)},input_changed:function(a){b.dirtyInput=a.target,b.maybe_update_checkout()},queue_update_checkout:function(a){var c=a.keyCode||a.which||0;return 9===c||(b.dirtyInput=this,b.reset_update_checkout_timer(),void(b.updateTimer=setTimeout(b.maybe_update_checkout,"1000")))},trigger_update_checkout:function(){b.reset_update_checkout_timer(),b.dirtyInput=!1,a(document.body).trigger("update_checkout")},maybe_update_checkout:function(){var c=!0;if(a(b.dirtyInput).length){var d=a(b.dirtyInput).closest("div").find(".address-field.validate-required");d.length&&d.each(function(){""===a(this).find("input.input-text").val()&&(c=!1)})}c&&b.trigger_update_checkout()},ship_to_different_address:function(){a("div.shipping_address").hide(),a(this).is(":checked")&&a("div.shipping_address").slideDown()},reset_update_checkout_timer:function(){clearTimeout(b.updateTimer)},validate_field:function(){var b=a(this),c=b.closest(".form-row"),d=!0;if(c.is(".validate-required")&&("checkbox"!==b.attr("type")||b.is(":checked")?""===b.val()&&(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-required-field"),d=!1):(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-required-field"),d=!1)),c.is(".validate-email")&&b.val()){var e=new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);e.test(b.val())||(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-email"),d=!1)}d&&c.removeClass("woocommerce-invalid woocommerce-invalid-required-field").addClass("woocommerce-validated")},update_checkout:function(a,c){b.reset_update_checkout_timer(),b.updateTimer=setTimeout(b.update_checkout_action,"5",c)},update_checkout_action:function(c){if(b.xhr&&b.xhr.abort(),0!==a("form.checkout").length){c="undefined"!=typeof c?c:{update_shipping_method:!0};var d=a("#billing_country").val(),e=a("#billing_state").val(),f=a("input#billing_postcode").val(),g=a("#billing_city").val(),h=a("input#billing_address_1").val(),i=a("input#billing_address_2").val(),j=d,k=e,l=f,m=g,n=h,o=i;a("#ship-to-different-address").find("input").is(":checked")&&(j=a("#shipping_country").val(),k=a("#shipping_state").val(),l=a("input#shipping_postcode").val(),m=a("#shipping_city").val(),n=a("input#shipping_address_1").val(),o=a("input#shipping_address_2").val());var p={security:wc_checkout_params.update_order_review_nonce,payment_method:b.get_payment_method(),country:d,state:e,postcode:f,city:g,address:h,address_2:i,s_country:j,s_state:k,s_postcode:l,s_city:m,s_address:n,s_address_2:o,post_data:a("form.checkout").serialize()};if(!1!==c.update_shipping_method){var q={};a('select.shipping_method, input[name^="shipping_method"][type="radio"]:checked, input[name^="shipping_method"][type="hidden"]').each(function(){q[a(this).data("index")]=a(this).val()}),p.shipping_method=q}a(".woocommerce-checkout-payment, .woocommerce-checkout-review-order-table").block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),b.xhr=a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","update_order_review"),data:p,success:function(c){if("true"===c.reload)return void window.location.reload();a(".woocommerce-NoticeGroup-updateOrderReview").remove();var d=a("#terms").prop("checked");if(c&&c.fragments&&a.each(c.fragments,function(b,c){a(b).replaceWith(c),a(b).unblock()}),d&&a("#terms").prop("checked",!0),"failure"===c.result){var e=a("form.checkout");a(".woocommerce-error, .woocommerce-message").remove(),c.messages?e.prepend('
    '+c.messages+"
    "):e.prepend(c),e.find(".input-text, select").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3)}b.init_payment_methods(),a(document.body).trigger("updated_checkout")}})}},submit:function(){b.reset_update_checkout_timer();var c=a(this);if(c.is(".processing"))return!1;if(c.triggerHandler("checkout_place_order")!==!1&&c.triggerHandler("checkout_place_order_"+b.get_payment_method())!==!1){c.addClass("processing");var d=c.data();1!==d["blockUI.isBlocked"]&&c.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),a.ajaxSetup({dataFilter:function(b,c){if("json"!==c)return b;try{var d=a.parseJSON(b);if(d&&"object"==typeof d)return b}catch(e){var f=b.match(/{"result.*"}/);null===f?console.log("Unable to fix malformed JSON"):(console.log("Fixed malformed JSON. Original:"),console.log(b),b=f[0])}return b}}),a.ajax({type:"POST",url:wc_checkout_params.checkout_url,data:c.serialize(),dataType:"json",success:function(c){try{if("success"!==c.result)throw"failure"===c.result?"Result failure":"Invalid response";-1===c.redirect.indexOf("https://")||-1===c.redirect.indexOf("http://")?window.location=c.redirect:window.location=decodeURI(c.redirect)}catch(d){if("true"===c.reload)return void window.location.reload();"true"===c.refresh&&a(document.body).trigger("update_checkout"),c.messages?b.submit_error(c.messages):b.submit_error('
    '+wc_checkout_params.i18n_checkout_error+"
    ")}},error:function(a,c,d){b.submit_error('
    '+d+"
    ")}})}return!1},submit_error:function(c){a(".woocommerce-error, .woocommerce-message").remove(),b.$checkout_form.prepend(c),b.$checkout_form.removeClass("processing").unblock(),b.$checkout_form.find(".input-text, select").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3),a(document.body).trigger("checkout_error")}},c={init:function(){a(document.body).on("click","a.showcoupon",this.show_coupon_form),a(document.body).on("click",".woocommerce-remove-coupon",this.remove_coupon),a("form.checkout_coupon").hide().submit(this.submit)},show_coupon_form:function(){return a(".checkout_coupon").slideToggle(400,function(){a(".checkout_coupon").find(":input:eq(0)").focus()}),!1},submit:function(){var b=a(this);if(b.is(".processing"))return!1;b.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={security:wc_checkout_params.apply_coupon_nonce,coupon_code:b.find('input[name="coupon_code"]').val()};return a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),data:c,success:function(c){a(".woocommerce-error, .woocommerce-message").remove(),b.removeClass("processing").unblock(),c&&(b.before(c),b.slideUp(),a(document.body).trigger("update_checkout",{update_shipping_method:!1}))},dataType:"html"}),!1},remove_coupon:function(b){b.preventDefault();var c=a(this).parents(".woocommerce-checkout-review-order"),d=a(this).data("coupon");c.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var e={security:wc_checkout_params.remove_coupon_nonce,coupon:d};a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","remove_coupon"),data:e,success:function(b){a(".woocommerce-error, .woocommerce-message").remove(),c.removeClass("processing").unblock(),b&&(a("form.woocommerce-checkout").before(b),a(document.body).trigger("update_checkout",{update_shipping_method:!1}),a("form.checkout_coupon").find('input[name="coupon_code"]').val(""))},error:function(a){wc_checkout_params.debug_mode&&console.log(a.responseText)},dataType:"html"})}},d={init:function(){a(document.body).on("click","a.showlogin",this.show_login_form)},show_login_form:function(){return a("form.login").slideToggle(),!1}};b.init(),c.init(),d.init()}); \ No newline at end of file diff --git a/assets/js/frontend/single-product.min.js b/assets/js/frontend/single-product.min.js index 7f9cce13f12..0ad5ff1f4e8 100644 --- a/assets/js/frontend/single-product.min.js +++ b/assets/js/frontend/single-product.min.js @@ -1 +1 @@ -jQuery(function(a){return"undefined"==typeof wc_single_product_params?!1:(a("body").on("init",".wc-tabs-wrapper, .woocommerce-tabs",function(){a(".wc-tab, .woocommerce-tabs .panel:not(.panel .panel)").hide();var b=window.location.hash,c=window.location.href,d=a(this).find(".wc-tabs, ul.tabs").first();b.toLowerCase().indexOf("comment-")>=0||"#reviews"===b||"#tab-reviews"===b?d.find("li.reviews_tab a").click():c.indexOf("comment-page-")>0||c.indexOf("cpage=")>0?d.find("li.reviews_tab a").click():d.find("li:first a").click()}).on("click",".wc-tabs li a, ul.tabs li a",function(b){b.preventDefault();var c=a(this),d=c.closest(".wc-tabs-wrapper, .woocommerce-tabs"),e=d.find(".wc-tabs, ul.tabs");e.find("li").removeClass("active"),d.find(".wc-tab, .panel:not(.panel .panel)").hide(),c.closest("li").addClass("active"),d.find(c.attr("href")).show()}).on("click","a.woocommerce-review-link",function(){return a(".reviews_tab a").click(),!0}).on("init","#rating",function(){a("#rating").hide().before('

    12345

    ')}).on("click","#respond p.stars a",function(){var b=a(this),c=a(this).closest("#respond").find("#rating"),d=a(this).closest(".stars");return c.val(b.text()),b.siblings("a").removeClass("active"),b.addClass("active"),d.addClass("selected"),!1}).on("click","#respond #submit",function(){var b=a(this).closest("#respond").find("#rating"),c=b.val();return b.length>0&&!c&&"yes"===wc_single_product_params.review_rating_required?(window.alert(wc_single_product_params.i18n_required_rating_text),!1):void 0}),void a(".wc-tabs-wrapper, .woocommerce-tabs, #rating").trigger("init"))}); \ No newline at end of file +jQuery(function(a){return"undefined"!=typeof wc_single_product_params&&(a("body").on("init",".wc-tabs-wrapper, .woocommerce-tabs",function(){a(".wc-tab, .woocommerce-tabs .panel:not(.panel .panel)").hide();var b=window.location.hash,c=window.location.href,d=a(this).find(".wc-tabs, ul.tabs").first();b.toLowerCase().indexOf("comment-")>=0||"#reviews"===b||"#tab-reviews"===b?d.find("li.reviews_tab a").click():c.indexOf("comment-page-")>0||c.indexOf("cpage=")>0?d.find("li.reviews_tab a").click():d.find("li:first a").click()}).on("click",".wc-tabs li a, ul.tabs li a",function(b){b.preventDefault();var c=a(this),d=c.closest(".wc-tabs-wrapper, .woocommerce-tabs"),e=d.find(".wc-tabs, ul.tabs");e.find("li").removeClass("active"),d.find(".wc-tab, .panel:not(.panel .panel)").hide(),c.closest("li").addClass("active"),d.find(c.attr("href")).show()}).on("click","a.woocommerce-review-link",function(){return a(".reviews_tab a").click(),!0}).on("init","#rating",function(){a("#rating").hide().before('

    12345

    ')}).on("click","#respond p.stars a",function(){var b=a(this),c=a(this).closest("#respond").find("#rating"),d=a(this).closest(".stars");return c.val(b.text()),b.siblings("a").removeClass("active"),b.addClass("active"),d.addClass("selected"),!1}).on("click","#respond #submit",function(){var b=a(this).closest("#respond").find("#rating"),c=b.val();if(b.length>0&&!c&&"yes"===wc_single_product_params.review_rating_required)return window.alert(wc_single_product_params.i18n_required_rating_text),!1}),void a(".wc-tabs-wrapper, .woocommerce-tabs, #rating").trigger("init"))}); \ No newline at end of file diff --git a/assets/js/jquery-blockui/jquery.blockUI.min.js b/assets/js/jquery-blockui/jquery.blockUI.min.js index 0571d56cf2c..36dab7dd11b 100644 --- a/assets/js/jquery-blockui/jquery.blockUI.min.js +++ b/assets/js/jquery-blockui/jquery.blockUI.min.js @@ -11,4 +11,4 @@ * * Thanks to Amir-Hossein Sobhi for some excellent contributions! */ -!function(){"use strict";function a(a){function b(b,d){var f,p,q=b==window,r=d&&void 0!==d.message?d.message:void 0;if(d=a.extend({},a.blockUI.defaults,d||{}),!d.ignoreIfBlocked||!a(b).data("blockUI.isBlocked")){if(d.overlayCSS=a.extend({},a.blockUI.defaults.overlayCSS,d.overlayCSS||{}),f=a.extend({},a.blockUI.defaults.css,d.css||{}),d.onOverlayClick&&(d.overlayCSS.cursor="pointer"),p=a.extend({},a.blockUI.defaults.themedCSS,d.themedCSS||{}),r=void 0===r?d.message:r,q&&n&&c(window,{fadeOut:0}),r&&"string"!=typeof r&&(r.parentNode||r.jquery)){var s=r.jquery?r[0]:r,t={};a(b).data("blockUI.history",t),t.el=s,t.parent=s.parentNode,t.display=s.style.display,t.position=s.style.position,t.parent&&t.parent.removeChild(s)}a(b).data("blockUI.onUnblock",d.onUnblock);var u,v,w,x,y=d.baseZ;u=a(k||d.forceIframe?'':''),v=a(d.theme?'':''),d.theme&&q?(x='"):d.theme?(x='"):x=q?'':'',w=a(x),r&&(d.theme?(w.css(p),w.addClass("ui-widget-content")):w.css(f)),d.theme||v.css(d.overlayCSS),v.css("position",q?"fixed":"absolute"),(k||d.forceIframe)&&u.css("opacity",0);var z=[u,v,w],A=a(q?"body":b);a.each(z,function(){this.appendTo(A)}),d.theme&&d.draggable&&a.fn.draggable&&w.draggable({handle:".ui-dialog-titlebar",cancel:"li"});var B=m&&(!a.support.boxModel||a("object,embed",q?null:b).length>0);if(l||B){if(q&&d.allowBodyStretch&&a.support.boxModel&&a("html,body").css("height","100%"),(l||!a.support.boxModel)&&!q)var C=i(b,"borderTopWidth"),D=i(b,"borderLeftWidth"),E=C?"(0 - "+C+")":0,F=D?"(0 - "+D+")":0;a.each(z,function(a,b){var c=b[0].style;if(c.position="absolute",2>a)q?c.setExpression("height","Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:"+d.quirksmodeOffsetHack+') + "px"'):c.setExpression("height",'this.parentNode.offsetHeight + "px"'),q?c.setExpression("width",'jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'):c.setExpression("width",'this.parentNode.offsetWidth + "px"'),F&&c.setExpression("left",F),E&&c.setExpression("top",E);else if(d.centerY)q&&c.setExpression("top",'(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'),c.marginTop=0;else if(!d.centerY&&q){var e=d.css&&d.css.top?parseInt(d.css.top,10):0,f="((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "+e+') + "px"';c.setExpression("top",f)}})}if(r&&(d.theme?w.find(".ui-widget-content").append(r):w.append(r),(r.jquery||r.nodeType)&&a(r).show()),(k||d.forceIframe)&&d.showOverlay&&u.show(),d.fadeIn){var G=d.onBlock?d.onBlock:j,H=d.showOverlay&&!r?G:j,I=r?G:j;d.showOverlay&&v._fadeIn(d.fadeIn,H),r&&w._fadeIn(d.fadeIn,I)}else d.showOverlay&&v.show(),r&&w.show(),d.onBlock&&d.onBlock.bind(w)();if(e(1,b,d),q?(n=w[0],o=a(d.focusableElements,n),d.focusInput&&setTimeout(g,20)):h(w[0],d.centerX,d.centerY),d.timeout){var J=setTimeout(function(){q?a.unblockUI(d):a(b).unblock(d)},d.timeout);a(b).data("blockUI.timeout",J)}}}function c(b,c){var f,g=b==window,h=a(b),i=h.data("blockUI.history"),j=h.data("blockUI.timeout");j&&(clearTimeout(j),h.removeData("blockUI.timeout")),c=a.extend({},a.blockUI.defaults,c||{}),e(0,b,c),null===c.onUnblock&&(c.onUnblock=h.data("blockUI.onUnblock"),h.removeData("blockUI.onUnblock"));var k;k=g?a(document.body).children().filter(".blockUI").add("body > .blockUI"):h.find(">.blockUI"),c.cursorReset&&(k.length>1&&(k[1].style.cursor=c.cursorReset),k.length>2&&(k[2].style.cursor=c.cursorReset)),g&&(n=o=null),c.fadeOut?(f=k.length,k.stop().fadeOut(c.fadeOut,function(){0===--f&&d(k,i,c,b)})):d(k,i,c,b)}function d(b,c,d,e){var f=a(e);if(!f.data("blockUI.isBlocked")){b.each(function(a,b){this.parentNode&&this.parentNode.removeChild(this)}),c&&c.el&&(c.el.style.display=c.display,c.el.style.position=c.position,c.el.style.cursor="default",c.parent&&c.parent.appendChild(c.el),f.removeData("blockUI.history")),f.data("blockUI.static")&&f.css("position","static"),"function"==typeof d.onUnblock&&d.onUnblock(e,d);var g=a(document.body),h=g.width(),i=g[0].style.width;g.width(h-1).width(h),g[0].style.width=i}}function e(b,c,d){var e=c==window,g=a(c);if((b||(!e||n)&&(e||g.data("blockUI.isBlocked")))&&(g.data("blockUI.isBlocked",b),e&&d.bindEvents&&(!b||d.showOverlay))){var h="mousedown mouseup keydown keypress keyup touchstart touchend touchmove";b?a(document).bind(h,d,f):a(document).unbind(h,f)}}function f(b){if("keydown"===b.type&&b.keyCode&&9==b.keyCode&&n&&b.data.constrainTabKey){var c=o,d=!b.shiftKey&&b.target===c[c.length-1],e=b.shiftKey&&b.target===c[0];if(d||e)return setTimeout(function(){g(e)},10),!1}var f=b.data,h=a(b.target);return h.hasClass("blockOverlay")&&f.onOverlayClick&&f.onOverlayClick(b),h.parents("div."+f.blockMsgClass).length>0?!0:0===h.parents().children().filter("div.blockUI").length}function g(a){if(o){var b=o[a===!0?o.length-1:0];b&&b.focus()}}function h(a,b,c){var d=a.parentNode,e=a.style,f=(d.offsetWidth-a.offsetWidth)/2-i(d,"borderLeftWidth"),g=(d.offsetHeight-a.offsetHeight)/2-i(d,"borderTopWidth");b&&(e.left=f>0?f+"px":"0"),c&&(e.top=g>0?g+"px":"0")}function i(b,c){return parseInt(a.css(b,c),10)||0}a.fn._fadeIn=a.fn.fadeIn;var j=a.noop||function(){},k=/MSIE/.test(navigator.userAgent),l=/MSIE 6.0/.test(navigator.userAgent)&&!/MSIE 8.0/.test(navigator.userAgent),m=(document.documentMode||0,a.isFunction(document.createElement("div").style.setExpression));a.blockUI=function(a){b(window,a)},a.unblockUI=function(a){c(window,a)},a.growlUI=function(b,c,d,e){var f=a('
    ');b&&f.append("

    "+b+"

    "),c&&f.append("

    "+c+"

    "),void 0===d&&(d=3e3);var g=function(b){b=b||{},a.blockUI({message:f,fadeIn:"undefined"!=typeof b.fadeIn?b.fadeIn:700,fadeOut:"undefined"!=typeof b.fadeOut?b.fadeOut:1e3,timeout:"undefined"!=typeof b.timeout?b.timeout:d,centerY:!1,showOverlay:!1,onUnblock:e,css:a.blockUI.defaults.growlCSS})};g();f.css("opacity");f.mouseover(function(){g({fadeIn:0,timeout:3e4});var b=a(".blockMsg");b.stop(),b.fadeTo(300,1)}).mouseout(function(){a(".blockMsg").fadeOut(1e3)})},a.fn.block=function(c){if(this[0]===window)return a.blockUI(c),this;var d=a.extend({},a.blockUI.defaults,c||{});return this.each(function(){var b=a(this);d.ignoreIfBlocked&&b.data("blockUI.isBlocked")||b.unblock({fadeOut:0})}),this.each(function(){"static"==a.css(this,"position")&&(this.style.position="relative",a(this).data("blockUI.static",!0)),this.style.zoom=1,b(this,c)})},a.fn.unblock=function(b){return this[0]===window?(a.unblockUI(b),this):this.each(function(){c(this,b)})},a.blockUI.version=2.7,a.blockUI.defaults={message:"

    Please wait...

    ",title:null,draggable:!0,theme:!1,css:{padding:0,margin:0,width:"30%",top:"40%",left:"35%",textAlign:"center",color:"#000",border:"3px solid #aaa",backgroundColor:"#fff",cursor:"wait"},themedCSS:{width:"30%",top:"40%",left:"35%"},overlayCSS:{backgroundColor:"#000",opacity:.6,cursor:"wait"},cursorReset:"default",growlCSS:{width:"350px",top:"10px",left:"",right:"10px",border:"none",padding:"5px",opacity:.6,cursor:"default",color:"#fff",backgroundColor:"#000","-webkit-border-radius":"10px","-moz-border-radius":"10px","border-radius":"10px"},iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank",forceIframe:!1,baseZ:1e3,centerX:!0,centerY:!0,allowBodyStretch:!0,bindEvents:!0,constrainTabKey:!0,fadeIn:200,fadeOut:400,timeout:0,showOverlay:!0,focusInput:!0,focusableElements:":input:enabled:visible",onBlock:null,onUnblock:null,onOverlayClick:null,quirksmodeOffsetHack:4,blockMsgClass:"blockMsg",ignoreIfBlocked:!1};var n=null,o=[]}"function"==typeof define&&define.amd&&define.amd.jQuery?define(["jquery"],a):a(jQuery)}(); \ No newline at end of file +!function(){"use strict";function a(a){function b(b,d){var f,p,q=b==window,r=d&&void 0!==d.message?d.message:void 0;if(d=a.extend({},a.blockUI.defaults,d||{}),!d.ignoreIfBlocked||!a(b).data("blockUI.isBlocked")){if(d.overlayCSS=a.extend({},a.blockUI.defaults.overlayCSS,d.overlayCSS||{}),f=a.extend({},a.blockUI.defaults.css,d.css||{}),d.onOverlayClick&&(d.overlayCSS.cursor="pointer"),p=a.extend({},a.blockUI.defaults.themedCSS,d.themedCSS||{}),r=void 0===r?d.message:r,q&&n&&c(window,{fadeOut:0}),r&&"string"!=typeof r&&(r.parentNode||r.jquery)){var s=r.jquery?r[0]:r,t={};a(b).data("blockUI.history",t),t.el=s,t.parent=s.parentNode,t.display=s.style.display,t.position=s.style.position,t.parent&&t.parent.removeChild(s)}a(b).data("blockUI.onUnblock",d.onUnblock);var u,v,w,x,y=d.baseZ;u=a(k||d.forceIframe?'':''),v=a(d.theme?'':''),d.theme&&q?(x='"):d.theme?(x='"):x=q?'':'',w=a(x),r&&(d.theme?(w.css(p),w.addClass("ui-widget-content")):w.css(f)),d.theme||v.css(d.overlayCSS),v.css("position",q?"fixed":"absolute"),(k||d.forceIframe)&&u.css("opacity",0);var z=[u,v,w],A=a(q?"body":b);a.each(z,function(){this.appendTo(A)}),d.theme&&d.draggable&&a.fn.draggable&&w.draggable({handle:".ui-dialog-titlebar",cancel:"li"});var B=m&&(!a.support.boxModel||a("object,embed",q?null:b).length>0);if(l||B){if(q&&d.allowBodyStretch&&a.support.boxModel&&a("html,body").css("height","100%"),(l||!a.support.boxModel)&&!q)var C=i(b,"borderTopWidth"),D=i(b,"borderLeftWidth"),E=C?"(0 - "+C+")":0,F=D?"(0 - "+D+")":0;a.each(z,function(a,b){var c=b[0].style;if(c.position="absolute",a<2)q?c.setExpression("height","Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:"+d.quirksmodeOffsetHack+') + "px"'):c.setExpression("height",'this.parentNode.offsetHeight + "px"'),q?c.setExpression("width",'jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'):c.setExpression("width",'this.parentNode.offsetWidth + "px"'),F&&c.setExpression("left",F),E&&c.setExpression("top",E);else if(d.centerY)q&&c.setExpression("top",'(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'),c.marginTop=0;else if(!d.centerY&&q){var e=d.css&&d.css.top?parseInt(d.css.top,10):0,f="((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "+e+') + "px"';c.setExpression("top",f)}})}if(r&&(d.theme?w.find(".ui-widget-content").append(r):w.append(r),(r.jquery||r.nodeType)&&a(r).show()),(k||d.forceIframe)&&d.showOverlay&&u.show(),d.fadeIn){var G=d.onBlock?d.onBlock:j,H=d.showOverlay&&!r?G:j,I=r?G:j;d.showOverlay&&v._fadeIn(d.fadeIn,H),r&&w._fadeIn(d.fadeIn,I)}else d.showOverlay&&v.show(),r&&w.show(),d.onBlock&&d.onBlock.bind(w)();if(e(1,b,d),q?(n=w[0],o=a(d.focusableElements,n),d.focusInput&&setTimeout(g,20)):h(w[0],d.centerX,d.centerY),d.timeout){var J=setTimeout(function(){q?a.unblockUI(d):a(b).unblock(d)},d.timeout);a(b).data("blockUI.timeout",J)}}}function c(b,c){var f,g=b==window,h=a(b),i=h.data("blockUI.history"),j=h.data("blockUI.timeout");j&&(clearTimeout(j),h.removeData("blockUI.timeout")),c=a.extend({},a.blockUI.defaults,c||{}),e(0,b,c),null===c.onUnblock&&(c.onUnblock=h.data("blockUI.onUnblock"),h.removeData("blockUI.onUnblock"));var k;k=g?a(document.body).children().filter(".blockUI").add("body > .blockUI"):h.find(">.blockUI"),c.cursorReset&&(k.length>1&&(k[1].style.cursor=c.cursorReset),k.length>2&&(k[2].style.cursor=c.cursorReset)),g&&(n=o=null),c.fadeOut?(f=k.length,k.stop().fadeOut(c.fadeOut,function(){0===--f&&d(k,i,c,b)})):d(k,i,c,b)}function d(b,c,d,e){var f=a(e);if(!f.data("blockUI.isBlocked")){b.each(function(a,b){this.parentNode&&this.parentNode.removeChild(this)}),c&&c.el&&(c.el.style.display=c.display,c.el.style.position=c.position,c.el.style.cursor="default",c.parent&&c.parent.appendChild(c.el),f.removeData("blockUI.history")),f.data("blockUI.static")&&f.css("position","static"),"function"==typeof d.onUnblock&&d.onUnblock(e,d);var g=a(document.body),h=g.width(),i=g[0].style.width;g.width(h-1).width(h),g[0].style.width=i}}function e(b,c,d){var e=c==window,g=a(c);if((b||(!e||n)&&(e||g.data("blockUI.isBlocked")))&&(g.data("blockUI.isBlocked",b),e&&d.bindEvents&&(!b||d.showOverlay))){var h="mousedown mouseup keydown keypress keyup touchstart touchend touchmove";b?a(document).bind(h,d,f):a(document).unbind(h,f)}}function f(b){if("keydown"===b.type&&b.keyCode&&9==b.keyCode&&n&&b.data.constrainTabKey){var c=o,d=!b.shiftKey&&b.target===c[c.length-1],e=b.shiftKey&&b.target===c[0];if(d||e)return setTimeout(function(){g(e)},10),!1}var f=b.data,h=a(b.target);return h.hasClass("blockOverlay")&&f.onOverlayClick&&f.onOverlayClick(b),h.parents("div."+f.blockMsgClass).length>0||0===h.parents().children().filter("div.blockUI").length}function g(a){if(o){var b=o[a===!0?o.length-1:0];b&&b.focus()}}function h(a,b,c){var d=a.parentNode,e=a.style,f=(d.offsetWidth-a.offsetWidth)/2-i(d,"borderLeftWidth"),g=(d.offsetHeight-a.offsetHeight)/2-i(d,"borderTopWidth");b&&(e.left=f>0?f+"px":"0"),c&&(e.top=g>0?g+"px":"0")}function i(b,c){return parseInt(a.css(b,c),10)||0}a.fn._fadeIn=a.fn.fadeIn;var j=a.noop||function(){},k=/MSIE/.test(navigator.userAgent),l=/MSIE 6.0/.test(navigator.userAgent)&&!/MSIE 8.0/.test(navigator.userAgent),m=(document.documentMode||0,a.isFunction(document.createElement("div").style.setExpression));a.blockUI=function(a){b(window,a)},a.unblockUI=function(a){c(window,a)},a.growlUI=function(b,c,d,e){var f=a('
    ');b&&f.append("

    "+b+"

    "),c&&f.append("

    "+c+"

    "),void 0===d&&(d=3e3);var g=function(b){b=b||{},a.blockUI({message:f,fadeIn:"undefined"!=typeof b.fadeIn?b.fadeIn:700,fadeOut:"undefined"!=typeof b.fadeOut?b.fadeOut:1e3,timeout:"undefined"!=typeof b.timeout?b.timeout:d,centerY:!1,showOverlay:!1,onUnblock:e,css:a.blockUI.defaults.growlCSS})};g();f.css("opacity");f.mouseover(function(){g({fadeIn:0,timeout:3e4});var b=a(".blockMsg");b.stop(),b.fadeTo(300,1)}).mouseout(function(){a(".blockMsg").fadeOut(1e3)})},a.fn.block=function(c){if(this[0]===window)return a.blockUI(c),this;var d=a.extend({},a.blockUI.defaults,c||{});return this.each(function(){var b=a(this);d.ignoreIfBlocked&&b.data("blockUI.isBlocked")||b.unblock({fadeOut:0})}),this.each(function(){"static"==a.css(this,"position")&&(this.style.position="relative",a(this).data("blockUI.static",!0)),this.style.zoom=1,b(this,c)})},a.fn.unblock=function(b){return this[0]===window?(a.unblockUI(b),this):this.each(function(){c(this,b)})},a.blockUI.version=2.7,a.blockUI.defaults={message:"

    Please wait...

    ",title:null,draggable:!0,theme:!1,css:{padding:0,margin:0,width:"30%",top:"40%",left:"35%",textAlign:"center",color:"#000",border:"3px solid #aaa",backgroundColor:"#fff",cursor:"wait"},themedCSS:{width:"30%",top:"40%",left:"35%"},overlayCSS:{backgroundColor:"#000",opacity:.6,cursor:"wait"},cursorReset:"default",growlCSS:{width:"350px",top:"10px",left:"",right:"10px",border:"none",padding:"5px",opacity:.6,cursor:"default",color:"#fff",backgroundColor:"#000","-webkit-border-radius":"10px","-moz-border-radius":"10px","border-radius":"10px"},iframeSrc:/^https/i.test(window.location.href||"")?"javascript:false":"about:blank",forceIframe:!1,baseZ:1e3,centerX:!0,centerY:!0,allowBodyStretch:!0,bindEvents:!0,constrainTabKey:!0,fadeIn:200,fadeOut:400,timeout:0,showOverlay:!0,focusInput:!0,focusableElements:":input:enabled:visible",onBlock:null,onUnblock:null,onOverlayClick:null,quirksmodeOffsetHack:4,blockMsgClass:"blockMsg",ignoreIfBlocked:!1};var n=null,o=[]}"function"==typeof define&&define.amd&&define.amd.jQuery?define(["jquery"],a):a(jQuery)}(); \ No newline at end of file diff --git a/assets/js/jquery-cookie/jquery.cookie.min.js b/assets/js/jquery-cookie/jquery.cookie.min.js index 5be813ad400..bdf1c502623 100644 --- a/assets/js/jquery-cookie/jquery.cookie.min.js +++ b/assets/js/jquery-cookie/jquery.cookie.min.js @@ -5,4 +5,4 @@ * Copyright 2013 Klaus Hartl * Released under the MIT license */ -!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){function b(a){return h.raw?a:encodeURIComponent(a)}function c(a){return h.raw?a:decodeURIComponent(a)}function d(a){return b(h.json?JSON.stringify(a):String(a))}function e(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(g," ")),h.json?JSON.parse(a):a}catch(b){}}function f(b,c){var d=h.raw?b:e(b);return a.isFunction(c)?c(d):d}var g=/\+/g,h=a.cookie=function(e,g,i){if(void 0!==g&&!a.isFunction(g)){if(i=a.extend({},h.defaults,i),"number"==typeof i.expires){var j=i.expires,k=i.expires=new Date;k.setTime(+k+864e5*j)}return document.cookie=[b(e),"=",d(g),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}for(var l=e?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;o>n;n++){var p=m[n].split("="),q=c(p.shift()),r=p.join("=");if(e&&e===q){l=f(r,g);break}e||void 0===(r=f(r))||(l[q]=r)}return l};h.defaults={},a.removeCookie=function(b,c){return void 0===a.cookie(b)?!1:(a.cookie(b,"",a.extend({},c,{expires:-1})),!a.cookie(b))}}); \ No newline at end of file +!function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function(a){function b(a){return h.raw?a:encodeURIComponent(a)}function c(a){return h.raw?a:decodeURIComponent(a)}function d(a){return b(h.json?JSON.stringify(a):String(a))}function e(a){0===a.indexOf('"')&&(a=a.slice(1,-1).replace(/\\"/g,'"').replace(/\\\\/g,"\\"));try{return a=decodeURIComponent(a.replace(g," ")),h.json?JSON.parse(a):a}catch(b){}}function f(b,c){var d=h.raw?b:e(b);return a.isFunction(c)?c(d):d}var g=/\+/g,h=a.cookie=function(e,g,i){if(void 0!==g&&!a.isFunction(g)){if(i=a.extend({},h.defaults,i),"number"==typeof i.expires){var j=i.expires,k=i.expires=new Date;k.setTime(+k+864e5*j)}return document.cookie=[b(e),"=",d(g),i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}for(var l=e?void 0:{},m=document.cookie?document.cookie.split("; "):[],n=0,o=m.length;n=1?"rgb("+[f.r,f.g,f.b].join(",")+")":"rgba("+[f.r,f.g,f.b,f.a].join(",")+")"},f.normalize=function(){function a(a,b,c){return a>b?a:b>c?c:b}return f.r=a(0,parseInt(f.r),255),f.g=a(0,parseInt(f.g),255),f.b=a(0,parseInt(f.b),255),f.a=a(0,f.a,1),f},f.clone=function(){return a.color.make(f.r,f.b,f.g,f.a)},f.normalize()},a.color.extract=function(b,c){var d;do{if(d=b.css(c).toLowerCase(),""!=d&&"transparent"!=d)break;b=b.parent()}while(!a.nodeName(b.get(0),"body"));return"rgba(0, 0, 0, 0)"==d&&(d="transparent"),a.color.parse(d)},a.color.parse=function(c){var d,e=a.color.make;if(d=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return e(parseInt(d[1],10),parseInt(d[2],10),parseInt(d[3],10));if(d=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(c))return e(parseInt(d[1],10),parseInt(d[2],10),parseInt(d[3],10),parseFloat(d[4]));if(d=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return e(2.55*parseFloat(d[1]),2.55*parseFloat(d[2]),2.55*parseFloat(d[3]));if(d=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(c))return e(2.55*parseFloat(d[1]),2.55*parseFloat(d[2]),2.55*parseFloat(d[3]),parseFloat(d[4]));if(d=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return e(parseInt(d[1],16),parseInt(d[2],16),parseInt(d[3],16));if(d=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return e(parseInt(d[1]+d[1],16),parseInt(d[2]+d[2],16),parseInt(d[3]+d[3],16));var f=a.trim(c).toLowerCase();return"transparent"==f?e(255,255,255,0):(d=b[f]||[0,0,0],e(d[0],d[1],d[2]))};var b={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}}(jQuery),function(a){function b(b,c){var d=c.children("."+b)[0];if(null==d&&(d=document.createElement("canvas"),d.className=b,a(d).css({direction:"ltr",position:"absolute",left:0,top:0}).appendTo(c),!d.getContext)){if(!window.G_vmlCanvasManager)throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.");d=window.G_vmlCanvasManager.initElement(d)}this.element=d;var e=this.context=d.getContext("2d"),f=window.devicePixelRatio||1,g=e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1;this.pixelRatio=f/g,this.resize(c.width(),c.height()),this.textContainer=null,this.text={},this._textCache={}}function c(c,e,f,g){function h(a,b){b=[qa].concat(b);for(var c=0;cd;++d)e=ea.xaxes[d],e&&!e.tickColor&&(e.tickColor=e.color),e=a.extend(!0,{},ea.xaxis,e),ea.xaxes[d]=e,e.font&&(e.font=a.extend({},g,e.font),e.font.color||(e.font.color=e.color));for(f=ea.yaxes.length||1,d=0;f>d;++d)e=ea.yaxes[d],e&&!e.tickColor&&(e.tickColor=e.color),e=a.extend(!0,{},ea.yaxis,e),ea.yaxes[d]=e,e.font&&(e.font=a.extend({},g,e.font),e.font.color||(e.font.color=e.color));for(ea.xaxis.noTicks&&null==ea.xaxis.ticks&&(ea.xaxis.ticks=ea.xaxis.noTicks),ea.yaxis.noTicks&&null==ea.yaxis.ticks&&(ea.yaxis.ticks=ea.yaxis.noTicks),ea.x2axis&&(ea.xaxes[1]=a.extend(!0,{},ea.xaxis,ea.x2axis),ea.xaxes[1].position="top"),ea.y2axis&&(ea.yaxes[1]=a.extend(!0,{},ea.yaxis,ea.y2axis),ea.yaxes[1].position="right"),ea.grid.coloredAreas&&(ea.grid.markings=ea.grid.coloredAreas),ea.grid.coloredAreasColor&&(ea.grid.markingsColor=ea.grid.coloredAreasColor),ea.lines&&a.extend(!0,ea.series.lines,ea.lines),ea.points&&a.extend(!0,ea.series.points,ea.points),ea.bars&&a.extend(!0,ea.series.bars,ea.bars),null!=ea.shadowSize&&(ea.series.shadowSize=ea.shadowSize),null!=ea.highlightColor&&(ea.series.highlightColor=ea.highlightColor),d=0;dd&&(d=e))}d>=c&&(c=d+1);var f,g=[],h=ea.colors,i=h.length,j=0;for(b=0;c>b;b++)f=a.color.parse(h[b%i]||"#666"),b%i==0&&b&&(j=j>=0?.5>j?-j-.2:0:-j),g[b]=f.scale("rgb",1+j);var k,l=0;for(b=0;ba.datamax&&c!=s&&(a.datamax=c)}var c,d,e,f,g,i,j,k,l,m,o,p,q=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY,s=Number.MAX_VALUE;for(a.each(n(),function(a,b){b.datamin=q,b.datamax=r,b.used=!1}),c=0;cf;++f)k=m[f],l=p[f],l&&(l.number&&null!=k&&(k=+k,isNaN(k)?k=null:k==1/0?k=s:k==-(1/0)&&(k=-s)),null==k&&(l.required&&(v=!0),null!=l.defaultValue&&(k=l.defaultValue))),i[e+f]=k;if(v)for(f=0;j>f;++f)k=i[e+f],null!=k&&(l=p[f],l.autoscale&&(l.x&&b(g.xaxis,k,k),l.y&&b(g.yaxis,k,k))),i[e+f]=null;else if(u&&e>0&&null!=i[e-j]&&i[e-j]!=i[e]&&i[e-j+1]!=i[e+1]){for(f=0;j>f;++f)i[e+j+f]=i[e+f];i[e+1]=i[e-j+1],e+=j}}}}for(c=0;cf;++f)k=i[d+f],l=p[f],l&&l.autoscale!==!1&&k!=s&&k!=-s&&(l.x&&(w>k&&(w=k),k>y&&(y=k)),l.y&&(x>k&&(x=k),k>z&&(z=k)));if(g.bars.show){var A;switch(g.bars.align){case"left":A=0;break;case"right":A=-g.bars.barWidth;break;case"center":A=-g.bars.barWidth/2;break;default:throw new Error("Invalid bar alignment: "+g.bars.align)}g.bars.horizontal?(x+=A,z+=A+g.bars.barWidth):(w+=A,y+=A+g.bars.barWidth)}b(g.xaxis,w,y),b(g.yaxis,x,z)}a.each(n(),function(a,b){b.datamin==q&&(b.datamin=null),b.datamax==r&&(b.datamax=null)})}function t(){c.css("padding",0).children(":not(.flot-base,.flot-overlay)").remove(),"static"==c.css("position")&&c.css("position","relative"),fa=new b("flot-base",c),ga=new b("flot-overlay",c),ia=fa.context,ja=ga.context,ha=a(ga.element).unbind();var d=c.data("plot");d&&(d.shutdown(),ga.clear()),c.data("plot",qa)}function u(){ea.grid.hoverable&&(ha.mousemove(T),ha.bind("mouseleave",U)),ea.grid.clickable&&ha.click(V),h(pa.bindEvents,[ha])}function v(){sa&&clearTimeout(sa),ha.unbind("mousemove",T),ha.unbind("mouseleave",U),ha.unbind("click",V),h(pa.shutdown,[ha])}function w(a){function b(a){return a}var c,d,e=a.options.transform||b,f=a.options.inverseTransform;"x"==a.direction?(c=a.scale=na/Math.abs(e(a.max)-e(a.min)),d=Math.min(e(a.max),e(a.min))):(c=a.scale=oa/Math.abs(e(a.max)-e(a.min)),c=-c,d=Math.max(e(a.max),e(a.min))),e==b?a.p2c=function(a){return(a-d)*c}:a.p2c=function(a){return(e(a)-d)*c},f?a.c2p=function(a){return f(d+a/c)}:a.c2p=function(a){return d+a/c}}function x(a){var b=a.options,c=a.ticks||[],d=b.labelWidth||0,e=b.labelHeight||0,f=d||"x"==a.direction?Math.floor(fa.width/(c.length||1)):null;legacyStyles=a.direction+"Axis "+a.direction+a.n+"Axis",layer="flot-"+a.direction+"-axis flot-"+a.direction+a.n+"-axis "+legacyStyles,font=b.font||"flot-tick-label tickLabel";for(var g=0;g=0;--b)y(g[b]);A(),a.each(g,function(a,b){z(b)})}na=fa.width-ma.left-ma.right,oa=fa.height-ma.bottom-ma.top,a.each(c,function(a,b){w(b)}),d&&K(),R()}function C(a){var b=a.options,c=+(null!=b.min?b.min:a.datamin),d=+(null!=b.max?b.max:a.datamax),e=d-c;if(0==e){var f=0==d?1:.01;null==b.min&&(c-=f),null!=b.max&&null==b.min||(d+=f)}else{var g=b.autoscaleMargin;null!=g&&(null==b.min&&(c-=e*g,0>c&&null!=a.datamin&&a.datamin>=0&&(c=0)),null==b.max&&(d+=e*g,d>0&&null!=a.datamax&&a.datamax<=0&&(d=0)))}a.min=c,a.max=d}function D(b){var c,e=b.options;c="number"==typeof e.ticks&&e.ticks>0?e.ticks:.3*Math.sqrt("x"==b.direction?fa.width:fa.height);var f=(b.max-b.min)/c,g=-Math.floor(Math.log(f)/Math.LN10),h=e.tickDecimals;null!=h&&g>h&&(g=h);var i,j=Math.pow(10,-g),k=f/j;if(1.5>k?i=1:3>k?(i=2,k>2.25&&(null==h||h>=g+1)&&(i=2.5,++g)):i=7.5>k?5:10,i*=j,null!=e.minTickSize&&i0&&(null==e.min&&(b.min=Math.min(b.min,m[0])),null==e.max&&m.length>1&&(b.max=Math.max(b.max,m[m.length-1]))),b.tickGenerator=function(a){var b,c,d=[];for(c=0;c1&&/\..*0$/.test((o[1]-o[0]).toFixed(n))||(b.tickDecimals=n)}}}}function E(b){var c=b.options.ticks,d=[];null==c||"number"==typeof c&&c>0?d=b.tickGenerator(b):c&&(d=a.isFunction(c)?c(b):c);var e,f;for(b.ticks=[],e=0;e1&&(g=h[1])):f=+h,null==g&&(g=b.tickFormatter(f,b)),isNaN(f)||b.ticks.push({v:f,label:g})}}function F(a,b){a.options.autoscaleMargin&&b.length>0&&(null==a.options.min&&(a.min=Math.min(a.min,b[0].v)),null==a.options.max&&b.length>1&&(a.max=Math.max(a.max,b[b.length-1].v)))}function G(){fa.clear(),h(pa.drawBackground,[ia]);var a=ea.grid;a.show&&a.backgroundColor&&I(),a.show&&!a.aboveData&&J();for(var b=0;be){var i=d;d=e,e=i}return{from:d,to:e,axis:c}}function I(){ia.save(),ia.translate(ma.left,ma.top),ia.fillStyle=ca(ea.grid.backgroundColor,oa,0,"rgba(255, 255, 255, 0)"),ia.fillRect(0,0,na,oa),ia.restore()}function J(){var b,c,d,e;ia.save(),ia.translate(ma.left,ma.top);var f=ea.grid.markings;if(f)for(a.isFunction(f)&&(c=qa.getAxes(),c.xmin=c.xaxis.min,c.xmax=c.xaxis.max,c.ymin=c.yaxis.min,c.ymax=c.yaxis.max,f=f(c)),b=0;bh.axis.max||i.toi.axis.max||(h.from=Math.max(h.from,h.axis.min),h.to=Math.min(h.to,h.axis.max),i.from=Math.max(i.from,i.axis.min),i.to=Math.min(i.to,i.axis.max),h.from==h.to&&i.from==i.to||(h.from=h.axis.p2c(h.from),h.to=h.axis.p2c(h.to),i.from=i.axis.p2c(i.from),i.to=i.axis.p2c(i.to),h.from==h.to||i.from==i.to?(ia.beginPath(),ia.strokeStyle=g.color||ea.grid.markingsColor,ia.lineWidth=g.lineWidth||ea.grid.markingsLineWidth,ia.moveTo(h.from,i.from),ia.lineTo(h.to,i.to),ia.stroke()):(ia.fillStyle=g.color||ea.grid.markingsColor,ia.fillRect(h.from,i.to,h.to-h.from,i.from-i.to))))}c=n(),d=ea.grid.borderWidth;for(var j=0;jp.max||"full"==r&&("object"==typeof d&&d[p.position]>0||d>0)&&(s==p.min||s==p.max)||("x"==p.direction?(k=p.p2c(s),o="full"==r?-oa:r,"top"==p.position&&(o=-o)):(l=p.p2c(s),m="full"==r?-na:r,"left"==p.position&&(m=-m)),1==ia.lineWidth&&("x"==p.direction?k=Math.floor(k)+.5:l=Math.floor(l)+.5),ia.moveTo(k,l),ia.lineTo(k+m,l+o))}ia.stroke()}}d&&(e=ea.grid.borderColor,"object"==typeof d||"object"==typeof e?("object"!=typeof d&&(d={top:d,right:d,bottom:d,left:d}),"object"!=typeof e&&(e={top:e,right:e,bottom:e,left:e}),d.top>0&&(ia.strokeStyle=e.top,ia.lineWidth=d.top,ia.beginPath(),ia.moveTo(0-d.left,0-d.top/2),ia.lineTo(na,0-d.top/2),ia.stroke()),d.right>0&&(ia.strokeStyle=e.right,ia.lineWidth=d.right,ia.beginPath(),ia.moveTo(na+d.right/2,0-d.top),ia.lineTo(na+d.right/2,oa),ia.stroke()),d.bottom>0&&(ia.strokeStyle=e.bottom,ia.lineWidth=d.bottom,ia.beginPath(),ia.moveTo(na+d.right,oa+d.bottom/2),ia.lineTo(0,oa+d.bottom/2),ia.stroke()),d.left>0&&(ia.strokeStyle=e.left,ia.lineWidth=d.left,ia.beginPath(),ia.moveTo(0-d.left/2,oa+d.bottom),ia.lineTo(0-d.left/2,0),ia.stroke())):(ia.lineWidth=d,ia.strokeStyle=ea.grid.borderColor,ia.strokeRect(-d/2,-d/2,na+d,oa+d))),ia.restore()}function K(){a.each(n(),function(a,b){if(b.show&&0!=b.ticks.length){var c,d,e,f,g,h=b.box,i=b.direction+"Axis "+b.direction+b.n+"Axis",j="flot-"+b.direction+"-axis flot-"+b.direction+b.n+"-axis "+i,k=b.options.font||"flot-tick-label tickLabel";fa.removeText(j);for(var l=0;lb.max||("x"==b.direction?(f="center",d=ma.left+b.p2c(c.v),"bottom"==b.position?e=h.top+h.padding:(e=h.top+h.height-h.padding,g="bottom")):(g="middle",e=ma.top+b.p2c(c.v),"left"==b.position?(d=h.left+h.width-h.padding,f="right"):d=h.left+h.padding),fa.addText(j,d,e,c.label,k,null,null,f,g))}})}function L(a){a.lines.show&&M(a),a.bars.show&&P(a),a.points.show&&N(a)}function M(a){function b(a,b,c,d,e){var f=a.points,g=a.pointsize,h=null,i=null;ia.beginPath();for(var j=g;j=l&&l=n&&n=n&&l>e.max){if(n>e.max)continue;k=(e.max-l)/(n-l)*(m-k)+k,l=e.max}else if(n>=l&&n>e.max){if(l>e.max)continue;m=(e.max-l)/(n-l)*(m-k)+k,n=e.max}if(m>=k&&k=m&&m=m&&k>d.max){if(m>d.max)continue;l=(d.max-k)/(m-k)*(n-l)+l,k=d.max}else if(m>=k&&m>d.max){if(k>d.max)continue;n=(d.max-k)/(m-k)*(n-l)+l,m=d.max}k==h&&l==i||ia.moveTo(d.p2c(k)+b,e.p2c(l)+c),h=m,i=n,ia.lineTo(d.p2c(m)+b,e.p2c(n)+c)}}ia.stroke()}function c(a,b,c){for(var d=a.points,e=a.pointsize,f=Math.min(Math.max(0,c.min),c.max),g=0,h=!1,i=1,j=0,k=0;;){if(e>0&&g>d.length+e)break;g+=e;var l=d[g-e],m=d[g-e+i],n=d[g],o=d[g+i];if(h){if(e>0&&null!=l&&null==n){k=g,e=-e,i=2;continue}if(0>e&&g==j+e){ia.fill(),h=!1,e=-e,i=1,g=j=k+e;continue}}if(null!=l&&null!=n){if(n>=l&&l=n&&n=n&&l>b.max){if(n>b.max)continue;m=(b.max-l)/(n-l)*(o-m)+m,l=b.max}else if(n>=l&&n>b.max){if(l>b.max)continue;o=(b.max-l)/(n-l)*(o-m)+m,n=b.max}if(h||(ia.beginPath(),ia.moveTo(b.p2c(l),c.p2c(f)),h=!0),m>=c.max&&o>=c.max)ia.lineTo(b.p2c(l),c.p2c(c.max)),ia.lineTo(b.p2c(n),c.p2c(c.max));else if(m<=c.min&&o<=c.min)ia.lineTo(b.p2c(l),c.p2c(c.min)),ia.lineTo(b.p2c(n),c.p2c(c.min));else{var p=l,q=n;o>=m&&m=c.min?(l=(c.min-m)/(o-m)*(n-l)+l,m=c.min):m>=o&&o=c.min&&(n=(c.min-m)/(o-m)*(n-l)+l,o=c.min),m>=o&&m>c.max&&o<=c.max?(l=(c.max-m)/(o-m)*(n-l)+l,m=c.max):o>=m&&o>c.max&&m<=c.max&&(n=(c.max-m)/(o-m)*(n-l)+l,o=c.max),l!=p&&ia.lineTo(b.p2c(p),c.p2c(m)),ia.lineTo(b.p2c(l),c.p2c(m)),ia.lineTo(b.p2c(n),c.p2c(o)),n!=q&&(ia.lineTo(b.p2c(n),c.p2c(o)),ia.lineTo(b.p2c(q),c.p2c(o)))}}}}ia.save(),ia.translate(ma.left,ma.top),ia.lineJoin="round";var d=a.lines.lineWidth,e=a.shadowSize;if(d>0&&e>0){ia.lineWidth=e,ia.strokeStyle="rgba(0,0,0,0.1)";var f=Math.PI/18;b(a.datapoints,Math.sin(f)*(d/2+e/2),Math.cos(f)*(d/2+e/2),a.xaxis,a.yaxis),ia.lineWidth=e/2,b(a.datapoints,Math.sin(f)*(d/2+e/4),Math.cos(f)*(d/2+e/4),a.xaxis,a.yaxis)}ia.lineWidth=d,ia.strokeStyle=a.color;var g=Q(a.lines,a.color,0,oa);g&&(ia.fillStyle=g,c(a.datapoints,a.xaxis,a.yaxis)),d>0&&b(a.datapoints,0,0,a.xaxis,a.yaxis),ia.restore()}function N(a){function b(a,b,c,d,e,f,g,h){for(var i=a.points,j=a.pointsize,k=0;kf.max||mg.max||(ia.beginPath(),l=f.p2c(l),m=g.p2c(m)+d,"circle"==h?ia.arc(l,m,b,0,e?Math.PI:2*Math.PI,!1):h(ia,l,m,b,e),ia.closePath(),c&&(ia.fillStyle=c,ia.fill()),ia.stroke())}}ia.save(),ia.translate(ma.left,ma.top);var c=a.points.lineWidth,d=a.shadowSize,e=a.points.radius,f=a.points.symbol;if(0==c&&(c=1e-4),c>0&&d>0){var g=d/2;ia.lineWidth=g,ia.strokeStyle="rgba(0,0,0,0.1)",b(a.datapoints,e,null,g+g/2,!0,a.xaxis,a.yaxis,f),ia.strokeStyle="rgba(0,0,0,0.2)",b(a.datapoints,e,null,g/2,!0,a.xaxis,a.yaxis,f)}ia.lineWidth=c,ia.strokeStyle=a.color,b(a.datapoints,e,Q(a.points,a.color),0,!1,a.xaxis,a.yaxis,f),ia.restore()}function O(a,b,c,d,e,f,g,h,i,j,k,l){var m,n,o,p,q,r,s,t,u;k?(t=r=s=!0,q=!1,m=c,n=a,p=b+d,o=b+e,m>n&&(u=n,n=m,m=u,q=!0,r=!1)):(q=r=s=!0,t=!1,m=a+d,n=a+e,o=c,p=b,o>p&&(u=p,p=o,o=u,t=!0,s=!1)),nh.max||pi.max||(mh.max&&(n=h.max,r=!1),oi.max&&(p=i.max,s=!1),m=h.p2c(m),o=i.p2c(o),n=h.p2c(n),p=i.p2c(p),g&&(j.beginPath(),j.moveTo(m,o),j.lineTo(m,p),j.lineTo(n,p),j.lineTo(n,o),j.fillStyle=g(o,p),j.fill()),l>0&&(q||r||s||t)&&(j.beginPath(),j.moveTo(m,o+f),q?j.lineTo(m,p+f):j.moveTo(m,p+f),s?j.lineTo(n,p+f):j.moveTo(n,p+f),r?j.lineTo(n,o+f):j.moveTo(n,o+f),t?j.lineTo(m,o+f):j.moveTo(m,o+f),j.stroke()))}function P(a){function b(b,c,d,e,f,g,h){for(var i=b.points,j=b.pointsize,k=0;k"),e.push(""),g=!0),e.push('
    '+k.label+"")}if(g&&e.push(""),0!=e.length){var l=''+e.join("")+"
    ";if(null!=ea.legend.container)a(ea.legend.container).html(l);else{var m="",n=ea.legend.position,o=ea.legend.margin;null==o[0]&&(o=[o,o]),"n"==n.charAt(0)?m+="top:"+(o[1]+ma.top)+"px;":"s"==n.charAt(0)&&(m+="bottom:"+(o[1]+ma.bottom)+"px;"),"e"==n.charAt(1)?m+="right:"+(o[0]+ma.right)+"px;":"w"==n.charAt(1)&&(m+="left:"+(o[0]+ma.left)+"px;");var p=a('
    '+l.replace('style="','style="position:absolute;'+m+";")+"
    ").appendTo(c);if(0!=ea.legend.backgroundOpacity){var q=ea.legend.backgroundColor;null==q&&(q=ea.grid.backgroundColor,q=q&&"string"==typeof q?a.color.parse(q):a.color.extract(p,"background-color"),q.a=1,q=q.toString());var r=p.children();a('
    ').prependTo(p).css("opacity",ea.legend.backgroundOpacity)}}}}}function S(a,b,c){var d,e,f,g=ea.grid.mouseActiveRadius,h=g*g+1,i=null;for(d=da.length-1;d>=0;--d)if(c(da[d])){var j=da[d],k=j.xaxis,l=j.yaxis,m=j.datapoints.points,n=k.c2p(a),o=l.c2p(b),p=g/k.scale,q=g/l.scale;if(f=j.datapoints.pointsize,k.options.inverseTransform&&(p=Number.MAX_VALUE),l.options.inverseTransform&&(q=Number.MAX_VALUE),j.lines.show||j.points.show)for(e=0;ep||-p>r-n||s-o>q||-q>s-o)){var t=Math.abs(k.p2c(r)-a),u=Math.abs(l.p2c(s)-b),v=t*t+u*u;h>v&&(h=v,i=[d,e/f])}}if(j.bars.show&&!i){var w="left"==j.bars.align?0:-j.bars.barWidth/2,x=w+j.bars.barWidth;for(e=0;e=Math.min(y,r)&&o>=s+w&&s+x>=o:n>=r+w&&r+x>=n&&o>=Math.min(y,s)&&o<=Math.max(y,s))&&(i=[d,e/f])}}}return i?(d=i[0],e=i[1],f=da[d].datapoints.pointsize,{datapoint:da[d].datapoints.points.slice(e*f,(e+1)*f),dataIndex:e,series:da[d],seriesIndex:d}):null}function T(a){ea.grid.hoverable&&W("plothover",a,function(a){return 0!=a.hoverable})}function U(a){ea.grid.hoverable&&W("plothover",a,function(a){return!1})}function V(a){W("plotclick",a,function(a){return 0!=a.clickable})}function W(a,b,d){var e=ha.offset(),f=b.pageX-e.left-ma.left,g=b.pageY-e.top-ma.top,h=o({left:f,top:g});h.pageX=b.pageX,h.pageY=b.pageY;var i=S(f,g,d);if(i&&(i.pageX=parseInt(i.series.xaxis.p2c(i.datapoint[0])+e.left+ma.left,10),i.pageY=parseInt(i.series.yaxis.p2c(i.datapoint[1])+e.top+ma.top,10)),ea.grid.autoHighlight){for(var j=0;jf.max||eg.max)){var i=b.points.radius+b.points.lineWidth/2;ja.lineWidth=i,ja.strokeStyle=h;var j=1.5*i;d=f.p2c(d),e=g.p2c(e),ja.beginPath(),"circle"==b.points.symbol?ja.arc(d,e,j,0,2*Math.PI,!1):b.points.symbol(ja,d,e,j,!1),ja.closePath(),ja.stroke()}}function ba(b,c){var d="string"==typeof b.highlightColor?b.highlightColor:a.color.parse(b.color).scale("a",.5).toString(),e=d,f="left"==b.bars.align?0:-b.bars.barWidth/2;ja.lineWidth=b.bars.lineWidth,ja.strokeStyle=d,O(c[0],c[1],c[2]||0,f,f+b.bars.barWidth,0,function(){return e},b.xaxis,b.yaxis,ja,b.bars.horizontal,b.bars.lineWidth)}function ca(b,c,d,e){if("string"==typeof b)return b;for(var f=ia.createLinearGradient(0,d,0,c),g=0,h=b.colors.length;h>g;++g){var i=b.colors[g];if("string"!=typeof i){var j=a.color.parse(e);null!=i.brightness&&(j=j.scale("rgb",i.brightness)),null!=i.opacity&&(j.a*=i.opacity),i=j.toString()}f.addColorStop(g/(h-1),i)}return f}var da=[],ea={colors:["#edc240","#afd8f8","#cb4b4b","#4da74d","#9440ed"],legend:{show:!0,noColumns:1,labelFormatter:null,labelBoxBorderColor:"#ccc",container:null,position:"ne",margin:5,backgroundColor:null,backgroundOpacity:.85,sorted:null},xaxis:{show:null,position:"bottom",mode:null,font:null,color:null,tickColor:null,transform:null,inverseTransform:null,min:null,max:null,autoscaleMargin:null,ticks:null,tickFormatter:null,labelWidth:null,labelHeight:null,reserveSpace:null,tickLength:null,alignTicksWithAxis:null,tickDecimals:null,tickSize:null,minTickSize:null},yaxis:{autoscaleMargin:.02,position:"left"},xaxes:[],yaxes:[],series:{points:{show:!1,radius:3,lineWidth:2,fill:!0,fillColor:"#ffffff",symbol:"circle"},lines:{lineWidth:2,fill:!1,fillColor:null,steps:!1},bars:{show:!1,lineWidth:2,barWidth:1,fill:!0,fillColor:null,align:"left",horizontal:!1,zero:!0},shadowSize:3,highlightColor:null},grid:{show:!0,aboveData:!1,color:"#545454",backgroundColor:null,borderColor:null,tickColor:null,margin:0,labelMargin:5,axisMargin:8,borderWidth:2,minBorderMargin:null,markings:null,markingsColor:"#f4f4f4",markingsLineWidth:2,clickable:!1,hoverable:!1,autoHighlight:!0,mouseActiveRadius:10},interaction:{redrawOverlayInterval:1e3/60},hooks:{}},fa=null,ga=null,ha=null,ia=null,ja=null,ka=[],la=[],ma={left:0,right:0,top:0,bottom:0},na=0,oa=0,pa={processOptions:[],processRawData:[], -processDatapoints:[],processOffset:[],drawBackground:[],drawSeries:[],draw:[],bindEvents:[],drawOverlay:[],shutdown:[]},qa=this;qa.setData=k,qa.setupGrid=B,qa.draw=G,qa.getPlaceholder=function(){return c},qa.getCanvas=function(){return fa.element},qa.getPlotOffset=function(){return ma},qa.width=function(){return na},qa.height=function(){return oa},qa.offset=function(){var a=ha.offset();return a.left+=ma.left,a.top+=ma.top,a},qa.getData=function(){return da},qa.getAxes=function(){var b={};return a.each(ka.concat(la),function(a,c){c&&(b[c.direction+(1!=c.n?c.n:"")+"axis"]=c)}),b},qa.getXAxes=function(){return ka},qa.getYAxes=function(){return la},qa.c2p=o,qa.p2c=p,qa.getOptions=function(){return ea},qa.highlight=Z,qa.unhighlight=$,qa.triggerRedrawOverlay=X,qa.pointOffset=function(a){return{left:parseInt(ka[m(a,"x")-1].p2c(+a.x)+ma.left,10),top:parseInt(la[m(a,"y")-1].p2c(+a.y)+ma.top,10)}},qa.shutdown=v,qa.resize=function(){var a=c.width(),b=c.height();fa.resize(a,b),ga.resize(a,b)},qa.hooks=pa,i(qa),j(f),t(),k(e),B(),G(),u();var ra=[],sa=null}function d(a,b){return b*Math.floor(a/b)}var e=Object.prototype.hasOwnProperty;b.prototype.resize=function(a,b){if(0>=a||0>=b)throw new Error("Invalid dimensions for plot, width = "+a+", height = "+b);var c=this.element,d=this.context,e=this.pixelRatio;this.width!=a&&(c.width=a*e,c.style.width=a+"px",this.width=a),this.height!=b&&(c.height=b*e,c.style.height=b+"px",this.height=b),d.restore(),d.save(),d.scale(e,e)},b.prototype.clear=function(){this.context.clearRect(0,0,this.width,this.height)},b.prototype.render=function(){var a=this._textCache;for(var b in a)if(e.call(a,b)){var c=this.getTextLayer(b),d=a[b];c.hide();for(var f in d)if(e.call(d,f)){var g=d[f];for(var h in g)if(e.call(g,h)){for(var i,j=g[h].positions,k=0;i=j[k];k++)i.active?i.rendered||(c.append(i.element),i.rendered=!0):(j.splice(k--,1),i.rendered&&i.element.detach());0==j.length&&delete g[h]}}c.show()}},b.prototype.getTextLayer=function(b){var c=this.text[b];return null==c&&(null==this.textContainer&&(this.textContainer=a("
    ").css({position:"absolute",top:0,left:0,bottom:0,right:0,"font-size":"smaller",color:"#545454"}).insertAfter(this.element)),c=this.text[b]=a("
    ").addClass(b).css({position:"absolute",top:0,left:0,bottom:0,right:0}).appendTo(this.textContainer)),c},b.prototype.getTextInfo=function(b,c,d,e,f){var g,h,i,j;if(c=""+c,g="object"==typeof d?d.style+" "+d.variant+" "+d.weight+" "+d.size+"px/"+d.lineHeight+"px "+d.family:d,h=this._textCache[b],null==h&&(h=this._textCache[b]={}),i=h[g],null==i&&(i=h[g]={}),j=i[c],null==j){var k=a("
    ").html(c).css({position:"absolute","max-width":f,top:-9999}).appendTo(this.getTextLayer(b));"object"==typeof d?k.css({font:g,color:d.color}):"string"==typeof d&&k.addClass(d),j=i[c]={width:k.outerWidth(!0),height:k.outerHeight(!0),element:k,positions:[]},k.detach()}return j},b.prototype.addText=function(a,b,c,d,e,f,g,h,i){var j=this.getTextInfo(a,d,e,f,g),k=j.positions;"center"==h?b-=j.width/2:"right"==h&&(b-=j.width),"middle"==i?c-=j.height/2:"bottom"==i&&(c-=j.height);for(var l,m=0;l=k[m];m++)if(l.x==b&&l.y==c)return void(l.active=!0);l={active:!0,rendered:!1,element:k.length?j.element.clone():j.element,x:b,y:c},k.push(l),l.element.css({top:Math.round(c),left:Math.round(b),"text-align":h})},b.prototype.removeText=function(a,b,c,d,f,g){if(null==d){var h=this._textCache[a];if(null!=h)for(var i in h)if(e.call(h,i)){var j=h[i];for(var k in j)if(e.call(j,k))for(var l,m=j[k].positions,n=0;l=m[n];n++)l.active=!1}}else for(var l,m=this.getTextInfo(a,d,f,g).positions,n=0;l=m[n];n++)l.x==b&&l.y==c&&(l.active=!1)},a.plot=function(b,d,e){var f=new c(a(b),d,e,a.plot.plugins);return f},a.plot.version="0.8.1",a.plot.plugins=[],a.fn.plot=function(b,c){return this.each(function(){a.plot(this,b,c)})}}(jQuery); \ No newline at end of file +!function(a){a.color={},a.color.make=function(b,c,d,e){var f={};return f.r=b||0,f.g=c||0,f.b=d||0,f.a=null!=e?e:1,f.add=function(a,b){for(var c=0;c=1?"rgb("+[f.r,f.g,f.b].join(",")+")":"rgba("+[f.r,f.g,f.b,f.a].join(",")+")"},f.normalize=function(){function a(a,b,c){return bc?c:b}return f.r=a(0,parseInt(f.r),255),f.g=a(0,parseInt(f.g),255),f.b=a(0,parseInt(f.b),255),f.a=a(0,f.a,1),f},f.clone=function(){return a.color.make(f.r,f.b,f.g,f.a)},f.normalize()},a.color.extract=function(b,c){var d;do{if(d=b.css(c).toLowerCase(),""!=d&&"transparent"!=d)break;b=b.parent()}while(!a.nodeName(b.get(0),"body"));return"rgba(0, 0, 0, 0)"==d&&(d="transparent"),a.color.parse(d)},a.color.parse=function(c){var d,e=a.color.make;if(d=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(c))return e(parseInt(d[1],10),parseInt(d[2],10),parseInt(d[3],10));if(d=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(c))return e(parseInt(d[1],10),parseInt(d[2],10),parseInt(d[3],10),parseFloat(d[4]));if(d=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(c))return e(2.55*parseFloat(d[1]),2.55*parseFloat(d[2]),2.55*parseFloat(d[3]));if(d=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(c))return e(2.55*parseFloat(d[1]),2.55*parseFloat(d[2]),2.55*parseFloat(d[3]),parseFloat(d[4]));if(d=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(c))return e(parseInt(d[1],16),parseInt(d[2],16),parseInt(d[3],16));if(d=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(c))return e(parseInt(d[1]+d[1],16),parseInt(d[2]+d[2],16),parseInt(d[3]+d[3],16));var f=a.trim(c).toLowerCase();return"transparent"==f?e(255,255,255,0):(d=b[f]||[0,0,0],e(d[0],d[1],d[2]))};var b={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}}(jQuery),function(a){function b(b,c){var d=c.children("."+b)[0];if(null==d&&(d=document.createElement("canvas"),d.className=b,a(d).css({direction:"ltr",position:"absolute",left:0,top:0}).appendTo(c),!d.getContext)){if(!window.G_vmlCanvasManager)throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.");d=window.G_vmlCanvasManager.initElement(d)}this.element=d;var e=this.context=d.getContext("2d"),f=window.devicePixelRatio||1,g=e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||e.backingStorePixelRatio||1;this.pixelRatio=f/g,this.resize(c.width(),c.height()),this.textContainer=null,this.text={},this._textCache={}}function c(c,e,f,g){function h(a,b){b=[qa].concat(b);for(var c=0;cd&&(d=e))}c<=d&&(c=d+1);var f,g=[],h=ea.colors,i=h.length,j=0;for(b=0;b=0?j<.5?-j-.2:0:-j),g[b]=f.scale("rgb",1+j);var k,l=0;for(b=0;ba.datamax&&c!=s&&(a.datamax=c)}var c,d,e,f,g,i,j,k,l,m,o,p,q=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY,s=Number.MAX_VALUE;for(a.each(n(),function(a,b){b.datamin=q,b.datamax=r,b.used=!1}),c=0;c0&&null!=i[e-j]&&i[e-j]!=i[e]&&i[e-j+1]!=i[e+1]){for(f=0;fy&&(y=k)),l.y&&(kz&&(z=k)));if(g.bars.show){var A;switch(g.bars.align){case"left":A=0;break;case"right":A=-g.bars.barWidth;break;case"center":A=-g.bars.barWidth/2;break;default:throw new Error("Invalid bar alignment: "+g.bars.align)}g.bars.horizontal?(x+=A,z+=A+g.bars.barWidth):(w+=A,y+=A+g.bars.barWidth)}b(g.xaxis,w,y),b(g.yaxis,x,z)}a.each(n(),function(a,b){b.datamin==q&&(b.datamin=null),b.datamax==r&&(b.datamax=null)})}function t(){c.css("padding",0).children(":not(.flot-base,.flot-overlay)").remove(),"static"==c.css("position")&&c.css("position","relative"),fa=new b("flot-base",c),ga=new b("flot-overlay",c),ia=fa.context,ja=ga.context,ha=a(ga.element).unbind();var d=c.data("plot");d&&(d.shutdown(),ga.clear()),c.data("plot",qa)}function u(){ea.grid.hoverable&&(ha.mousemove(T),ha.bind("mouseleave",U)),ea.grid.clickable&&ha.click(V),h(pa.bindEvents,[ha])}function v(){sa&&clearTimeout(sa),ha.unbind("mousemove",T),ha.unbind("mouseleave",U),ha.unbind("click",V),h(pa.shutdown,[ha])}function w(a){function b(a){return a}var c,d,e=a.options.transform||b,f=a.options.inverseTransform;"x"==a.direction?(c=a.scale=na/Math.abs(e(a.max)-e(a.min)),d=Math.min(e(a.max),e(a.min))):(c=a.scale=oa/Math.abs(e(a.max)-e(a.min)),c=-c,d=Math.max(e(a.max),e(a.min))),e==b?a.p2c=function(a){return(a-d)*c}:a.p2c=function(a){return(e(a)-d)*c},f?a.c2p=function(a){return f(d+a/c)}:a.c2p=function(a){return d+a/c}}function x(a){var b=a.options,c=a.ticks||[],d=b.labelWidth||0,e=b.labelHeight||0,f=d||"x"==a.direction?Math.floor(fa.width/(c.length||1)):null;legacyStyles=a.direction+"Axis "+a.direction+a.n+"Axis",layer="flot-"+a.direction+"-axis flot-"+a.direction+a.n+"-axis "+legacyStyles,font=b.font||"flot-tick-label tickLabel";for(var g=0;g=0;--b)y(g[b]);A(),a.each(g,function(a,b){z(b)})}na=fa.width-ma.left-ma.right,oa=fa.height-ma.bottom-ma.top,a.each(c,function(a,b){w(b)}),d&&K(),R()}function C(a){var b=a.options,c=+(null!=b.min?b.min:a.datamin),d=+(null!=b.max?b.max:a.datamax),e=d-c;if(0==e){var f=0==d?1:.01;null==b.min&&(c-=f),null!=b.max&&null==b.min||(d+=f)}else{var g=b.autoscaleMargin;null!=g&&(null==b.min&&(c-=e*g,c<0&&null!=a.datamin&&a.datamin>=0&&(c=0)),null==b.max&&(d+=e*g,d>0&&null!=a.datamax&&a.datamax<=0&&(d=0)))}a.min=c,a.max=d}function D(b){var c,e=b.options;c="number"==typeof e.ticks&&e.ticks>0?e.ticks:.3*Math.sqrt("x"==b.direction?fa.width:fa.height);var f=(b.max-b.min)/c,g=-Math.floor(Math.log(f)/Math.LN10),h=e.tickDecimals;null!=h&&g>h&&(g=h);var i,j=Math.pow(10,-g),k=f/j;if(k<1.5?i=1:k<3?(i=2,k>2.25&&(null==h||g+1<=h)&&(i=2.5,++g)):i=k<7.5?5:10,i*=j,null!=e.minTickSize&&i0&&(null==e.min&&(b.min=Math.min(b.min,m[0])),null==e.max&&m.length>1&&(b.max=Math.max(b.max,m[m.length-1]))),b.tickGenerator=function(a){var b,c,d=[];for(c=0;c1&&/\..*0$/.test((o[1]-o[0]).toFixed(n))||(b.tickDecimals=n)}}}}function E(b){var c=b.options.ticks,d=[];null==c||"number"==typeof c&&c>0?d=b.tickGenerator(b):c&&(d=a.isFunction(c)?c(b):c);var e,f;for(b.ticks=[],e=0;e1&&(g=h[1])):f=+h,null==g&&(g=b.tickFormatter(f,b)),isNaN(f)||b.ticks.push({v:f,label:g})}}function F(a,b){a.options.autoscaleMargin&&b.length>0&&(null==a.options.min&&(a.min=Math.min(a.min,b[0].v)),null==a.options.max&&b.length>1&&(a.max=Math.max(a.max,b[b.length-1].v)))}function G(){fa.clear(),h(pa.drawBackground,[ia]);var a=ea.grid;a.show&&a.backgroundColor&&I(),a.show&&!a.aboveData&&J();for(var b=0;be){var i=d;d=e,e=i}return{from:d,to:e,axis:c}}function I(){ia.save(),ia.translate(ma.left,ma.top),ia.fillStyle=ca(ea.grid.backgroundColor,oa,0,"rgba(255, 255, 255, 0)"),ia.fillRect(0,0,na,oa),ia.restore()}function J(){var b,c,d,e;ia.save(),ia.translate(ma.left,ma.top);var f=ea.grid.markings;if(f)for(a.isFunction(f)&&(c=qa.getAxes(),c.xmin=c.xaxis.min,c.xmax=c.xaxis.max,c.ymin=c.yaxis.min,c.ymax=c.yaxis.max,f=f(c)),b=0;bh.axis.max||i.toi.axis.max||(h.from=Math.max(h.from,h.axis.min),h.to=Math.min(h.to,h.axis.max),i.from=Math.max(i.from,i.axis.min),i.to=Math.min(i.to,i.axis.max),h.from==h.to&&i.from==i.to||(h.from=h.axis.p2c(h.from),h.to=h.axis.p2c(h.to),i.from=i.axis.p2c(i.from),i.to=i.axis.p2c(i.to),h.from==h.to||i.from==i.to?(ia.beginPath(),ia.strokeStyle=g.color||ea.grid.markingsColor,ia.lineWidth=g.lineWidth||ea.grid.markingsLineWidth,ia.moveTo(h.from,i.from),ia.lineTo(h.to,i.to),ia.stroke()):(ia.fillStyle=g.color||ea.grid.markingsColor,ia.fillRect(h.from,i.to,h.to-h.from,i.from-i.to))))}c=n(),d=ea.grid.borderWidth;for(var j=0;jp.max||"full"==r&&("object"==typeof d&&d[p.position]>0||d>0)&&(s==p.min||s==p.max)||("x"==p.direction?(k=p.p2c(s),o="full"==r?-oa:r,"top"==p.position&&(o=-o)):(l=p.p2c(s),m="full"==r?-na:r,"left"==p.position&&(m=-m)),1==ia.lineWidth&&("x"==p.direction?k=Math.floor(k)+.5:l=Math.floor(l)+.5),ia.moveTo(k,l),ia.lineTo(k+m,l+o))}ia.stroke()}}d&&(e=ea.grid.borderColor,"object"==typeof d||"object"==typeof e?("object"!=typeof d&&(d={top:d,right:d,bottom:d,left:d}),"object"!=typeof e&&(e={top:e,right:e,bottom:e,left:e}),d.top>0&&(ia.strokeStyle=e.top,ia.lineWidth=d.top,ia.beginPath(),ia.moveTo(0-d.left,0-d.top/2),ia.lineTo(na,0-d.top/2),ia.stroke()),d.right>0&&(ia.strokeStyle=e.right,ia.lineWidth=d.right,ia.beginPath(),ia.moveTo(na+d.right/2,0-d.top),ia.lineTo(na+d.right/2,oa),ia.stroke()),d.bottom>0&&(ia.strokeStyle=e.bottom,ia.lineWidth=d.bottom,ia.beginPath(),ia.moveTo(na+d.right,oa+d.bottom/2),ia.lineTo(0,oa+d.bottom/2),ia.stroke()),d.left>0&&(ia.strokeStyle=e.left,ia.lineWidth=d.left,ia.beginPath(),ia.moveTo(0-d.left/2,oa+d.bottom),ia.lineTo(0-d.left/2,0),ia.stroke())):(ia.lineWidth=d,ia.strokeStyle=ea.grid.borderColor,ia.strokeRect(-d/2,-d/2,na+d,oa+d))),ia.restore()}function K(){a.each(n(),function(a,b){if(b.show&&0!=b.ticks.length){var c,d,e,f,g,h=b.box,i=b.direction+"Axis "+b.direction+b.n+"Axis",j="flot-"+b.direction+"-axis flot-"+b.direction+b.n+"-axis "+i,k=b.options.font||"flot-tick-label tickLabel";fa.removeText(j);for(var l=0;lb.max||("x"==b.direction?(f="center",d=ma.left+b.p2c(c.v),"bottom"==b.position?e=h.top+h.padding:(e=h.top+h.height-h.padding,g="bottom")):(g="middle",e=ma.top+b.p2c(c.v),"left"==b.position?(d=h.left+h.width-h.padding,f="right"):d=h.left+h.padding),fa.addText(j,d,e,c.label,k,null,null,f,g))}})}function L(a){a.lines.show&&M(a),a.bars.show&&P(a),a.points.show&&N(a)}function M(a){function b(a,b,c,d,e){var f=a.points,g=a.pointsize,h=null,i=null;ia.beginPath();for(var j=g;j=n&&l>e.max){if(n>e.max)continue;k=(e.max-l)/(n-l)*(m-k)+k,l=e.max}else if(n>=l&&n>e.max){if(l>e.max)continue;m=(e.max-l)/(n-l)*(m-k)+k,n=e.max}if(k<=m&&k=m&&k>d.max){if(m>d.max)continue;l=(d.max-k)/(m-k)*(n-l)+l,k=d.max}else if(m>=k&&m>d.max){if(k>d.max)continue;n=(d.max-k)/(m-k)*(n-l)+l,m=d.max}k==h&&l==i||ia.moveTo(d.p2c(k)+b,e.p2c(l)+c),h=m,i=n,ia.lineTo(d.p2c(m)+b,e.p2c(n)+c)}}ia.stroke()}function c(a,b,c){for(var d=a.points,e=a.pointsize,f=Math.min(Math.max(0,c.min),c.max),g=0,h=!1,i=1,j=0,k=0;;){if(e>0&&g>d.length+e)break;g+=e;var l=d[g-e],m=d[g-e+i],n=d[g],o=d[g+i];if(h){if(e>0&&null!=l&&null==n){k=g,e=-e,i=2;continue}if(e<0&&g==j+e){ia.fill(),h=!1,e=-e,i=1,g=j=k+e;continue}}if(null!=l&&null!=n){if(l<=n&&l=n&&l>b.max){if(n>b.max)continue;m=(b.max-l)/(n-l)*(o-m)+m,l=b.max}else if(n>=l&&n>b.max){if(l>b.max)continue;o=(b.max-l)/(n-l)*(o-m)+m,n=b.max}if(h||(ia.beginPath(),ia.moveTo(b.p2c(l),c.p2c(f)),h=!0),m>=c.max&&o>=c.max)ia.lineTo(b.p2c(l),c.p2c(c.max)),ia.lineTo(b.p2c(n),c.p2c(c.max));else if(m<=c.min&&o<=c.min)ia.lineTo(b.p2c(l),c.p2c(c.min)),ia.lineTo(b.p2c(n),c.p2c(c.min));else{var p=l,q=n;m<=o&&m=c.min?(l=(c.min-m)/(o-m)*(n-l)+l,m=c.min):o<=m&&o=c.min&&(n=(c.min-m)/(o-m)*(n-l)+l,o=c.min),m>=o&&m>c.max&&o<=c.max?(l=(c.max-m)/(o-m)*(n-l)+l,m=c.max):o>=m&&o>c.max&&m<=c.max&&(n=(c.max-m)/(o-m)*(n-l)+l,o=c.max),l!=p&&ia.lineTo(b.p2c(p),c.p2c(m)),ia.lineTo(b.p2c(l),c.p2c(m)),ia.lineTo(b.p2c(n),c.p2c(o)),n!=q&&(ia.lineTo(b.p2c(n),c.p2c(o)),ia.lineTo(b.p2c(q),c.p2c(o)))}}}}ia.save(),ia.translate(ma.left,ma.top),ia.lineJoin="round";var d=a.lines.lineWidth,e=a.shadowSize;if(d>0&&e>0){ia.lineWidth=e,ia.strokeStyle="rgba(0,0,0,0.1)";var f=Math.PI/18;b(a.datapoints,Math.sin(f)*(d/2+e/2),Math.cos(f)*(d/2+e/2),a.xaxis,a.yaxis),ia.lineWidth=e/2,b(a.datapoints,Math.sin(f)*(d/2+e/4),Math.cos(f)*(d/2+e/4),a.xaxis,a.yaxis)}ia.lineWidth=d,ia.strokeStyle=a.color;var g=Q(a.lines,a.color,0,oa);g&&(ia.fillStyle=g,c(a.datapoints,a.xaxis,a.yaxis)),d>0&&b(a.datapoints,0,0,a.xaxis,a.yaxis),ia.restore()}function N(a){function b(a,b,c,d,e,f,g,h){for(var i=a.points,j=a.pointsize,k=0;kf.max||mg.max||(ia.beginPath(),l=f.p2c(l),m=g.p2c(m)+d,"circle"==h?ia.arc(l,m,b,0,e?Math.PI:2*Math.PI,!1):h(ia,l,m,b,e),ia.closePath(),c&&(ia.fillStyle=c,ia.fill()),ia.stroke())}}ia.save(),ia.translate(ma.left,ma.top);var c=a.points.lineWidth,d=a.shadowSize,e=a.points.radius,f=a.points.symbol;if(0==c&&(c=1e-4),c>0&&d>0){var g=d/2;ia.lineWidth=g,ia.strokeStyle="rgba(0,0,0,0.1)",b(a.datapoints,e,null,g+g/2,!0,a.xaxis,a.yaxis,f),ia.strokeStyle="rgba(0,0,0,0.2)",b(a.datapoints,e,null,g/2,!0,a.xaxis,a.yaxis,f)}ia.lineWidth=c,ia.strokeStyle=a.color,b(a.datapoints,e,Q(a.points,a.color),0,!1,a.xaxis,a.yaxis,f),ia.restore()}function O(a,b,c,d,e,f,g,h,i,j,k,l){var m,n,o,p,q,r,s,t,u;k?(t=r=s=!0,q=!1,m=c,n=a,p=b+d,o=b+e,nh.max||pi.max||(mh.max&&(n=h.max,r=!1),oi.max&&(p=i.max,s=!1),m=h.p2c(m),o=i.p2c(o),n=h.p2c(n),p=i.p2c(p),g&&(j.beginPath(),j.moveTo(m,o),j.lineTo(m,p),j.lineTo(n,p),j.lineTo(n,o),j.fillStyle=g(o,p),j.fill()),l>0&&(q||r||s||t)&&(j.beginPath(),j.moveTo(m,o+f),q?j.lineTo(m,p+f):j.moveTo(m,p+f),s?j.lineTo(n,p+f):j.moveTo(n,p+f),r?j.lineTo(n,o+f):j.moveTo(n,o+f),t?j.lineTo(m,o+f):j.moveTo(m,o+f),j.stroke()))}function P(a){function b(b,c,d,e,f,g,h){for(var i=b.points,j=b.pointsize,k=0;k"),e.push(""),g=!0),e.push('
    '+k.label+"")}if(g&&e.push(""),0!=e.length){var l=''+e.join("")+"
    ";if(null!=ea.legend.container)a(ea.legend.container).html(l);else{var m="",n=ea.legend.position,o=ea.legend.margin;null==o[0]&&(o=[o,o]),"n"==n.charAt(0)?m+="top:"+(o[1]+ma.top)+"px;":"s"==n.charAt(0)&&(m+="bottom:"+(o[1]+ma.bottom)+"px;"),"e"==n.charAt(1)?m+="right:"+(o[0]+ma.right)+"px;":"w"==n.charAt(1)&&(m+="left:"+(o[0]+ma.left)+"px;");var p=a('
    '+l.replace('style="','style="position:absolute;'+m+";")+"
    ").appendTo(c);if(0!=ea.legend.backgroundOpacity){var q=ea.legend.backgroundColor;null==q&&(q=ea.grid.backgroundColor,q=q&&"string"==typeof q?a.color.parse(q):a.color.extract(p,"background-color"),q.a=1,q=q.toString());var r=p.children();a('
    ').prependTo(p).css("opacity",ea.legend.backgroundOpacity)}}}}}function S(a,b,c){var d,e,f,g=ea.grid.mouseActiveRadius,h=g*g+1,i=null;for(d=da.length-1;d>=0;--d)if(c(da[d])){var j=da[d],k=j.xaxis,l=j.yaxis,m=j.datapoints.points,n=k.c2p(a),o=l.c2p(b),p=g/k.scale,q=g/l.scale;if(f=j.datapoints.pointsize,k.options.inverseTransform&&(p=Number.MAX_VALUE),l.options.inverseTransform&&(q=Number.MAX_VALUE),j.lines.show||j.points.show)for(e=0;ep||r-n<-p||s-o>q||s-o<-q)){var t=Math.abs(k.p2c(r)-a),u=Math.abs(l.p2c(s)-b),v=t*t+u*u;v=Math.min(y,r)&&o>=s+w&&o<=s+x:n>=r+w&&n<=r+x&&o>=Math.min(y,s)&&o<=Math.max(y,s))&&(i=[d,e/f])}}}return i?(d=i[0],e=i[1],f=da[d].datapoints.pointsize,{datapoint:da[d].datapoints.points.slice(e*f,(e+1)*f),dataIndex:e,series:da[d],seriesIndex:d}):null}function T(a){ea.grid.hoverable&&W("plothover",a,function(a){return 0!=a.hoverable})}function U(a){ea.grid.hoverable&&W("plothover",a,function(a){return!1})}function V(a){W("plotclick",a,function(a){return 0!=a.clickable})}function W(a,b,d){var e=ha.offset(),f=b.pageX-e.left-ma.left,g=b.pageY-e.top-ma.top,h=o({left:f,top:g});h.pageX=b.pageX,h.pageY=b.pageY;var i=S(f,g,d);if(i&&(i.pageX=parseInt(i.series.xaxis.p2c(i.datapoint[0])+e.left+ma.left,10),i.pageY=parseInt(i.series.yaxis.p2c(i.datapoint[1])+e.top+ma.top,10)),ea.grid.autoHighlight){for(var j=0;jf.max||eg.max)){var i=b.points.radius+b.points.lineWidth/2;ja.lineWidth=i,ja.strokeStyle=h;var j=1.5*i;d=f.p2c(d),e=g.p2c(e),ja.beginPath(),"circle"==b.points.symbol?ja.arc(d,e,j,0,2*Math.PI,!1):b.points.symbol(ja,d,e,j,!1),ja.closePath(),ja.stroke()}}function ba(b,c){var d="string"==typeof b.highlightColor?b.highlightColor:a.color.parse(b.color).scale("a",.5).toString(),e=d,f="left"==b.bars.align?0:-b.bars.barWidth/2;ja.lineWidth=b.bars.lineWidth,ja.strokeStyle=d,O(c[0],c[1],c[2]||0,f,f+b.bars.barWidth,0,function(){return e},b.xaxis,b.yaxis,ja,b.bars.horizontal,b.bars.lineWidth)}function ca(b,c,d,e){if("string"==typeof b)return b;for(var f=ia.createLinearGradient(0,d,0,c),g=0,h=b.colors.length;g").css({position:"absolute",top:0,left:0,bottom:0,right:0,"font-size":"smaller",color:"#545454"}).insertAfter(this.element)),c=this.text[b]=a("
    ").addClass(b).css({position:"absolute",top:0,left:0,bottom:0,right:0}).appendTo(this.textContainer)),c},b.prototype.getTextInfo=function(b,c,d,e,f){var g,h,i,j;if(c=""+c,g="object"==typeof d?d.style+" "+d.variant+" "+d.weight+" "+d.size+"px/"+d.lineHeight+"px "+d.family:d,h=this._textCache[b],null==h&&(h=this._textCache[b]={}),i=h[g],null==i&&(i=h[g]={}),j=i[c],null==j){var k=a("
    ").html(c).css({position:"absolute","max-width":f,top:-9999}).appendTo(this.getTextLayer(b));"object"==typeof d?k.css({font:g,color:d.color}):"string"==typeof d&&k.addClass(d),j=i[c]={width:k.outerWidth(!0),height:k.outerHeight(!0),element:k,positions:[]},k.detach()}return j},b.prototype.addText=function(a,b,c,d,e,f,g,h,i){var j=this.getTextInfo(a,d,e,f,g),k=j.positions;"center"==h?b-=j.width/2:"right"==h&&(b-=j.width),"middle"==i?c-=j.height/2:"bottom"==i&&(c-=j.height);for(var l,m=0;l=k[m];m++)if(l.x==b&&l.y==c)return void(l.active=!0);l={active:!0,rendered:!1,element:k.length?j.element.clone():j.element,x:b,y:c},k.push(l),l.element.css({top:Math.round(c),left:Math.round(b),"text-align":h})},b.prototype.removeText=function(a,b,c,d,f,g){if(null==d){var h=this._textCache[a];if(null!=h)for(var i in h)if(e.call(h,i)){var j=h[i];for(var k in j)if(e.call(j,k))for(var l,m=j[k].positions,n=0;l=m[n];n++)l.active=!1}}else for(var l,m=this.getTextInfo(a,d,f,g).positions,n=0;l=m[n];n++)l.x==b&&l.y==c&&(l.active=!1)},a.plot=function(b,d,e){var f=new c(a(b),d,e,a.plot.plugins);return f},a.plot.version="0.8.1",a.plot.plugins=[],a.fn.plot=function(b,c){return this.each(function(){a.plot(this,b,c)})}}(jQuery); \ No newline at end of file diff --git a/assets/js/jquery-flot/jquery.flot.pie.min.js b/assets/js/jquery-flot/jquery.flot.pie.min.js index 2bacbcf63b8..0f661ee9d6d 100644 --- a/assets/js/jquery-flot/jquery.flot.pie.min.js +++ b/assets/js/jquery-flot/jquery.flot.pie.min.js @@ -1 +1 @@ -!function(a){function b(b){function f(b,c,d){x||(x=!0,s=b.getCanvas(),t=a(s).parent(),e=b.getOptions(),b.setData(g(b.getData())))}function g(b){for(var c=0,d=0,f=0,g=e.series.pie.combine.color,h=[],i=0;if||j/c>e.series.pie.combine.threshold)&&h.push({data:[[1,j]],color:b[i].color,label:b[i].label,angle:j*Math.PI*2/c,percent:j/(c/100)})}return f>1&&h.push({data:[[1,d]],color:g,label:e.series.pie.combine.label,angle:d*Math.PI*2/c,percent:d/(c/100)}),h}function h(b,f){function g(){y.clearRect(0,0,k,l),t.children().filter(".pieLabel, .pieLabelBackground").remove()}function h(){var a=e.series.pie.shadow.left,b=e.series.pie.shadow.top,c=10,d=e.series.pie.shadow.alpha,f=e.series.pie.radius>1?e.series.pie.radius:u*e.series.pie.radius;if(!(f>=k/2-a||f*e.series.pie.tilt>=l/2-b||c>=f)){y.save(),y.translate(a,b),y.globalAlpha=d,y.fillStyle="#000",y.translate(v,w),y.scale(1,e.series.pie.tilt);for(var g=1;c>=g;g++)y.beginPath(),y.arc(0,0,f,0,2*Math.PI,!1),y.fill(),f-=g;y.restore()}}function j(){function b(a,b,c){0>=a||isNaN(a)||(c?y.fillStyle=b:(y.strokeStyle=b,y.lineJoin="round"),y.beginPath(),Math.abs(a-2*Math.PI)>1e-9&&y.moveTo(0,0),y.arc(0,0,f,g,g+a/2,!1),y.arc(0,0,f,g+a/2,g+a,!1),y.closePath(),g+=a,c?y.fill():y.stroke())}function c(){function b(b,c,d){if(0==b.data[0][1])return!0;var g,h=e.legend.labelFormatter,i=e.series.pie.label.formatter;g=h?h(b.label,b):b.label,i&&(g=i(g,b));var j=(c+b.angle+c)/2,m=v+Math.round(Math.cos(j)*f),n=w+Math.round(Math.sin(j)*f)*e.series.pie.tilt,o=""+g+"";t.append(o);var p=t.children("#pieLabel"+d),q=n-p.height()/2,r=m-p.width()/2;if(p.css("top",q),p.css("left",r),0-q>0||0-r>0||l-(q+p.height())<0||k-(r+p.width())<0)return!1;if(0!=e.series.pie.label.background.opacity){var s=e.series.pie.label.background.color;null==s&&(s=b.color);var u="top:"+q+"px;left:"+r+"px;";a("
    ").css("opacity",e.series.pie.label.background.opacity).insertBefore(p)}return!0}for(var c=d,f=e.series.pie.label.radius>1?e.series.pie.label.radius:u*e.series.pie.label.radius,g=0;g=100*e.series.pie.label.threshold&&!b(n[g],c,g))return!1;c+=n[g].angle}return!0}var d=Math.PI*e.series.pie.startAngle,f=e.series.pie.radius>1?e.series.pie.radius:u*e.series.pie.radius;y.save(),y.translate(v,w),y.scale(1,e.series.pie.tilt),y.save();for(var g=d,h=0;h0){y.save(),y.lineWidth=e.series.pie.stroke.width,g=d;for(var h=0;hv?v=u:v>k-u&&(v=k-u);var n=b.getData(),o=0;do o>0&&(u*=d),o+=1,g(),e.series.pie.tilt<=.8&&h();while(!j()&&c>o);o>=c&&(g(),t.prepend("
    Could not draw pie with labels contained inside canvas
    ")),b.setSeries&&b.insertLegend&&(b.setSeries(n),b.insertLegend())}}function i(a){if(e.series.pie.innerRadius>0){a.save();var b=e.series.pie.innerRadius>1?e.series.pie.innerRadius:u*e.series.pie.innerRadius;a.globalCompositeOperation="destination-out",a.beginPath(),a.fillStyle=e.series.pie.stroke.color,a.arc(0,0,b,0,2*Math.PI,!1),a.fill(),a.closePath(),a.restore(),a.save(),a.beginPath(),a.strokeStyle=e.series.pie.stroke.color,a.arc(0,0,b,0,2*Math.PI,!1),a.stroke(),a.closePath(),a.restore()}}function j(a,b){for(var c=!1,d=-1,e=a.length,f=e-1;++d1?g.series.pie.radius:u*g.series.pie.radius,i=0;i1e-9&&b.moveTo(0,0),b.arc(0,0,e,a.startAngle,a.startAngle+a.angle/2,!1),b.arc(0,0,e,a.startAngle+a.angle/2,a.startAngle+a.angle,!1),b.closePath(),b.fill())}var d=a.getOptions(),e=d.series.pie.radius>1?d.series.pie.radius:u*d.series.pie.radius;b.save(),b.translate(v,w),b.scale(1,d.series.pie.tilt);for(var f=0;f1?b.series.pie.tilt=1:b.series.pie.tilt<0&&(b.series.pie.tilt=0))}),b.hooks.bindEvents.push(function(a,b){var c=a.getOptions();c.series.pie.show&&(c.grid.hoverable&&b.unbind("mousemove").mousemove(l),c.grid.clickable&&b.unbind("click").click(m))}),b.hooks.processDatapoints.push(function(a,b,c,d){var e=a.getOptions();e.series.pie.show&&f(a,b,c,d)}),b.hooks.drawOverlay.push(function(a,b){var c=a.getOptions();c.series.pie.show&&r(a,b)}),b.hooks.draw.push(function(a,b){var c=a.getOptions();c.series.pie.show&&h(a,b)})}var c=10,d=.95,e={series:{pie:{show:!1,radius:"auto",innerRadius:0,startAngle:1.5,tilt:1,shadow:{left:5,top:15,alpha:.02},offset:{top:0,left:"auto"},stroke:{color:"#fff",width:1},label:{show:"auto",formatter:function(a,b){return"
    "+a+"
    "+Math.round(b.percent)+"%
    "},radius:1,background:{color:null,opacity:0},threshold:0},combine:{threshold:-1,color:null,label:"Other"},highlight:{opacity:.5}}}};a.plot.plugins.push({init:b,options:e,name:"pie",version:"1.1"})}(jQuery); \ No newline at end of file +!function(a){function b(b){function f(b,c,d){x||(x=!0,s=b.getCanvas(),t=a(s).parent(),e=b.getOptions(),b.setData(g(b.getData())))}function g(b){for(var c=0,d=0,f=0,g=e.series.pie.combine.color,h=[],i=0;ie.series.pie.combine.threshold)&&h.push({data:[[1,j]],color:b[i].color,label:b[i].label,angle:j*Math.PI*2/c,percent:j/(c/100)})}return f>1&&h.push({data:[[1,d]],color:g,label:e.series.pie.combine.label,angle:d*Math.PI*2/c,percent:d/(c/100)}),h}function h(b,f){function g(){y.clearRect(0,0,k,l),t.children().filter(".pieLabel, .pieLabelBackground").remove()}function h(){var a=e.series.pie.shadow.left,b=e.series.pie.shadow.top,c=10,d=e.series.pie.shadow.alpha,f=e.series.pie.radius>1?e.series.pie.radius:u*e.series.pie.radius;if(!(f>=k/2-a||f*e.series.pie.tilt>=l/2-b||f<=c)){y.save(),y.translate(a,b),y.globalAlpha=d,y.fillStyle="#000",y.translate(v,w),y.scale(1,e.series.pie.tilt);for(var g=1;g<=c;g++)y.beginPath(),y.arc(0,0,f,0,2*Math.PI,!1),y.fill(),f-=g;y.restore()}}function j(){function b(a,b,c){a<=0||isNaN(a)||(c?y.fillStyle=b:(y.strokeStyle=b,y.lineJoin="round"),y.beginPath(),Math.abs(a-2*Math.PI)>1e-9&&y.moveTo(0,0),y.arc(0,0,f,g,g+a/2,!1),y.arc(0,0,f,g+a/2,g+a,!1),y.closePath(),g+=a,c?y.fill():y.stroke())}function c(){function b(b,c,d){if(0==b.data[0][1])return!0;var g,h=e.legend.labelFormatter,i=e.series.pie.label.formatter;g=h?h(b.label,b):b.label,i&&(g=i(g,b));var j=(c+b.angle+c)/2,m=v+Math.round(Math.cos(j)*f),n=w+Math.round(Math.sin(j)*f)*e.series.pie.tilt,o=""+g+"";t.append(o);var p=t.children("#pieLabel"+d),q=n-p.height()/2,r=m-p.width()/2;if(p.css("top",q),p.css("left",r),0-q>0||0-r>0||l-(q+p.height())<0||k-(r+p.width())<0)return!1;if(0!=e.series.pie.label.background.opacity){var s=e.series.pie.label.background.color;null==s&&(s=b.color);var u="top:"+q+"px;left:"+r+"px;";a("
    ").css("opacity",e.series.pie.label.background.opacity).insertBefore(p)}return!0}for(var c=d,f=e.series.pie.label.radius>1?e.series.pie.label.radius:u*e.series.pie.label.radius,g=0;g=100*e.series.pie.label.threshold&&!b(n[g],c,g))return!1;c+=n[g].angle}return!0}var d=Math.PI*e.series.pie.startAngle,f=e.series.pie.radius>1?e.series.pie.radius:u*e.series.pie.radius;y.save(),y.translate(v,w),y.scale(1,e.series.pie.tilt),y.save();for(var g=d,h=0;h0){y.save(),y.lineWidth=e.series.pie.stroke.width,g=d;for(var h=0;hk-u&&(v=k-u);var n=b.getData(),o=0;do o>0&&(u*=d),o+=1,g(),e.series.pie.tilt<=.8&&h();while(!j()&&o=c&&(g(),t.prepend("
    Could not draw pie with labels contained inside canvas
    ")),b.setSeries&&b.insertLegend&&(b.setSeries(n),b.insertLegend())}}function i(a){if(e.series.pie.innerRadius>0){a.save();var b=e.series.pie.innerRadius>1?e.series.pie.innerRadius:u*e.series.pie.innerRadius;a.globalCompositeOperation="destination-out",a.beginPath(),a.fillStyle=e.series.pie.stroke.color,a.arc(0,0,b,0,2*Math.PI,!1),a.fill(),a.closePath(),a.restore(),a.save(),a.beginPath(),a.strokeStyle=e.series.pie.stroke.color,a.arc(0,0,b,0,2*Math.PI,!1),a.stroke(),a.closePath(),a.restore()}}function j(a,b){for(var c=!1,d=-1,e=a.length,f=e-1;++d1?g.series.pie.radius:u*g.series.pie.radius,i=0;i1e-9&&b.moveTo(0,0),b.arc(0,0,e,a.startAngle,a.startAngle+a.angle/2,!1),b.arc(0,0,e,a.startAngle+a.angle/2,a.startAngle+a.angle,!1),b.closePath(),b.fill())}var d=a.getOptions(),e=d.series.pie.radius>1?d.series.pie.radius:u*d.series.pie.radius;b.save(),b.translate(v,w),b.scale(1,d.series.pie.tilt);for(var f=0;f1?b.series.pie.tilt=1:b.series.pie.tilt<0&&(b.series.pie.tilt=0))}),b.hooks.bindEvents.push(function(a,b){var c=a.getOptions();c.series.pie.show&&(c.grid.hoverable&&b.unbind("mousemove").mousemove(l),c.grid.clickable&&b.unbind("click").click(m))}),b.hooks.processDatapoints.push(function(a,b,c,d){var e=a.getOptions();e.series.pie.show&&f(a,b,c,d)}),b.hooks.drawOverlay.push(function(a,b){var c=a.getOptions();c.series.pie.show&&r(a,b)}),b.hooks.draw.push(function(a,b){var c=a.getOptions();c.series.pie.show&&h(a,b)})}var c=10,d=.95,e={series:{pie:{show:!1,radius:"auto",innerRadius:0,startAngle:1.5,tilt:1,shadow:{left:5,top:15,alpha:.02},offset:{top:0,left:"auto"},stroke:{color:"#fff",width:1},label:{show:"auto",formatter:function(a,b){return"
    "+a+"
    "+Math.round(b.percent)+"%
    "},radius:1,background:{color:null,opacity:0},threshold:0},combine:{threshold:-1,color:null,label:"Other"},highlight:{opacity:.5}}}};a.plot.plugins.push({init:b,options:e,name:"pie",version:"1.1"})}(jQuery); \ No newline at end of file diff --git a/assets/js/jquery-flot/jquery.flot.stack.min.js b/assets/js/jquery-flot/jquery.flot.stack.min.js index e8be501186d..2d8da5be1ae 100644 --- a/assets/js/jquery-flot/jquery.flot.stack.min.js +++ b/assets/js/jquery-flot/jquery.flot.stack.min.js @@ -1 +1 @@ -!function(a){function b(a){function b(a,b){for(var c=null,d=0;d2&&(t?d.format[2].x:d.format[2].y),v=s&&c.lines.steps,w=!0,x=t?1:0,y=t?0:1,z=0,A=0;;){if(z>=o.length)break;if(l=r.length,null==o[z]){for(m=0;n>m;++m)r.push(o[z+m]);z+=n}else if(A>=q.length){if(!s)for(m=0;n>m;++m)r.push(o[z+m]);z+=n}else if(null==q[A]){for(m=0;n>m;++m)r.push(null);w=!0,A+=p}else{if(f=o[z+x],g=o[z+y],i=q[A+x],j=q[A+y],k=0,f==i){for(m=0;n>m;++m)r.push(o[z+m]);r[l+y]+=j,k=j,z+=n,A+=p}else if(f>i){if(s&&z>0&&null!=o[z-n]){for(h=g+(o[z-n+y]-g)*(i-f)/(o[z-n+x]-f),r.push(i),r.push(h+j),m=2;n>m;++m)r.push(o[z+m]);k=j}A+=p}else{if(w&&s){z+=n;continue}for(m=0;n>m;++m)r.push(o[z+m]);s&&A>0&&null!=q[A-p]&&(k=j+(q[A-p+y]-j)*(f-i)/(q[A-p+x]-i)),r[l+y]+=k,z+=n}w=!1,l!=r.length&&u&&(r[l+2]+=k)}if(v&&l!=r.length&&l>0&&null!=r[l]&&r[l]!=r[l-n]&&r[l+1]!=r[l-n+1]){for(m=0;n>m;++m)r[l+n+m]=r[l+m];r[l+1]=r[l-n+1]}}d.points=r}}}a.hooks.processDatapoints.push(c)}var c={series:{stack:null}};a.plot.plugins.push({init:b,options:c,name:"stack",version:"1.2"})}(jQuery); \ No newline at end of file +!function(a){function b(a){function b(a,b){for(var c=null,d=0;d2&&(t?d.format[2].x:d.format[2].y),v=s&&c.lines.steps,w=!0,x=t?1:0,y=t?0:1,z=0,A=0;;){if(z>=o.length)break;if(l=r.length,null==o[z]){for(m=0;m=q.length){if(!s)for(m=0;mi){if(s&&z>0&&null!=o[z-n]){for(h=g+(o[z-n+y]-g)*(i-f)/(o[z-n+x]-f),r.push(i),r.push(h+j),m=2;m0&&null!=q[A-p]&&(k=j+(q[A-p+y]-j)*(f-i)/(q[A-p+x]-i)),r[l+y]+=k,z+=n}w=!1,l!=r.length&&u&&(r[l+2]+=k)}if(v&&l!=r.length&&l>0&&null!=r[l]&&r[l]!=r[l-n]&&r[l+1]!=r[l-n+1]){for(m=0;mh;null==c&&(c=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]),null==d&&(d=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]);var j;j=h>12?h-12:0==h?12:h;for(var k=0;k=g);++l);var m=i[l][0],n=i[l][1];if("year"==n){if(null!=f.minTickSize&&"year"==f.minTickSize[1])m=Math.floor(f.minTickSize[0]);else{var o=Math.pow(10,Math.floor(Math.log(a.delta/h.year)/Math.LN10)),p=a.delta/h.year/o;m=1.5>p?1:3>p?2:7.5>p?5:10,m*=o}1>m&&(m=1)}a.tickSize=f.tickSize||[m,n];var q=a.tickSize[0];n=a.tickSize[1];var r=q*h[n];"second"==n?d.setSeconds(b(d.getSeconds(),q)):"minute"==n?d.setMinutes(b(d.getMinutes(),q)):"hour"==n?d.setHours(b(d.getHours(),q)):"month"==n?d.setMonth(b(d.getMonth(),q)):"quarter"==n?d.setMonth(3*b(d.getMonth()/3,q)):"year"==n&&d.setFullYear(b(d.getFullYear(),q)),d.setMilliseconds(0),r>=h.minute&&d.setSeconds(0),r>=h.hour&&d.setMinutes(0),r>=h.day&&d.setHours(0),r>=4*h.day&&d.setDate(1),r>=2*h.month&&d.setMonth(b(d.getMonth(),3)),r>=2*h.quarter&&d.setMonth(b(d.getMonth(),6)),r>=h.year&&d.setMonth(0);var s,t=0,u=Number.NaN;do if(s=u,u=d.getTime(),c.push(u),"month"==n||"quarter"==n)if(1>q){d.setDate(1);var v=d.getTime();d.setMonth(d.getMonth()+("quarter"==n?3:1));var w=d.getTime();d.setTime(u+t*h.hour+(w-v)*q),t=d.getHours(),d.setHours(0)}else d.setMonth(d.getMonth()+q*("quarter"==n?3:1));else"year"==n?d.setFullYear(d.getFullYear()+q):d.setTime(u+r);while(u12?h-12:0==h?12:h;for(var k=0;k=g);++l);var m=i[l][0],n=i[l][1];if("year"==n){if(null!=f.minTickSize&&"year"==f.minTickSize[1])m=Math.floor(f.minTickSize[0]);else{var o=Math.pow(10,Math.floor(Math.log(a.delta/h.year)/Math.LN10)),p=a.delta/h.year/o;m=p<1.5?1:p<3?2:p<7.5?5:10,m*=o}m<1&&(m=1)}a.tickSize=f.tickSize||[m,n];var q=a.tickSize[0];n=a.tickSize[1];var r=q*h[n];"second"==n?d.setSeconds(b(d.getSeconds(),q)):"minute"==n?d.setMinutes(b(d.getMinutes(),q)):"hour"==n?d.setHours(b(d.getHours(),q)):"month"==n?d.setMonth(b(d.getMonth(),q)):"quarter"==n?d.setMonth(3*b(d.getMonth()/3,q)):"year"==n&&d.setFullYear(b(d.getFullYear(),q)),d.setMilliseconds(0),r>=h.minute&&d.setSeconds(0),r>=h.hour&&d.setMinutes(0),r>=h.day&&d.setHours(0),r>=4*h.day&&d.setDate(1),r>=2*h.month&&d.setMonth(b(d.getMonth(),3)),r>=2*h.quarter&&d.setMonth(b(d.getMonth(),6)),r>=h.year&&d.setMonth(0);var s,t=0,u=Number.NaN;do if(s=u,u=d.getTime(),c.push(u),"month"==n||"quarter"==n)if(q<1){d.setDate(1);var v=d.getTime();d.setMonth(d.getMonth()+("quarter"==n?3:1));var w=d.getTime();d.setTime(u+t*h.hour+(w-v)*q),t=d.getHours(),d.setHours(0)}else d.setMonth(d.getMonth()+q*("quarter"==n?3:1));else"year"==n?d.setFullYear(d.getFullYear()+q):d.setTime(u+r);while(ub;b++)if(b in this&&this[b]===a)return b;return-1};a=window.jQuery||window.Zepto||window.$,a.payment={},a.payment.fn={},a.fn.payment=function(){var b,c;return c=arguments[0],b=2<=arguments.length?y.call(arguments,1):[],a.payment.fn[c].apply(this,b)},e=/(\d{1,4})/g,a.payment.cards=d=[{type:"visaelectron",patterns:[4026,417500,4405,4508,4844,4913,4917],format:e,length:[16],cvcLength:[3],luhn:!0},{type:"maestro",patterns:[5018,502,503,506,56,58,639,6220,67],format:e,length:[12,13,14,15,16,17,18,19],cvcLength:[3],luhn:!0},{type:"forbrugsforeningen",patterns:[600],format:e,length:[16],cvcLength:[3],luhn:!0},{type:"dankort",patterns:[5019],format:e,length:[16],cvcLength:[3],luhn:!0},{type:"elo",patterns:[4011,4312,4389,4514,4573,4576,5041,5066,5067,509,6277,6362,6363,650,6516,6550],format:e,length:[16],cvcLength:[3],luhn:!0},{type:"visa",patterns:[4],format:e,length:[13,16],cvcLength:[3],luhn:!0},{type:"mastercard",patterns:[51,52,53,54,55,22,23,24,25,26,27],format:e,length:[16],cvcLength:[3],luhn:!0},{type:"amex",patterns:[34,37],format:/(\d{1,4})(\d{1,6})?(\d{1,5})?/,length:[15],cvcLength:[3,4],luhn:!0},{type:"dinersclub",patterns:[30,36,38,39],format:/(\d{1,4})(\d{1,6})?(\d{1,4})?/,length:[14],cvcLength:[3],luhn:!0},{type:"discover",patterns:[60,64,65,622],format:e,length:[16],cvcLength:[3],luhn:!0},{type:"unionpay",patterns:[62,88],format:e,length:[16,17,18,19],cvcLength:[3],luhn:!1},{type:"jcb",patterns:[35],format:e,length:[16],cvcLength:[3],luhn:!0}],b=function(a){var b,c,e,f,g,h,i,j;for(a=(a+"").replace(/\D/g,""),f=0,h=d.length;h>f;f++)for(b=d[f],j=b.patterns,g=0,i=j.length;i>g;g++)if(e=j[g],c=e+"",a.substr(0,c.length)===c)return b},c=function(a){var b,c,e;for(c=0,e=d.length;e>c;c++)if(b=d[c],b.type===a)return b},m=function(a){var b,c,d,e,f,g;for(d=!0,e=0,c=(a+"").split("").reverse(),f=0,g=c.length;g>f;f++)b=c[f],b=parseInt(b,10),(d=!d)&&(b*=2),b>9&&(b-=9),e+=b;return e%10===0},l=function(a){var b;return null!=a.prop("selectionStart")&&a.prop("selectionStart")!==a.prop("selectionEnd")?!0:!(null==("undefined"!=typeof document&&null!==document&&null!=(b=document.selection)?b.createRange:void 0)||!document.selection.createRange().text)},w=function(a,b){var c,d,e,f,g,h;try{d=b.prop("selectionStart")}catch(i){f=i,d=null}return g=b.val(),b.val(a),null!==d&&b.is(":focus")?(d===g.length&&(d=a.length),g!==a&&(h=g.slice(d-1,+d+1||9e9),c=a.slice(d-1,+d+1||9e9),e=a[d],/\d/.test(e)&&h===""+e+" "&&c===" "+e&&(d+=1)),b.prop("selectionStart",d),b.prop("selectionEnd",d)):void 0},r=function(a){var b,c,d,e,f,g,h,i;for(null==a&&(a=""),d="0123456789",e="0123456789",g="",b=a.split(""),h=0,i=b.length;i>h;h++)c=b[h],f=d.indexOf(c),f>-1&&(c=e[f]),g+=c;return g},q=function(b){var c;return c=a(b.currentTarget),setTimeout(function(){var a;return a=c.val(),a=r(a),a=a.replace(/\D/g,""),w(a,c)})},o=function(b){var c;return c=a(b.currentTarget),setTimeout(function(){var b;return b=c.val(),b=r(b),b=a.payment.formatCardNumber(b),w(b,c)})},h=function(c){var d,e,f,g,h,i,j;return f=String.fromCharCode(c.which),!/^\d+$/.test(f)||(d=a(c.currentTarget),j=d.val(),e=b(j+f),g=(j.replace(/\D/g,"")+f).length,i=16,e&&(i=e.length[e.length.length-1]),g>=i||null!=d.prop("selectionStart")&&d.prop("selectionStart")!==j.length)?void 0:(h=e&&"amex"===e.type?/^(\d{4}|\d{4}\s\d{6})$/:/(?:^|\s)(\d{4})$/,h.test(j)?(c.preventDefault(),setTimeout(function(){return d.val(j+" "+f)})):h.test(j+f)?(c.preventDefault(),setTimeout(function(){return d.val(j+f+" ")})):void 0)},f=function(b){var c,d;return c=a(b.currentTarget),d=c.val(),8!==b.which||null!=c.prop("selectionStart")&&c.prop("selectionStart")!==d.length?void 0:/\d\s$/.test(d)?(b.preventDefault(),setTimeout(function(){return c.val(d.replace(/\d\s$/,""))})):/\s\d?$/.test(d)?(b.preventDefault(),setTimeout(function(){return c.val(d.replace(/\d$/,""))})):void 0},p=function(b){var c;return c=a(b.currentTarget),setTimeout(function(){var b;return b=c.val(),b=r(b),b=a.payment.formatExpiry(b),w(b,c)})},i=function(b){var c,d,e;return d=String.fromCharCode(b.which),/^\d+$/.test(d)?(c=a(b.currentTarget),e=c.val()+d,/^\d$/.test(e)&&"0"!==e&&"1"!==e?(b.preventDefault(),setTimeout(function(){return c.val("0"+e+" / ")})):/^\d\d$/.test(e)?(b.preventDefault(),setTimeout(function(){var a,b;return a=parseInt(e[0],10),b=parseInt(e[1],10),b>2&&0!==a?c.val("0"+a+" / "+b):c.val(""+e+" / ")})):void 0):void 0},j=function(b){var c,d,e;return d=String.fromCharCode(b.which),/^\d+$/.test(d)?(c=a(b.currentTarget),e=c.val(),/^\d\d$/.test(e)?c.val(""+e+" / "):void 0):void 0},k=function(b){var c,d,e;return e=String.fromCharCode(b.which),"/"===e||" "===e?(c=a(b.currentTarget),d=c.val(),/^\d$/.test(d)&&"0"!==d?c.val("0"+d+" / "):void 0):void 0},g=function(b){var c,d;return c=a(b.currentTarget),d=c.val(),8!==b.which||null!=c.prop("selectionStart")&&c.prop("selectionStart")!==d.length?void 0:/\d\s\/\s$/.test(d)?(b.preventDefault(),setTimeout(function(){return c.val(d.replace(/\d\s\/\s$/,""))})):void 0},n=function(b){var c;return c=a(b.currentTarget),setTimeout(function(){var a;return a=c.val(),a=r(a),a=a.replace(/\D/g,"").slice(0,4),w(a,c)})},v=function(a){var b;return a.metaKey||a.ctrlKey?!0:32===a.which?!1:0===a.which?!0:a.which<33?!0:(b=String.fromCharCode(a.which),!!/[\d\s]/.test(b))},t=function(c){var d,e,f,g;return d=a(c.currentTarget),f=String.fromCharCode(c.which),/^\d+$/.test(f)&&!l(d)?(g=(d.val()+f).replace(/\D/g,""),e=b(g),e?g.length<=e.length[e.length.length-1]:g.length<=16):void 0},u=function(b){var c,d,e;return c=a(b.currentTarget),d=String.fromCharCode(b.which),/^\d+$/.test(d)&&!l(c)?(e=c.val()+d,e=e.replace(/\D/g,""),e.length>6?!1:void 0):void 0},s=function(b){var c,d,e;return c=a(b.currentTarget),d=String.fromCharCode(b.which),/^\d+$/.test(d)&&!l(c)?(e=c.val()+d,e.length<=4):void 0},x=function(b){var c,e,f,g,h;return c=a(b.currentTarget),h=c.val(),g=a.payment.cardType(h)||"unknown",c.hasClass(g)?void 0:(e=function(){var a,b,c;for(c=[],a=0,b=d.length;b>a;a++)f=d[a],c.push(f.type);return c}(),c.removeClass("unknown"),c.removeClass(e.join(" ")),c.addClass(g),c.toggleClass("identified","unknown"!==g),c.trigger("payment.cardType",g))},a.payment.fn.formatCardCVC=function(){return this.on("keypress",v),this.on("keypress",s),this.on("paste",n),this.on("change",n),this.on("input",n),this},a.payment.fn.formatCardExpiry=function(){return this.on("keypress",v),this.on("keypress",u),this.on("keypress",i),this.on("keypress",k),this.on("keypress",j),this.on("keydown",g),this.on("change",p),this.on("input",p),this},a.payment.fn.formatCardNumber=function(){return this.on("keypress",v),this.on("keypress",t),this.on("keypress",h),this.on("keydown",f),this.on("keyup",x),this.on("paste",o),this.on("change",o),this.on("input",o),this.on("input",x),this},a.payment.fn.restrictNumeric=function(){return this.on("keypress",v),this.on("paste",q),this.on("change",q),this.on("input",q),this},a.payment.fn.cardExpiryVal=function(){return a.payment.cardExpiryVal(a(this).val())},a.payment.cardExpiryVal=function(a){var b,c,d,e;return e=a.split(/[\s\/]+/,2),b=e[0],d=e[1],2===(null!=d?d.length:void 0)&&/^\d+$/.test(d)&&(c=(new Date).getFullYear(),c=c.toString().slice(0,2),d=c+d),b=parseInt(b,10),d=parseInt(d,10),{month:b,year:d}},a.payment.validateCardNumber=function(a){var c,d;return a=(a+"").replace(/\s+|-/g,""),/^\d+$/.test(a)?(c=b(a),c?(d=a.length,z.call(c.length,d)>=0&&(c.luhn===!1||m(a))):!1):!1},a.payment.validateCardExpiry=function(b,c){var d,e,f;return"object"==typeof b&&"month"in b&&(f=b,b=f.month,c=f.year),b&&c?(b=a.trim(b),c=a.trim(c),/^\d+$/.test(b)&&/^\d+$/.test(c)&&b>=1&&12>=b?(2===c.length&&(c=70>c?"20"+c:"19"+c),4!==c.length?!1:(e=new Date(c,b),d=new Date,e.setMonth(e.getMonth()-1),e.setMonth(e.getMonth()+1,1),e>d)):!1):!1},a.payment.validateCardCVC=function(b,d){var e,f;return b=a.trim(b),/^\d+$/.test(b)?(e=c(d),null!=e?(f=b.length,z.call(e.cvcLength,f)>=0):b.length>=3&&b.length<=4):!1},a.payment.cardType=function(a){var c;return a?(null!=(c=b(a))?c.type:void 0)||null:null},a.payment.formatCardNumber=function(c){var d,e,f,g;return c=c.replace(/\D/g,""),(d=b(c))?(f=d.length[d.length.length-1],c=c.slice(0,f),d.format.global?null!=(g=c.match(d.format))?g.join(" "):void 0:(e=d.format.exec(c),null!=e?(e.shift(),e=a.grep(e,function(a){return a}),e.join(" ")):void 0)):c},a.payment.formatExpiry=function(a){var b,c,d,e;return(c=a.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/))?(b=c[1]||"",d=c[2]||"",e=c[3]||"",e.length>0?d=" / ":" /"===d?(b=b.substring(0,1),d=""):2===b.length||d.length>0?d=" / ":1===b.length&&"0"!==b&&"1"!==b&&(b="0"+b,d=" / "),b+d+e):""}}).call(this)}); \ No newline at end of file +jQuery(function(a){(function(){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y=[].slice,z=[].indexOf||function(a){for(var b=0,c=this.length;b9&&(b-=9),e+=b;return e%10===0},l=function(a){var b;return null!=a.prop("selectionStart")&&a.prop("selectionStart")!==a.prop("selectionEnd")||!(null==("undefined"!=typeof document&&null!==document&&null!=(b=document.selection)?b.createRange:void 0)||!document.selection.createRange().text)},w=function(a,b){var c,d,e,f,g,h;try{d=b.prop("selectionStart")}catch(i){f=i,d=null}if(g=b.val(),b.val(a),null!==d&&b.is(":focus"))return d===g.length&&(d=a.length),g!==a&&(h=g.slice(d-1,+d+1||9e9),c=a.slice(d-1,+d+1||9e9),e=a[d],/\d/.test(e)&&h===""+e+" "&&c===" "+e&&(d+=1)),b.prop("selectionStart",d),b.prop("selectionEnd",d)},r=function(a){var b,c,d,e,f,g,h,i;for(null==a&&(a=""),d="0123456789",e="0123456789",g="",b=a.split(""),h=0,i=b.length;h-1&&(c=e[f]),g+=c;return g},q=function(b){var c;return c=a(b.currentTarget),setTimeout(function(){var a;return a=c.val(),a=r(a),a=a.replace(/\D/g,""),w(a,c)})},o=function(b){var c;return c=a(b.currentTarget),setTimeout(function(){var b;return b=c.val(),b=r(b),b=a.payment.formatCardNumber(b),w(b,c)})},h=function(c){var d,e,f,g,h,i,j;if(f=String.fromCharCode(c.which),/^\d+$/.test(f)&&(d=a(c.currentTarget),j=d.val(),e=b(j+f),g=(j.replace(/\D/g,"")+f).length,i=16,e&&(i=e.length[e.length.length-1]),!(g>=i||null!=d.prop("selectionStart")&&d.prop("selectionStart")!==j.length)))return h=e&&"amex"===e.type?/^(\d{4}|\d{4}\s\d{6})$/:/(?:^|\s)(\d{4})$/,h.test(j)?(c.preventDefault(),setTimeout(function(){return d.val(j+" "+f)})):h.test(j+f)?(c.preventDefault(),setTimeout(function(){return d.val(j+f+" ")})):void 0},f=function(b){var c,d;if(c=a(b.currentTarget),d=c.val(),8===b.which&&(null==c.prop("selectionStart")||c.prop("selectionStart")===d.length))return/\d\s$/.test(d)?(b.preventDefault(),setTimeout(function(){return c.val(d.replace(/\d\s$/,""))})):/\s\d?$/.test(d)?(b.preventDefault(),setTimeout(function(){return c.val(d.replace(/\d$/,""))})):void 0},p=function(b){var c;return c=a(b.currentTarget),setTimeout(function(){var b;return b=c.val(),b=r(b),b=a.payment.formatExpiry(b),w(b,c)})},i=function(b){var c,d,e;if(d=String.fromCharCode(b.which),/^\d+$/.test(d))return c=a(b.currentTarget),e=c.val()+d,/^\d$/.test(e)&&"0"!==e&&"1"!==e?(b.preventDefault(),setTimeout(function(){return c.val("0"+e+" / ")})):/^\d\d$/.test(e)?(b.preventDefault(),setTimeout(function(){var a,b;return a=parseInt(e[0],10),b=parseInt(e[1],10),b>2&&0!==a?c.val("0"+a+" / "+b):c.val(""+e+" / ")})):void 0},j=function(b){var c,d,e;if(d=String.fromCharCode(b.which),/^\d+$/.test(d))return c=a(b.currentTarget),e=c.val(),/^\d\d$/.test(e)?c.val(""+e+" / "):void 0},k=function(b){var c,d,e;if(e=String.fromCharCode(b.which),"/"===e||" "===e)return c=a(b.currentTarget),d=c.val(),/^\d$/.test(d)&&"0"!==d?c.val("0"+d+" / "):void 0},g=function(b){var c,d;if(c=a(b.currentTarget),d=c.val(),8===b.which&&(null==c.prop("selectionStart")||c.prop("selectionStart")===d.length))return/\d\s\/\s$/.test(d)?(b.preventDefault(),setTimeout(function(){return c.val(d.replace(/\d\s\/\s$/,""))})):void 0},n=function(b){var c;return c=a(b.currentTarget),setTimeout(function(){var a;return a=c.val(),a=r(a),a=a.replace(/\D/g,"").slice(0,4),w(a,c)})},v=function(a){var b;return!(!a.metaKey&&!a.ctrlKey)||32!==a.which&&(0===a.which||(a.which<33||(b=String.fromCharCode(a.which),!!/[\d\s]/.test(b))))},t=function(c){var d,e,f,g;if(d=a(c.currentTarget),f=String.fromCharCode(c.which),/^\d+$/.test(f)&&!l(d))return g=(d.val()+f).replace(/\D/g,""),e=b(g),e?g.length<=e.length[e.length.length-1]:g.length<=16},u=function(b){var c,d,e;if(c=a(b.currentTarget),d=String.fromCharCode(b.which),/^\d+$/.test(d)&&!l(c))return e=c.val()+d,e=e.replace(/\D/g,""),!(e.length>6)&&void 0},s=function(b){var c,d,e;if(c=a(b.currentTarget),d=String.fromCharCode(b.which),/^\d+$/.test(d)&&!l(c))return e=c.val()+d,e.length<=4},x=function(b){var c,e,f,g,h;if(c=a(b.currentTarget),h=c.val(),g=a.payment.cardType(h)||"unknown",!c.hasClass(g))return e=function(){var a,b,c;for(c=[],a=0,b=d.length;a=0&&(c.luhn===!1||m(a))))},a.payment.validateCardExpiry=function(b,c){var d,e,f;return"object"==typeof b&&"month"in b&&(f=b,b=f.month,c=f.year),!(!b||!c)&&(b=a.trim(b),c=a.trim(c),!!/^\d+$/.test(b)&&(!!/^\d+$/.test(c)&&(1<=b&&b<=12&&(2===c.length&&(c=c<70?"20"+c:"19"+c),4===c.length&&(e=new Date(c,b),d=new Date,e.setMonth(e.getMonth()-1),e.setMonth(e.getMonth()+1,1),e>d)))))},a.payment.validateCardCVC=function(b,d){var e,f;return b=a.trim(b),!!/^\d+$/.test(b)&&(e=c(d),null!=e?(f=b.length,z.call(e.cvcLength,f)>=0):b.length>=3&&b.length<=4)},a.payment.cardType=function(a){var c;return a?(null!=(c=b(a))?c.type:void 0)||null:null},a.payment.formatCardNumber=function(c){var d,e,f,g;return c=c.replace(/\D/g,""),(d=b(c))?(f=d.length[d.length.length-1],c=c.slice(0,f),d.format.global?null!=(g=c.match(d.format))?g.join(" "):void 0:(e=d.format.exec(c),null!=e?(e.shift(),e=a.grep(e,function(a){return a}),e.join(" ")):void 0)):c},a.payment.formatExpiry=function(a){var b,c,d,e;return(c=a.match(/^\D*(\d{1,2})(\D+)?(\d{1,4})?/))?(b=c[1]||"",d=c[2]||"",e=c[3]||"",e.length>0?d=" / ":" /"===d?(b=b.substring(0,1),d=""):2===b.length||d.length>0?d=" / ":1===b.length&&"0"!==b&&"1"!==b&&(b="0"+b,d=" / "),b+d+e):""}}).call(this)}); \ No newline at end of file diff --git a/assets/js/jquery-qrcode/jquery.qrcode.min.js b/assets/js/jquery-qrcode/jquery.qrcode.min.js index 786e42650a0..997f42d1534 100644 --- a/assets/js/jquery-qrcode/jquery.qrcode.min.js +++ b/assets/js/jquery-qrcode/jquery.qrcode.min.js @@ -1 +1 @@ -function QR8bitByte(a){this.mode=QRMode.MODE_8BIT_BYTE,this.data=a}function QRCode(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=new Array}function QRPolynomial(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;ca||this.moduleCount<=a||0>b||this.moduleCount<=b)throw new Error(a+","+b);return this.modules[a][b]},getModuleCount:function(){return this.moduleCount},make:function(){if(this.typeNumber<1){var a=1;for(a=1;40>a;a++){for(var b=QRRSBlock.getRSBlocks(a,this.errorCorrectLevel),c=new QRBitBuffer,d=0,e=0;e=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=QRCode.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,b)},setupPositionProbePattern:function(a,b){for(var c=-1;7>=c;c++)if(!(-1>=a+c||this.moduleCount<=a+c))for(var d=-1;7>=d;d++)-1>=b+d||this.moduleCount<=b+d||(c>=0&&6>=c&&(0==d||6==d)||d>=0&&6>=d&&(0==c||6==c)||c>=2&&4>=c&&d>=2&&4>=d?this.modules[a+c][b+d]=!0:this.modules[a+c][b+d]=!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;8>c;c++){this.makeImpl(!0,c);var d=QRUtil.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f=f;f++)for(var g=-2;2>=g;g++)-2==f||2==f||-2==g||2==g||0==f&&0==g?this.modules[d+f][e+g]=!0:this.modules[d+f][e+g]=!1}},setupTypeNumber:function(a){for(var b=QRUtil.getBCHTypeNumber(this.typeNumber),c=0;18>c;c++){var d=!a&&1==(b>>c&1);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;18>c;c++){var d=!a&&1==(b>>c&1);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=QRUtil.getBCHTypeInfo(c),e=0;15>e;e++){var f=!a&&1==(d>>e&1);6>e?this.modules[e][8]=f:8>e?this.modules[e+1][8]=f:this.modules[this.moduleCount-15+e][8]=f}for(var e=0;15>e;e++){var f=!a&&1==(d>>e&1);8>e?this.modules[8][this.moduleCount-e-1]=f:9>e?this.modules[8][15-e-1+1]=f:this.modules[8][15-e-1]=f}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,f=0,g=this.moduleCount-1;g>0;g-=2)for(6==g&&g--;;){for(var h=0;2>h;h++)if(null==this.modules[d][g-h]){var i=!1;f>>e&1));var j=QRUtil.getMask(b,d,g-h);j&&(i=!i),this.modules[d][g-h]=i,e--,-1==e&&(f++,e=7)}if(d+=c,0>d||this.moduleCount<=d){d-=c,c=-c;break}}}},QRCode.PAD0=236,QRCode.PAD1=17,QRCode.createData=function(a,b,c){for(var d=QRRSBlock.getRSBlocks(a,b),e=new QRBitBuffer,f=0;f8*h)throw new Error("code length overflow. ("+e.getLengthInBits()+">"+8*h+")");for(e.getLengthInBits()+4<=8*h&&e.put(0,4);e.getLengthInBits()%8!=0;)e.putBit(!1);for(;;){if(e.getLengthInBits()>=8*h)break;if(e.put(QRCode.PAD0,8),e.getLengthInBits()>=8*h)break;e.put(QRCode.PAD1,8)}return QRCode.createBytes(e,d)},QRCode.createBytes=function(a,b){for(var c=0,d=0,e=0,f=new Array(b.length),g=new Array(b.length),h=0;h=0?n.get(o):0}}for(var p=0,k=0;kk;k++)for(var h=0;hk;k++)for(var h=0;h=0;)b^=QRUtil.G15<=0;)b^=QRUtil.G18<>>=1;return b},getPatternPosition:function(a){return QRUtil.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case QRMaskPattern.PATTERN000:return(b+c)%2==0;case QRMaskPattern.PATTERN001:return b%2==0;case QRMaskPattern.PATTERN010:return c%3==0;case QRMaskPattern.PATTERN011:return(b+c)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(b/2)+Math.floor(c/3))%2==0;case QRMaskPattern.PATTERN101:return b*c%2+b*c%3==0;case QRMaskPattern.PATTERN110:return(b*c%2+b*c%3)%2==0;case QRMaskPattern.PATTERN111:return(b*c%3+(b+c)%2)%2==0;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new QRPolynomial([1],0),c=0;a>c;c++)b=b.multiply(new QRPolynomial([1,QRMath.gexp(c)],0));return b},getLengthInBits:function(a,b){if(b>=1&&10>b)switch(a){case QRMode.MODE_NUMBER:return 10;case QRMode.MODE_ALPHA_NUM:return 9;case QRMode.MODE_8BIT_BYTE:return 8;case QRMode.MODE_KANJI:return 8;default:throw new Error("mode:"+a)}else if(27>b)switch(a){case QRMode.MODE_NUMBER:return 12;case QRMode.MODE_ALPHA_NUM:return 11;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 10;default:throw new Error("mode:"+a)}else{if(!(41>b))throw new Error("type:"+b);switch(a){case QRMode.MODE_NUMBER:return 14;case QRMode.MODE_ALPHA_NUM:return 13;case QRMode.MODE_8BIT_BYTE:return 16;case QRMode.MODE_KANJI:return 12;default:throw new Error("mode:"+a)}}},getLostPoint:function(a){for(var b=a.getModuleCount(),c=0,d=0;b>d;d++)for(var e=0;b>e;e++){for(var f=0,g=a.isDark(d,e),h=-1;1>=h;h++)if(!(0>d+h||d+h>=b))for(var i=-1;1>=i;i++)0>e+i||e+i>=b||0==h&&0==i||g==a.isDark(d+h,e+i)&&f++;f>5&&(c+=3+f-5)}for(var d=0;b-1>d;d++)for(var e=0;b-1>e;e++){var j=0;a.isDark(d,e)&&j++,a.isDark(d+1,e)&&j++,a.isDark(d,e+1)&&j++,a.isDark(d+1,e+1)&&j++,0!=j&&4!=j||(c+=3)}for(var d=0;b>d;d++)for(var e=0;b-6>e;e++)a.isDark(d,e)&&!a.isDark(d,e+1)&&a.isDark(d,e+2)&&a.isDark(d,e+3)&&a.isDark(d,e+4)&&!a.isDark(d,e+5)&&a.isDark(d,e+6)&&(c+=40);for(var e=0;b>e;e++)for(var d=0;b-6>d;d++)a.isDark(d,e)&&!a.isDark(d+1,e)&&a.isDark(d+2,e)&&a.isDark(d+3,e)&&a.isDark(d+4,e)&&!a.isDark(d+5,e)&&a.isDark(d+6,e)&&(c+=40);for(var k=0,e=0;b>e;e++)for(var d=0;b>d;d++)a.isDark(d,e)&&k++;var l=Math.abs(100*k/b/b-50)/5;return c+=10*l}},QRMath={glog:function(a){if(1>a)throw new Error("glog("+a+")");return QRMath.LOG_TABLE[a]},gexp:function(a){for(;0>a;)a+=255;for(;a>=256;)a-=255;return QRMath.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},i=0;8>i;i++)QRMath.EXP_TABLE[i]=1<i;i++)QRMath.EXP_TABLE[i]=QRMath.EXP_TABLE[i-4]^QRMath.EXP_TABLE[i-5]^QRMath.EXP_TABLE[i-6]^QRMath.EXP_TABLE[i-8];for(var i=0;255>i;i++)QRMath.LOG_TABLE[QRMath.EXP_TABLE[i]]=i;QRPolynomial.prototype={get:function(a){return this.num[a]},getLength:function(){return this.num.length},multiply:function(a){for(var b=new Array(this.getLength()+a.getLength()-1),c=0;cf;f++)for(var g=c[3*f+0],h=c[3*f+1],i=c[3*f+2],j=0;g>j;j++)e.push(new QRRSBlock(h,i));return e},QRRSBlock.getRsBlockTable=function(a,b){switch(b){case QRErrorCorrectLevel.L:return QRRSBlock.RS_BLOCK_TABLE[4*(a-1)+0];case QRErrorCorrectLevel.M:return QRRSBlock.RS_BLOCK_TABLE[4*(a-1)+1];case QRErrorCorrectLevel.Q:return QRRSBlock.RS_BLOCK_TABLE[4*(a-1)+2];case QRErrorCorrectLevel.H:return QRRSBlock.RS_BLOCK_TABLE[4*(a-1)+3];default:return}},QRBitBuffer.prototype={get:function(a){var b=Math.floor(a/8);return 1==(this.buffer[b]>>>7-a%8&1)},put:function(a,b){for(var c=0;b>c;c++)this.putBit(1==(a>>>b-c-1&1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}},function(a){a.fn.qrcode=function(b){"string"==typeof b&&(b={text:b}),b=a.extend({},{render:"canvas",width:256,height:256,typeNumber:-1,correctLevel:QRErrorCorrectLevel.H,background:"#ffffff",foreground:"#000000"},b);var c=function(){var a=new QRCode(b.typeNumber,b.correctLevel);a.addData(b.text),a.make();var c=document.createElement("canvas");c.width=b.width,c.height=b.height;for(var d=c.getContext("2d"),e=b.width/a.getModuleCount(),f=b.height/a.getModuleCount(),g=0;g").css("width",b.width+"px").css("height",b.height+"px").css("border","0px").css("border-collapse","collapse").css("background-color",b.background),e=b.width/c.getModuleCount(),f=b.height/c.getModuleCount(),g=0;g").css("height",f+"px").appendTo(d),i=0;i").css("width",e+"px").css("background-color",c.isDark(g,i)?b.foreground:b.background).appendTo(h);return d};return this.each(function(){var e="canvas"==b.render?c():d();a(e).appendTo(this)})}}(jQuery); \ No newline at end of file +function QR8bitByte(a){this.mode=QRMode.MODE_8BIT_BYTE,this.data=a}function QRCode(a,b){this.typeNumber=a,this.errorCorrectLevel=b,this.modules=null,this.moduleCount=0,this.dataCache=null,this.dataList=new Array}function QRPolynomial(a,b){if(void 0==a.length)throw new Error(a.length+"/"+b);for(var c=0;c=7&&this.setupTypeNumber(a),null==this.dataCache&&(this.dataCache=QRCode.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,b)},setupPositionProbePattern:function(a,b){for(var c=-1;c<=7;c++)if(!(a+c<=-1||this.moduleCount<=a+c))for(var d=-1;d<=7;d++)b+d<=-1||this.moduleCount<=b+d||(0<=c&&c<=6&&(0==d||6==d)||0<=d&&d<=6&&(0==c||6==c)||2<=c&&c<=4&&2<=d&&d<=4?this.modules[a+c][b+d]=!0:this.modules[a+c][b+d]=!1)},getBestMaskPattern:function(){for(var a=0,b=0,c=0;c<8;c++){this.makeImpl(!0,c);var d=QRUtil.getLostPoint(this);(0==c||a>d)&&(a=d,b=c)}return b},createMovieClip:function(a,b,c){var d=a.createEmptyMovieClip(b,c),e=1;this.make();for(var f=0;f>c&1);this.modules[Math.floor(c/3)][c%3+this.moduleCount-8-3]=d}for(var c=0;c<18;c++){var d=!a&&1==(b>>c&1);this.modules[c%3+this.moduleCount-8-3][Math.floor(c/3)]=d}},setupTypeInfo:function(a,b){for(var c=this.errorCorrectLevel<<3|b,d=QRUtil.getBCHTypeInfo(c),e=0;e<15;e++){var f=!a&&1==(d>>e&1);e<6?this.modules[e][8]=f:e<8?this.modules[e+1][8]=f:this.modules[this.moduleCount-15+e][8]=f}for(var e=0;e<15;e++){var f=!a&&1==(d>>e&1);e<8?this.modules[8][this.moduleCount-e-1]=f:e<9?this.modules[8][15-e-1+1]=f:this.modules[8][15-e-1]=f}this.modules[this.moduleCount-8][8]=!a},mapData:function(a,b){for(var c=-1,d=this.moduleCount-1,e=7,f=0,g=this.moduleCount-1;g>0;g-=2)for(6==g&&g--;;){for(var h=0;h<2;h++)if(null==this.modules[d][g-h]){var i=!1;f>>e&1));var j=QRUtil.getMask(b,d,g-h);j&&(i=!i),this.modules[d][g-h]=i,e--,e==-1&&(f++,e=7)}if(d+=c,d<0||this.moduleCount<=d){d-=c,c=-c;break}}}},QRCode.PAD0=236,QRCode.PAD1=17,QRCode.createData=function(a,b,c){for(var d=QRRSBlock.getRSBlocks(a,b),e=new QRBitBuffer,f=0;f8*h)throw new Error("code length overflow. ("+e.getLengthInBits()+">"+8*h+")");for(e.getLengthInBits()+4<=8*h&&e.put(0,4);e.getLengthInBits()%8!=0;)e.putBit(!1);for(;;){if(e.getLengthInBits()>=8*h)break;if(e.put(QRCode.PAD0,8),e.getLengthInBits()>=8*h)break;e.put(QRCode.PAD1,8)}return QRCode.createBytes(e,d)},QRCode.createBytes=function(a,b){for(var c=0,d=0,e=0,f=new Array(b.length),g=new Array(b.length),h=0;h=0?n.get(o):0}}for(var p=0,k=0;k=0;)b^=QRUtil.G15<=0;)b^=QRUtil.G18<>>=1;return b},getPatternPosition:function(a){return QRUtil.PATTERN_POSITION_TABLE[a-1]},getMask:function(a,b,c){switch(a){case QRMaskPattern.PATTERN000:return(b+c)%2==0;case QRMaskPattern.PATTERN001:return b%2==0;case QRMaskPattern.PATTERN010:return c%3==0;case QRMaskPattern.PATTERN011:return(b+c)%3==0;case QRMaskPattern.PATTERN100:return(Math.floor(b/2)+Math.floor(c/3))%2==0;case QRMaskPattern.PATTERN101:return b*c%2+b*c%3==0;case QRMaskPattern.PATTERN110:return(b*c%2+b*c%3)%2==0;case QRMaskPattern.PATTERN111:return(b*c%3+(b+c)%2)%2==0;default:throw new Error("bad maskPattern:"+a)}},getErrorCorrectPolynomial:function(a){for(var b=new QRPolynomial([1],0),c=0;c5&&(c+=3+f-5)}for(var d=0;d=256;)a-=255;return QRMath.EXP_TABLE[a]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},i=0;i<8;i++)QRMath.EXP_TABLE[i]=1<>>7-a%8&1)},put:function(a,b){for(var c=0;c>>b-c-1&1))},getLengthInBits:function(){return this.length},putBit:function(a){var b=Math.floor(this.length/8);this.buffer.length<=b&&this.buffer.push(0),a&&(this.buffer[b]|=128>>>this.length%8),this.length++}},function(a){a.fn.qrcode=function(b){"string"==typeof b&&(b={text:b}),b=a.extend({},{render:"canvas",width:256,height:256,typeNumber:-1,correctLevel:QRErrorCorrectLevel.H,background:"#ffffff",foreground:"#000000"},b);var c=function(){var a=new QRCode(b.typeNumber,b.correctLevel);a.addData(b.text),a.make();var c=document.createElement("canvas");c.width=b.width,c.height=b.height;for(var d=c.getContext("2d"),e=b.width/a.getModuleCount(),f=b.height/a.getModuleCount(),g=0;g").css("width",b.width+"px").css("height",b.height+"px").css("border","0px").css("border-collapse","collapse").css("background-color",b.background),e=b.width/c.getModuleCount(),f=b.height/c.getModuleCount(),g=0;g").css("height",f+"px").appendTo(d),i=0;i").css("width",e+"px").css("background-color",c.isDark(g,i)?b.foreground:b.background).appendTo(h);return d};return this.each(function(){var e="canvas"==b.render?c():d();a(e).appendTo(this)})}}(jQuery); \ No newline at end of file diff --git a/assets/js/jquery-serializejson/jquery.serializejson.min.js b/assets/js/jquery-serializejson/jquery.serializejson.min.js index 2490903a4b8..ad4dccfe84c 100644 --- a/assets/js/jquery-serializejson/jquery.serializejson.min.js +++ b/assets/js/jquery-serializejson/jquery.serializejson.min.js @@ -7,4 +7,4 @@ Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. */ -!function(a){"use strict";a.fn.serializeJSON=function(b){var c,d,e,f,g,h,i;return h=a.serializeJSON,i=h.setupOpts(b),d=this.serializeArray(),h.readCheckboxUncheckedValues(d,this,i),c={},a.each(d,function(a,b){e=h.splitInputNameIntoKeysArray(b.name,i),f=e.pop(),"skip"!==f&&(g=h.parseValue(b.value,f,i),i.parseWithFunction&&"_"===f&&(g=i.parseWithFunction(g,b.name)),h.deepSet(c,e,g,i))}),c},a.serializeJSON={defaultOptions:{checkboxUncheckedValue:void 0,parseNumbers:!1,parseBooleans:!1,parseNulls:!1,parseAll:!1,parseWithFunction:null,customTypes:{},defaultTypes:{string:function(a){return String(a)},number:function(a){return Number(a)},"boolean":function(a){var b=["false","null","undefined","","0"];return-1===b.indexOf(a)},"null":function(a){var b=["false","null","undefined","","0"];return-1===b.indexOf(a)?a:null},array:function(a){return JSON.parse(a)},object:function(a){return JSON.parse(a)},auto:function(b){return a.serializeJSON.parseValue(b,null,{parseNumbers:!0,parseBooleans:!0,parseNulls:!0})}},useIntKeysAsArrayIndex:!1},setupOpts:function(b){var c,d,e,f,g,h;h=a.serializeJSON,null==b&&(b={}),e=h.defaultOptions||{},d=["checkboxUncheckedValue","parseNumbers","parseBooleans","parseNulls","parseAll","parseWithFunction","customTypes","defaultTypes","useIntKeysAsArrayIndex"];for(c in b)if(-1===d.indexOf(c))throw new Error("serializeJSON ERROR: invalid option '"+c+"'. Please use one of "+d.join(", "));return f=function(a){return b[a]!==!1&&""!==b[a]&&(b[a]||e[a])},g=f("parseAll"),{checkboxUncheckedValue:f("checkboxUncheckedValue"),parseNumbers:g||f("parseNumbers"),parseBooleans:g||f("parseBooleans"),parseNulls:g||f("parseNulls"),parseWithFunction:f("parseWithFunction"),typeFunctions:a.extend({},f("defaultTypes"),f("customTypes")),useIntKeysAsArrayIndex:f("useIntKeysAsArrayIndex")}},parseValue:function(b,c,d){var e,f;return f=a.serializeJSON,e=d.typeFunctions&&d.typeFunctions[c],e?e(b):d.parseNumbers&&f.isNumeric(b)?Number(b):!d.parseBooleans||"true"!==b&&"false"!==b?d.parseNulls&&"null"==b?null:b:"true"===b},isObject:function(a){return a===Object(a)},isUndefined:function(a){return void 0===a},isValidArrayIndex:function(a){return/^[0-9]+$/.test(String(a))},isNumeric:function(a){return a-parseFloat(a)>=0},optionKeys:function(a){if(Object.keys)return Object.keys(a);var b,c=[];for(b in a)c.push(b);return c},splitInputNameIntoKeysArray:function(b,c){var d,e,f,g,h;return h=a.serializeJSON,g=h.extractTypeFromInputName(b,c),e=g[0],f=g[1],d=e.split("["),d=a.map(d,function(a){return a.replace(/\]/g,"")}),""===d[0]&&d.shift(),d.push(f),d},extractTypeFromInputName:function(b,c){var d,e,f;if(d=b.match(/(.*):([^:]+)$/)){if(f=a.serializeJSON,e=f.optionKeys(c?c.typeFunctions:f.defaultOptions.defaultTypes),e.push("skip"),-1!==e.indexOf(d[2]))return[d[1],d[2]];throw new Error("serializeJSON ERROR: Invalid type "+d[2]+" found in input name '"+b+"', please use one of "+e.join(", "))}return[b,"_"]},deepSet:function(b,c,d,e){var f,g,h,i,j,k;if(null==e&&(e={}),k=a.serializeJSON,k.isUndefined(b))throw new Error("ArgumentError: param 'o' expected to be an object or array, found undefined");if(!c||0===c.length)throw new Error("ArgumentError: param 'keys' expected to be an array with least one element");f=c[0],1===c.length?""===f?b.push(d):b[f]=d:(g=c[1],""===f&&(i=b.length-1,j=b[i],f=k.isObject(j)&&(k.isUndefined(j[g])||c.length>2)?i:i+1),""===g?!k.isUndefined(b[f])&&a.isArray(b[f])||(b[f]=[]):e.useIntKeysAsArrayIndex&&k.isValidArrayIndex(g)?!k.isUndefined(b[f])&&a.isArray(b[f])||(b[f]=[]):!k.isUndefined(b[f])&&k.isObject(b[f])||(b[f]={}),h=c.slice(1),k.deepSet(b[f],h,d,e))},readCheckboxUncheckedValues:function(b,c,d){var e,f,g,h,i;null==d&&(d={}),i=a.serializeJSON,e="input[type=checkbox][name]:not(:checked):not([disabled])",f=c.find(e).add(c.filter(e)),f.each(function(c,e){g=a(e),h=g.attr("data-unchecked-value"),h?b.push({name:e.name,value:h}):i.isUndefined(d.checkboxUncheckedValue)||b.push({name:e.name,value:d.checkboxUncheckedValue})})}}}(window.jQuery||window.Zepto||window.$); \ No newline at end of file +!function(a){"use strict";a.fn.serializeJSON=function(b){var c,d,e,f,g,h,i;return h=a.serializeJSON,i=h.setupOpts(b),d=this.serializeArray(),h.readCheckboxUncheckedValues(d,this,i),c={},a.each(d,function(a,b){e=h.splitInputNameIntoKeysArray(b.name,i),f=e.pop(),"skip"!==f&&(g=h.parseValue(b.value,f,i),i.parseWithFunction&&"_"===f&&(g=i.parseWithFunction(g,b.name)),h.deepSet(c,e,g,i))}),c},a.serializeJSON={defaultOptions:{checkboxUncheckedValue:void 0,parseNumbers:!1,parseBooleans:!1,parseNulls:!1,parseAll:!1,parseWithFunction:null,customTypes:{},defaultTypes:{string:function(a){return String(a)},number:function(a){return Number(a)},"boolean":function(a){var b=["false","null","undefined","","0"];return b.indexOf(a)===-1},"null":function(a){var b=["false","null","undefined","","0"];return b.indexOf(a)===-1?a:null},array:function(a){return JSON.parse(a)},object:function(a){return JSON.parse(a)},auto:function(b){return a.serializeJSON.parseValue(b,null,{parseNumbers:!0,parseBooleans:!0,parseNulls:!0})}},useIntKeysAsArrayIndex:!1},setupOpts:function(b){var c,d,e,f,g,h;h=a.serializeJSON,null==b&&(b={}),e=h.defaultOptions||{},d=["checkboxUncheckedValue","parseNumbers","parseBooleans","parseNulls","parseAll","parseWithFunction","customTypes","defaultTypes","useIntKeysAsArrayIndex"];for(c in b)if(d.indexOf(c)===-1)throw new Error("serializeJSON ERROR: invalid option '"+c+"'. Please use one of "+d.join(", "));return f=function(a){return b[a]!==!1&&""!==b[a]&&(b[a]||e[a])},g=f("parseAll"),{checkboxUncheckedValue:f("checkboxUncheckedValue"),parseNumbers:g||f("parseNumbers"),parseBooleans:g||f("parseBooleans"),parseNulls:g||f("parseNulls"),parseWithFunction:f("parseWithFunction"),typeFunctions:a.extend({},f("defaultTypes"),f("customTypes")),useIntKeysAsArrayIndex:f("useIntKeysAsArrayIndex")}},parseValue:function(b,c,d){var e,f;return f=a.serializeJSON,e=d.typeFunctions&&d.typeFunctions[c],e?e(b):d.parseNumbers&&f.isNumeric(b)?Number(b):!d.parseBooleans||"true"!==b&&"false"!==b?d.parseNulls&&"null"==b?null:b:"true"===b},isObject:function(a){return a===Object(a)},isUndefined:function(a){return void 0===a},isValidArrayIndex:function(a){return/^[0-9]+$/.test(String(a))},isNumeric:function(a){return a-parseFloat(a)>=0},optionKeys:function(a){if(Object.keys)return Object.keys(a);var b,c=[];for(b in a)c.push(b);return c},splitInputNameIntoKeysArray:function(b,c){var d,e,f,g,h;return h=a.serializeJSON,g=h.extractTypeFromInputName(b,c),e=g[0],f=g[1],d=e.split("["),d=a.map(d,function(a){return a.replace(/\]/g,"")}),""===d[0]&&d.shift(),d.push(f),d},extractTypeFromInputName:function(b,c){var d,e,f;if(d=b.match(/(.*):([^:]+)$/)){if(f=a.serializeJSON,e=f.optionKeys(c?c.typeFunctions:f.defaultOptions.defaultTypes),e.push("skip"),e.indexOf(d[2])!==-1)return[d[1],d[2]];throw new Error("serializeJSON ERROR: Invalid type "+d[2]+" found in input name '"+b+"', please use one of "+e.join(", "))}return[b,"_"]},deepSet:function(b,c,d,e){var f,g,h,i,j,k;if(null==e&&(e={}),k=a.serializeJSON,k.isUndefined(b))throw new Error("ArgumentError: param 'o' expected to be an object or array, found undefined");if(!c||0===c.length)throw new Error("ArgumentError: param 'keys' expected to be an array with least one element");f=c[0],1===c.length?""===f?b.push(d):b[f]=d:(g=c[1],""===f&&(i=b.length-1,j=b[i],f=k.isObject(j)&&(k.isUndefined(j[g])||c.length>2)?i:i+1),""===g?!k.isUndefined(b[f])&&a.isArray(b[f])||(b[f]=[]):e.useIntKeysAsArrayIndex&&k.isValidArrayIndex(g)?!k.isUndefined(b[f])&&a.isArray(b[f])||(b[f]=[]):!k.isUndefined(b[f])&&k.isObject(b[f])||(b[f]={}),h=c.slice(1),k.deepSet(b[f],h,d,e))},readCheckboxUncheckedValues:function(b,c,d){var e,f,g,h,i;null==d&&(d={}),i=a.serializeJSON,e="input[type=checkbox][name]:not(:checked):not([disabled])",f=c.find(e).add(c.filter(e)),f.each(function(c,e){g=a(e),h=g.attr("data-unchecked-value"),h?b.push({name:e.name,value:h}):i.isUndefined(d.checkboxUncheckedValue)||b.push({name:e.name,value:d.checkboxUncheckedValue})})}}}(window.jQuery||window.Zepto||window.$); \ No newline at end of file diff --git a/assets/js/jquery-tiptip/jquery.tipTip.min.js b/assets/js/jquery-tiptip/jquery.tipTip.min.js index a438c2a927a..8fd09bf9600 100644 --- a/assets/js/jquery-tiptip/jquery.tipTip.min.js +++ b/assets/js/jquery-tiptip/jquery.tipTip.min.js @@ -1 +1 @@ -!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('
    '),f=a('
    '),g=a('
    ');a("body").append(e.html(f).prepend(g.html('
    ')))}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+cparseInt(a(window).width());v&&0>o||"_right"==s&&!w||"_left"==s&&co||"_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); \ No newline at end of file +!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('
    '),f=a('
    '),g=a('
    ');a("body").append(e.html(f).prepend(g.html('
    ')))}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+cparseInt(a(window).width());v&&o<0||"_right"==s&&!w||"_left"==s&&cparseInt(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); \ No newline at end of file diff --git a/assets/js/prettyPhoto/jquery.prettyPhoto.min.js b/assets/js/prettyPhoto/jquery.prettyPhoto.min.js index c309d0f4edb..7d1a0346aa7 100644 --- a/assets/js/prettyPhoto/jquery.prettyPhoto.min.js +++ b/assets/js/prettyPhoto/jquery.prettyPhoto.min.js @@ -1 +1 @@ -!function(a){function b(){var a=location.href;return hashtag=-1!==a.indexOf("#prettyPhoto")?decodeURI(a.substring(a.indexOf("#prettyPhoto")+1,a.length)):!1,hashtag&&(hashtag=hashtag.replace(/<|>/g,"")),hashtag}function c(){"undefined"!=typeof theRel&&(location.hash=theRel+"/"+rel_index+"/")}function d(){-1!==location.href.indexOf("#prettyPhoto")&&(location.hash="prettyPhoto")}function e(a,b){a=a.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var c="[\\?&]"+a+"=([^&#]*)",d=new RegExp(c),e=d.exec(b);return null==e?"":e[1]}a.prettyPhoto={version:"3.1.6"},a.fn.prettyPhoto=function(f){function g(){a(".pp_loaderIcon").hide(),projectedTop=scroll_pos.scrollTop+(A/2-r.containerHeight/2),projectedTop<0&&(projectedTop=0),$ppt.fadeTo(settings.animation_speed,1),$pp_pic_holder.find(".pp_content").animate({height:r.contentHeight,width:r.contentWidth},settings.animation_speed),$pp_pic_holder.animate({top:projectedTop,left:B/2-r.containerWidth/2<0?0:B/2-r.containerWidth/2,width:r.containerWidth},settings.animation_speed,function(){$pp_pic_holder.find(".pp_hoverContainer,#fullResImage").height(r.height).width(r.width),$pp_pic_holder.find(".pp_fade").fadeIn(settings.animation_speed),isSet&&"image"==l(pp_images[set_position])?$pp_pic_holder.find(".pp_hoverContainer").show():$pp_pic_holder.find(".pp_hoverContainer").hide(),settings.allow_expand&&(r.resized?a("a.pp_expand,a.pp_contract").show():a("a.pp_expand").hide()),!settings.autoplay_slideshow||x||s||a.prettyPhoto.startSlideshow(),settings.changepicturecallback(),s=!0}),p(),f.ajaxcallback()}function h(b){$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(){a(".pp_loaderIcon").show(),b()})}function i(b){b>1?a(".pp_nav").show():a(".pp_nav").hide()}function j(a,b){if(resized=!1,k(a,b),imageWidth=a,imageHeight=b,(w>B||v>A)&&doresize&&settings.allow_resize&&!z){for(resized=!0,fitting=!1;!fitting;)w>B?(imageWidth=B-200,imageHeight=b/a*imageWidth):v>A?(imageHeight=A-200,imageWidth=a/b*imageHeight):fitting=!0,v=imageHeight,w=imageWidth;(w>B||v>A)&&j(w,v),k(imageWidth,imageHeight)}return{width:Math.floor(imageWidth),height:Math.floor(imageHeight),containerHeight:Math.floor(v),containerWidth:Math.floor(w)+2*settings.horizontal_padding,contentHeight:Math.floor(t),contentWidth:Math.floor(u),resized:resized}}function k(b,c){b=parseFloat(b),c=parseFloat(c),$pp_details=$pp_pic_holder.find(".pp_details"),$pp_details.width(b),detailsHeight=parseFloat($pp_details.css("marginTop"))+parseFloat($pp_details.css("marginBottom")),$pp_details=$pp_details.clone().addClass(settings.theme).width(b).appendTo(a("body")).css({position:"absolute",top:-1e4}),detailsHeight+=$pp_details.height(),detailsHeight=detailsHeight<=34?36:detailsHeight,$pp_details.remove(),$pp_title=$pp_pic_holder.find(".ppt"),$pp_title.width(b),titleHeight=parseFloat($pp_title.css("marginTop"))+parseFloat($pp_title.css("marginBottom")),$pp_title=$pp_title.clone().appendTo(a("body")).css({position:"absolute",top:-1e4}),titleHeight+=$pp_title.height(),$pp_title.remove(),t=c+detailsHeight,u=b,v=t+titleHeight+$pp_pic_holder.find(".pp_top").height()+$pp_pic_holder.find(".pp_bottom").height(),w=b}function l(a){return a.match(/youtube\.com\/watch/i)||a.match(/youtu\.be/i)?"youtube":a.match(/vimeo\.com/i)?"vimeo":a.match(/\b.mov\b/i)?"quicktime":a.match(/\b.swf\b/i)?"flash":a.match(/\biframe=true\b/i)?"iframe":a.match(/\bajax=true\b/i)?"ajax":a.match(/\bcustom=true\b/i)?"custom":"#"==a.substr(0,1)?"inline":"image"}function m(){if(doresize&&"undefined"!=typeof $pp_pic_holder){if(scroll_pos=n(),contentHeight=$pp_pic_holder.height(),contentwidth=$pp_pic_holder.width(),projectedTop=A/2+scroll_pos.scrollTop-contentHeight/2,projectedTop<0&&(projectedTop=0),contentHeight>A)return;$pp_pic_holder.css({top:projectedTop,left:B/2+scroll_pos.scrollLeft-contentwidth/2})}}function n(){return self.pageYOffset?{scrollTop:self.pageYOffset,scrollLeft:self.pageXOffset}:document.documentElement&&document.documentElement.scrollTop?{scrollTop:document.documentElement.scrollTop,scrollLeft:document.documentElement.scrollLeft}:document.body?{scrollTop:document.body.scrollTop,scrollLeft:document.body.scrollLeft}:void 0}function o(){A=a(window).height(),B=a(window).width(),"undefined"!=typeof $pp_overlay&&$pp_overlay.height(a(document).height()).width(B)}function p(){isSet&&settings.overlay_gallery&&"image"==l(pp_images[set_position])?(itemWidth=57,navWidth="facebook"==settings.theme||"pp_default"==settings.theme?50:30,itemsPerPage=Math.floor((r.containerWidth-100-navWidth)/itemWidth),itemsPerPage=itemsPerPage";toInject=settings.gallery_markup.replace(/{gallery}/g,toInject),$pp_pic_holder.find("#pp_full_res").after(toInject),$pp_gallery=a(".pp_pic_holder .pp_gallery"),$pp_gallery_li=$pp_gallery.find("li"),$pp_gallery.find(".pp_arrow_next").click(function(){return a.prettyPhoto.changeGalleryPage("next"),a.prettyPhoto.stopSlideshow(),!1}),$pp_gallery.find(".pp_arrow_previous").click(function(){return a.prettyPhoto.changeGalleryPage("previous"),a.prettyPhoto.stopSlideshow(),!1}),$pp_pic_holder.find(".pp_content").hover(function(){$pp_pic_holder.find(".pp_gallery:not(.disabled)").fadeIn()},function(){$pp_pic_holder.find(".pp_gallery:not(.disabled)").fadeOut()}),itemWidth=57,$pp_gallery_li.each(function(b){a(this).find("a").click(function(){return a.prettyPhoto.changePage(b),a.prettyPhoto.stopSlideshow(),!1})})}settings.slideshow&&($pp_pic_holder.find(".pp_nav").prepend('Play'),$pp_pic_holder.find(".pp_nav .pp_play").click(function(){return a.prettyPhoto.startSlideshow(),!1})),$pp_pic_holder.attr("class","pp_pic_holder "+settings.theme),$pp_overlay.css({opacity:0,height:a(document).height(),width:a(window).width()}).bind("click",function(){settings.modal||a.prettyPhoto.close()}),a("a.pp_close").bind("click",function(){return a.prettyPhoto.close(),!1}),settings.allow_expand&&a("a.pp_expand").bind("click",function(b){return a(this).hasClass("pp_expand")?(a(this).removeClass("pp_expand").addClass("pp_contract"),doresize=!1):(a(this).removeClass("pp_contract").addClass("pp_expand"),doresize=!0),h(function(){a.prettyPhoto.open()}),!1}),$pp_pic_holder.find(".pp_previous, .pp_nav .pp_arrow_previous").bind("click",function(){return a.prettyPhoto.changePage("previous"),a.prettyPhoto.stopSlideshow(),!1}),$pp_pic_holder.find(".pp_next, .pp_nav .pp_arrow_next").bind("click",function(){return a.prettyPhoto.changePage("next"),a.prettyPhoto.stopSlideshow(),!1}),m()}f=jQuery.extend({hook:"rel",animation_speed:"fast",ajaxcallback:function(){},slideshow:5e3,autoplay_slideshow:!1,opacity:.8,show_title:!0,allow_resize:!0,allow_expand:!0,default_width:500,default_height:344,counter_separator_label:"/",theme:"pp_default",horizontal_padding:20,hideflash:!1,wmode:"opaque",autoplay:!0,modal:!1,deeplinking:!0,overlay_gallery:!0,overlay_gallery_max:30,keyboard_shortcuts:!0,changepicturecallback:function(){},callback:function(){},ie6_fallback:!0,markup:'
     
    ',gallery_markup:'',image_markup:'',flash_markup:'',quicktime_markup:'',iframe_markup:'',inline_markup:'
    {content}
    ',custom_markup:"",social_tools:''},f);var r,s,t,u,v,w,x,y=this,z=!1,A=a(window).height(),B=a(window).width();return doresize=!0,scroll_pos=n(),a(window).unbind("resize.prettyphoto").bind("resize.prettyphoto",function(){m(),o()}),f.keyboard_shortcuts&&a(document).unbind("keydown.prettyphoto").bind("keydown.prettyphoto",function(b){if("undefined"!=typeof $pp_pic_holder&&$pp_pic_holder.is(":visible"))switch(b.keyCode){case 37:a.prettyPhoto.changePage("previous"),b.preventDefault();break;case 39:a.prettyPhoto.changePage("next"),b.preventDefault();break;case 27:settings.modal||a.prettyPhoto.close(),b.preventDefault()}}),a.prettyPhoto.initialize=function(){return settings=f,"pp_default"==settings.theme&&(settings.horizontal_padding=16),theRel=a(this).attr(settings.hook),galleryRegExp=/\[(?:.*)\]/,isSet=!!galleryRegExp.exec(theRel),pp_images=isSet?jQuery.map(y,function(b,c){return-1!=a(b).attr(settings.hook).indexOf(theRel)?a(b).attr("href"):void 0}):a.makeArray(a(this).attr("href")),pp_titles=isSet?jQuery.map(y,function(b,c){return-1!=a(b).attr(settings.hook).indexOf(theRel)?a(b).find("img").attr("alt")?a(b).find("img").attr("alt"):"":void 0}):a.makeArray(a(this).find("img").attr("alt")),pp_descriptions=isSet?jQuery.map(y,function(b,c){return-1!=a(b).attr(settings.hook).indexOf(theRel)?a(b).attr("title")?a(b).attr("title"):"":void 0}):a.makeArray(a(this).attr("title")),pp_images.length>settings.overlay_gallery_max&&(settings.overlay_gallery=!1),set_position=jQuery.inArray(a(this).attr("href"),pp_images),rel_index=isSet?set_position:a("a["+settings.hook+"^='"+theRel+"']").index(a(this)),q(this),settings.allow_resize&&a(window).bind("scroll.prettyphoto",function(){m()}),a.prettyPhoto.open(),!1},a.prettyPhoto.open=function(b){return"undefined"==typeof settings&&(settings=f,pp_images=a.makeArray(arguments[0]),pp_titles=arguments[1]?a.makeArray(arguments[1]):a.makeArray(""),pp_descriptions=arguments[2]?a.makeArray(arguments[2]):a.makeArray(""),isSet=pp_images.length>1,set_position=arguments[3]?arguments[3]:0,q(b.target)),settings.hideflash&&a("object,embed,iframe[src*=youtube],iframe[src*=vimeo]").css("visibility","hidden"),i(a(pp_images).length),a(".pp_loaderIcon").show(),settings.deeplinking&&c(),settings.social_tools&&(facebook_like_link=settings.social_tools.replace("{location_href}",encodeURIComponent(location.href)),$pp_pic_holder.find(".pp_social").html(facebook_like_link)),$ppt.is(":hidden")&&$ppt.css("opacity",0).show(),$pp_overlay.show().fadeTo(settings.animation_speed,settings.opacity),$pp_pic_holder.find(".currentTextHolder").text(set_position+1+settings.counter_separator_label+a(pp_images).length),"undefined"!=typeof pp_descriptions[set_position]&&""!=pp_descriptions[set_position]?$pp_pic_holder.find(".pp_description").show().html(unescape(pp_descriptions[set_position])):$pp_pic_holder.find(".pp_description").hide(),movie_width=parseFloat(e("width",pp_images[set_position]))?e("width",pp_images[set_position]):settings.default_width.toString(),movie_height=parseFloat(e("height",pp_images[set_position]))?e("height",pp_images[set_position]):settings.default_height.toString(),z=!1,-1!=movie_height.indexOf("%")&&(movie_height=parseFloat(a(window).height()*parseFloat(movie_height)/100-150),z=!0),-1!=movie_width.indexOf("%")&&(movie_width=parseFloat(a(window).width()*parseFloat(movie_width)/100-150),z=!0),$pp_pic_holder.fadeIn(function(){switch(settings.show_title&&""!=pp_titles[set_position]&&"undefined"!=typeof pp_titles[set_position]?$ppt.html(unescape(pp_titles[set_position])):$ppt.html(" "),imgPreloader="",skipInjection=!1,l(pp_images[set_position])){case"image":imgPreloader=new Image,nextImage=new Image,isSet&&set_position0&&(movie_id=movie_id.substr(0,movie_id.indexOf("?"))),movie_id.indexOf("&")>0&&(movie_id=movie_id.substr(0,movie_id.indexOf("&")))),movie="//www.youtube.com/embed/"+movie_id,e("rel",pp_images[set_position])?movie+="?rel="+e("rel",pp_images[set_position]):movie+="?rel=1",settings.autoplay&&(movie+="&autoplay=1"),toInject=settings.iframe_markup.replace(/{width}/g,r.width).replace(/{height}/g,r.height).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,movie);break;case"vimeo":r=j(movie_width,movie_height),movie_id=pp_images[set_position];var b=/http(s?):\/\/(www\.)?vimeo.com\/(\d+)/,c=movie_id.match(b);movie="//player.vimeo.com/video/"+c[3]+"?title=0&byline=0&portrait=0",settings.autoplay&&(movie+="&autoplay=1;"),vimeo_width=r.width+"/embed/?moog_width="+r.width,toInject=settings.iframe_markup.replace(/{width}/g,vimeo_width).replace(/{height}/g,r.height).replace(/{path}/g,movie);break;case"quicktime":r=j(movie_width,movie_height),r.height+=15,r.contentHeight+=15,r.containerHeight+=15,toInject=settings.quicktime_markup.replace(/{width}/g,r.width).replace(/{height}/g,r.height).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,pp_images[set_position]).replace(/{autoplay}/g,settings.autoplay);break;case"flash":r=j(movie_width,movie_height),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,r.width).replace(/{height}/g,r.height).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,filename+"?"+flash_vars);break;case"iframe":r=j(movie_width,movie_height),frame_url=pp_images[set_position],frame_url=frame_url.substr(0,frame_url.indexOf("iframe")-1),toInject=settings.iframe_markup.replace(/{width}/g,r.width).replace(/{height}/g,r.height).replace(/{path}/g,frame_url);break;case"ajax":doresize=!1,r=j(movie_width,movie_height),doresize=!0,skipInjection=!0,a.get(pp_images[set_position],function(a){toInject=settings.inline_markup.replace(/{content}/g,a),$pp_pic_holder.find("#pp_full_res")[0].innerHTML=toInject,g()});break;case"custom":r=j(movie_width,movie_height),toInject=settings.custom_markup;break;case"inline":myClone=a(pp_images[set_position]).clone().append('
    ').css({width:settings.default_width}).wrapInner('
    ').appendTo(a("body")).show(),doresize=!1,r=j(a(myClone).width(),a(myClone).height()),doresize=!0,a(myClone).remove(),toInject=settings.inline_markup.replace(/{content}/g,a(pp_images[set_position]).html())}imgPreloader||skipInjection||($pp_pic_holder.find("#pp_full_res")[0].innerHTML=toInject,g())}),!1},a.prettyPhoto.changePage=function(b){currentGalleryPage=0,"previous"==b?(set_position--,set_position<0&&(set_position=a(pp_images).length-1)):"next"==b?(set_position++,set_position>a(pp_images).length-1&&(set_position=0)):set_position=b,rel_index=set_position,doresize||(doresize=!0),settings.allow_expand&&a(".pp_contract").removeClass("pp_contract").addClass("pp_expand"),h(function(){a.prettyPhoto.open()})},a.prettyPhoto.changeGalleryPage=function(a){"next"==a?(currentGalleryPage++,currentGalleryPage>totalPage&&(currentGalleryPage=0)):"previous"==a?(currentGalleryPage--,currentGalleryPage<0&&(currentGalleryPage=totalPage)):currentGalleryPage=a,slide_speed="next"==a||"previous"==a?settings.animation_speed:0,slide_to=currentGalleryPage*(itemsPerPage*itemWidth),$pp_gallery.find("ul").animate({left:-slide_to},slide_speed)},a.prettyPhoto.startSlideshow=function(){"undefined"==typeof x?($pp_pic_holder.find(".pp_play").unbind("click").removeClass("pp_play").addClass("pp_pause").click(function(){return a.prettyPhoto.stopSlideshow(),!1}),x=setInterval(a.prettyPhoto.startSlideshow,settings.slideshow)):a.prettyPhoto.changePage("next")},a.prettyPhoto.stopSlideshow=function(){$pp_pic_holder.find(".pp_pause").unbind("click").removeClass("pp_pause").addClass("pp_play").click(function(){return a.prettyPhoto.startSlideshow(),!1}),clearInterval(x),x=void 0},a.prettyPhoto.close=function(){$pp_overlay.is(":animated")||(a.prettyPhoto.stopSlideshow(),$pp_pic_holder.stop().find("object,embed").css("visibility","hidden"),a("div.pp_pic_holder,div.ppt,.pp_fade").fadeOut(settings.animation_speed,function(){a(this).remove()}),$pp_overlay.fadeOut(settings.animation_speed,function(){settings.hideflash&&a("object,embed,iframe[src*=youtube],iframe[src*=vimeo]").css("visibility","visible"),a(this).remove(),a(window).unbind("scroll.prettyphoto"),d(),settings.callback(),doresize=!0,s=!1,delete settings}))},!pp_alreadyInitialized&&b()&&(pp_alreadyInitialized=!0,hashIndex=b(),hashRel=hashIndex,hashIndex=hashIndex.substring(hashIndex.indexOf("/")+1,hashIndex.length-1),hashRel=hashRel.substring(0,hashRel.indexOf("/")),setTimeout(function(){a("a["+f.hook+"^='"+hashRel+"']:eq("+hashIndex+")").trigger("click")},50)),this.unbind("click.prettyphoto").bind("click.prettyphoto",a.prettyPhoto.initialize)}}(jQuery);var pp_alreadyInitialized=!1; \ No newline at end of file +!function(a){function b(){var a=location.href;return hashtag=a.indexOf("#prettyPhoto")!==-1&&decodeURI(a.substring(a.indexOf("#prettyPhoto")+1,a.length)),hashtag&&(hashtag=hashtag.replace(/<|>/g,"")),hashtag}function c(){"undefined"!=typeof theRel&&(location.hash=theRel+"/"+rel_index+"/")}function d(){location.href.indexOf("#prettyPhoto")!==-1&&(location.hash="prettyPhoto")}function e(a,b){a=a.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var c="[\\?&]"+a+"=([^&#]*)",d=new RegExp(c),e=d.exec(b);return null==e?"":e[1]}a.prettyPhoto={version:"3.1.6"},a.fn.prettyPhoto=function(f){function g(){a(".pp_loaderIcon").hide(),projectedTop=scroll_pos.scrollTop+(A/2-r.containerHeight/2),projectedTop<0&&(projectedTop=0),$ppt.fadeTo(settings.animation_speed,1),$pp_pic_holder.find(".pp_content").animate({height:r.contentHeight,width:r.contentWidth},settings.animation_speed),$pp_pic_holder.animate({top:projectedTop,left:B/2-r.containerWidth/2<0?0:B/2-r.containerWidth/2,width:r.containerWidth},settings.animation_speed,function(){$pp_pic_holder.find(".pp_hoverContainer,#fullResImage").height(r.height).width(r.width),$pp_pic_holder.find(".pp_fade").fadeIn(settings.animation_speed),isSet&&"image"==l(pp_images[set_position])?$pp_pic_holder.find(".pp_hoverContainer").show():$pp_pic_holder.find(".pp_hoverContainer").hide(),settings.allow_expand&&(r.resized?a("a.pp_expand,a.pp_contract").show():a("a.pp_expand").hide()),!settings.autoplay_slideshow||x||s||a.prettyPhoto.startSlideshow(),settings.changepicturecallback(),s=!0}),p(),f.ajaxcallback()}function h(b){$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(){a(".pp_loaderIcon").show(),b()})}function i(b){b>1?a(".pp_nav").show():a(".pp_nav").hide()}function j(a,b){if(resized=!1,k(a,b),imageWidth=a,imageHeight=b,(w>B||v>A)&&doresize&&settings.allow_resize&&!z){for(resized=!0,fitting=!1;!fitting;)w>B?(imageWidth=B-200,imageHeight=b/a*imageWidth):v>A?(imageHeight=A-200,imageWidth=a/b*imageHeight):fitting=!0,v=imageHeight,w=imageWidth;(w>B||v>A)&&j(w,v),k(imageWidth,imageHeight)}return{width:Math.floor(imageWidth),height:Math.floor(imageHeight),containerHeight:Math.floor(v),containerWidth:Math.floor(w)+2*settings.horizontal_padding,contentHeight:Math.floor(t),contentWidth:Math.floor(u),resized:resized}}function k(b,c){b=parseFloat(b),c=parseFloat(c),$pp_details=$pp_pic_holder.find(".pp_details"),$pp_details.width(b),detailsHeight=parseFloat($pp_details.css("marginTop"))+parseFloat($pp_details.css("marginBottom")),$pp_details=$pp_details.clone().addClass(settings.theme).width(b).appendTo(a("body")).css({position:"absolute",top:-1e4}),detailsHeight+=$pp_details.height(),detailsHeight=detailsHeight<=34?36:detailsHeight,$pp_details.remove(),$pp_title=$pp_pic_holder.find(".ppt"),$pp_title.width(b),titleHeight=parseFloat($pp_title.css("marginTop"))+parseFloat($pp_title.css("marginBottom")),$pp_title=$pp_title.clone().appendTo(a("body")).css({position:"absolute",top:-1e4}),titleHeight+=$pp_title.height(),$pp_title.remove(),t=c+detailsHeight,u=b,v=t+titleHeight+$pp_pic_holder.find(".pp_top").height()+$pp_pic_holder.find(".pp_bottom").height(),w=b}function l(a){return a.match(/youtube\.com\/watch/i)||a.match(/youtu\.be/i)?"youtube":a.match(/vimeo\.com/i)?"vimeo":a.match(/\b.mov\b/i)?"quicktime":a.match(/\b.swf\b/i)?"flash":a.match(/\biframe=true\b/i)?"iframe":a.match(/\bajax=true\b/i)?"ajax":a.match(/\bcustom=true\b/i)?"custom":"#"==a.substr(0,1)?"inline":"image"}function m(){if(doresize&&"undefined"!=typeof $pp_pic_holder){if(scroll_pos=n(),contentHeight=$pp_pic_holder.height(),contentwidth=$pp_pic_holder.width(),projectedTop=A/2+scroll_pos.scrollTop-contentHeight/2,projectedTop<0&&(projectedTop=0),contentHeight>A)return;$pp_pic_holder.css({top:projectedTop,left:B/2+scroll_pos.scrollLeft-contentwidth/2})}}function n(){return self.pageYOffset?{scrollTop:self.pageYOffset,scrollLeft:self.pageXOffset}:document.documentElement&&document.documentElement.scrollTop?{scrollTop:document.documentElement.scrollTop,scrollLeft:document.documentElement.scrollLeft}:document.body?{scrollTop:document.body.scrollTop,scrollLeft:document.body.scrollLeft}:void 0}function o(){A=a(window).height(),B=a(window).width(),"undefined"!=typeof $pp_overlay&&$pp_overlay.height(a(document).height()).width(B)}function p(){isSet&&settings.overlay_gallery&&"image"==l(pp_images[set_position])?(itemWidth=57,navWidth="facebook"==settings.theme||"pp_default"==settings.theme?50:30,itemsPerPage=Math.floor((r.containerWidth-100-navWidth)/itemWidth),itemsPerPage=itemsPerPage";toInject=settings.gallery_markup.replace(/{gallery}/g,toInject),$pp_pic_holder.find("#pp_full_res").after(toInject),$pp_gallery=a(".pp_pic_holder .pp_gallery"),$pp_gallery_li=$pp_gallery.find("li"),$pp_gallery.find(".pp_arrow_next").click(function(){return a.prettyPhoto.changeGalleryPage("next"),a.prettyPhoto.stopSlideshow(),!1}),$pp_gallery.find(".pp_arrow_previous").click(function(){return a.prettyPhoto.changeGalleryPage("previous"),a.prettyPhoto.stopSlideshow(),!1}),$pp_pic_holder.find(".pp_content").hover(function(){$pp_pic_holder.find(".pp_gallery:not(.disabled)").fadeIn()},function(){$pp_pic_holder.find(".pp_gallery:not(.disabled)").fadeOut()}),itemWidth=57,$pp_gallery_li.each(function(b){a(this).find("a").click(function(){return a.prettyPhoto.changePage(b),a.prettyPhoto.stopSlideshow(),!1})})}settings.slideshow&&($pp_pic_holder.find(".pp_nav").prepend('Play'),$pp_pic_holder.find(".pp_nav .pp_play").click(function(){return a.prettyPhoto.startSlideshow(),!1})),$pp_pic_holder.attr("class","pp_pic_holder "+settings.theme),$pp_overlay.css({opacity:0,height:a(document).height(),width:a(window).width()}).bind("click",function(){settings.modal||a.prettyPhoto.close()}),a("a.pp_close").bind("click",function(){return a.prettyPhoto.close(),!1}),settings.allow_expand&&a("a.pp_expand").bind("click",function(b){return a(this).hasClass("pp_expand")?(a(this).removeClass("pp_expand").addClass("pp_contract"),doresize=!1):(a(this).removeClass("pp_contract").addClass("pp_expand"),doresize=!0),h(function(){a.prettyPhoto.open()}),!1}),$pp_pic_holder.find(".pp_previous, .pp_nav .pp_arrow_previous").bind("click",function(){return a.prettyPhoto.changePage("previous"),a.prettyPhoto.stopSlideshow(),!1}),$pp_pic_holder.find(".pp_next, .pp_nav .pp_arrow_next").bind("click",function(){return a.prettyPhoto.changePage("next"),a.prettyPhoto.stopSlideshow(),!1}),m()}f=jQuery.extend({hook:"rel",animation_speed:"fast",ajaxcallback:function(){},slideshow:5e3,autoplay_slideshow:!1,opacity:.8,show_title:!0,allow_resize:!0,allow_expand:!0,default_width:500,default_height:344,counter_separator_label:"/",theme:"pp_default",horizontal_padding:20,hideflash:!1,wmode:"opaque",autoplay:!0,modal:!1,deeplinking:!0,overlay_gallery:!0,overlay_gallery_max:30,keyboard_shortcuts:!0,changepicturecallback:function(){},callback:function(){},ie6_fallback:!0,markup:'
    \t\t\t\t\t\t
     
    \t\t\t\t\t\t
    \t\t\t\t\t\t\t
    \t\t\t\t\t\t\t
    \t\t\t\t\t\t\t
    \t\t\t\t\t\t
    \t\t\t\t\t\t
    \t\t\t\t\t\t\t
    \t\t\t\t\t\t\t
    \t\t\t\t\t\t\t\t
    \t\t\t\t\t\t\t\t\t
    \t\t\t\t\t\t\t\t\t
    \t\t\t\t\t\t\t\t\t\tExpand \t\t\t\t\t\t\t\t\t\t
    \t\t\t\t\t\t\t\t\t\t\tnext \t\t\t\t\t\t\t\t\t\t\tprevious \t\t\t\t\t\t\t\t\t\t
    \t\t\t\t\t\t\t\t\t\t
    \t\t\t\t\t\t\t\t\t\t
    \t\t\t\t\t\t\t\t\t\t\t
    \t\t\t\t\t\t\t\t\t\t\t\tPrevious \t\t\t\t\t\t\t\t\t\t\t\t

    0/0

    \t\t\t\t\t\t\t\t\t\t\t\tNext \t\t\t\t\t\t\t\t\t\t\t
    \t\t\t\t\t\t\t\t\t\t\t

    \t\t\t\t\t\t\t\t\t\t\t
    {pp_social}
    \t\t\t\t\t\t\t\t\t\t\tClose \t\t\t\t\t\t\t\t\t\t
    \t\t\t\t\t\t\t\t\t
    \t\t\t\t\t\t\t\t
    \t\t\t\t\t\t\t
    \t\t\t\t\t\t\t
    \t\t\t\t\t\t
    \t\t\t\t\t\t
    \t\t\t\t\t\t\t
    \t\t\t\t\t\t\t
    \t\t\t\t\t\t\t
    \t\t\t\t\t\t
    \t\t\t\t\t
    \t\t\t\t\t
    ',gallery_markup:'',image_markup:'',flash_markup:'',quicktime_markup:'',iframe_markup:'',inline_markup:'
    {content}
    ',custom_markup:"",social_tools:''},f);var r,s,t,u,v,w,x,y=this,z=!1,A=a(window).height(),B=a(window).width();return doresize=!0,scroll_pos=n(),a(window).unbind("resize.prettyphoto").bind("resize.prettyphoto",function(){m(),o()}),f.keyboard_shortcuts&&a(document).unbind("keydown.prettyphoto").bind("keydown.prettyphoto",function(b){if("undefined"!=typeof $pp_pic_holder&&$pp_pic_holder.is(":visible"))switch(b.keyCode){case 37:a.prettyPhoto.changePage("previous"),b.preventDefault();break;case 39:a.prettyPhoto.changePage("next"),b.preventDefault();break;case 27:settings.modal||a.prettyPhoto.close(),b.preventDefault()}}),a.prettyPhoto.initialize=function(){return settings=f,"pp_default"==settings.theme&&(settings.horizontal_padding=16),theRel=a(this).attr(settings.hook),galleryRegExp=/\[(?:.*)\]/,isSet=!!galleryRegExp.exec(theRel),pp_images=isSet?jQuery.map(y,function(b,c){if(a(b).attr(settings.hook).indexOf(theRel)!=-1)return a(b).attr("href")}):a.makeArray(a(this).attr("href")),pp_titles=isSet?jQuery.map(y,function(b,c){if(a(b).attr(settings.hook).indexOf(theRel)!=-1)return a(b).find("img").attr("alt")?a(b).find("img").attr("alt"):""}):a.makeArray(a(this).find("img").attr("alt")),pp_descriptions=isSet?jQuery.map(y,function(b,c){if(a(b).attr(settings.hook).indexOf(theRel)!=-1)return a(b).attr("title")?a(b).attr("title"):""}):a.makeArray(a(this).attr("title")),pp_images.length>settings.overlay_gallery_max&&(settings.overlay_gallery=!1),set_position=jQuery.inArray(a(this).attr("href"),pp_images),rel_index=isSet?set_position:a("a["+settings.hook+"^='"+theRel+"']").index(a(this)),q(this),settings.allow_resize&&a(window).bind("scroll.prettyphoto",function(){m()}),a.prettyPhoto.open(),!1},a.prettyPhoto.open=function(b){return"undefined"==typeof settings&&(settings=f,pp_images=a.makeArray(arguments[0]),pp_titles=arguments[1]?a.makeArray(arguments[1]):a.makeArray(""),pp_descriptions=arguments[2]?a.makeArray(arguments[2]):a.makeArray(""),isSet=pp_images.length>1,set_position=arguments[3]?arguments[3]:0,q(b.target)),settings.hideflash&&a("object,embed,iframe[src*=youtube],iframe[src*=vimeo]").css("visibility","hidden"),i(a(pp_images).length),a(".pp_loaderIcon").show(),settings.deeplinking&&c(),settings.social_tools&&(facebook_like_link=settings.social_tools.replace("{location_href}",encodeURIComponent(location.href)),$pp_pic_holder.find(".pp_social").html(facebook_like_link)),$ppt.is(":hidden")&&$ppt.css("opacity",0).show(),$pp_overlay.show().fadeTo(settings.animation_speed,settings.opacity),$pp_pic_holder.find(".currentTextHolder").text(set_position+1+settings.counter_separator_label+a(pp_images).length),"undefined"!=typeof pp_descriptions[set_position]&&""!=pp_descriptions[set_position]?$pp_pic_holder.find(".pp_description").show().html(unescape(pp_descriptions[set_position])):$pp_pic_holder.find(".pp_description").hide(),movie_width=parseFloat(e("width",pp_images[set_position]))?e("width",pp_images[set_position]):settings.default_width.toString(),movie_height=parseFloat(e("height",pp_images[set_position]))?e("height",pp_images[set_position]):settings.default_height.toString(),z=!1,movie_height.indexOf("%")!=-1&&(movie_height=parseFloat(a(window).height()*parseFloat(movie_height)/100-150),z=!0),movie_width.indexOf("%")!=-1&&(movie_width=parseFloat(a(window).width()*parseFloat(movie_width)/100-150),z=!0),$pp_pic_holder.fadeIn(function(){switch(settings.show_title&&""!=pp_titles[set_position]&&"undefined"!=typeof pp_titles[set_position]?$ppt.html(unescape(pp_titles[set_position])):$ppt.html(" "),imgPreloader="",skipInjection=!1,l(pp_images[set_position])){case"image":imgPreloader=new Image,nextImage=new Image,isSet&&set_position0&&(movie_id=movie_id.substr(0,movie_id.indexOf("?"))),movie_id.indexOf("&")>0&&(movie_id=movie_id.substr(0,movie_id.indexOf("&")))),movie="//www.youtube.com/embed/"+movie_id,e("rel",pp_images[set_position])?movie+="?rel="+e("rel",pp_images[set_position]):movie+="?rel=1",settings.autoplay&&(movie+="&autoplay=1"),toInject=settings.iframe_markup.replace(/{width}/g,r.width).replace(/{height}/g,r.height).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,movie);break;case"vimeo":r=j(movie_width,movie_height),movie_id=pp_images[set_position];var b=/http(s?):\/\/(www\.)?vimeo.com\/(\d+)/,c=movie_id.match(b);movie="//player.vimeo.com/video/"+c[3]+"?title=0&byline=0&portrait=0",settings.autoplay&&(movie+="&autoplay=1;"),vimeo_width=r.width+"/embed/?moog_width="+r.width,toInject=settings.iframe_markup.replace(/{width}/g,vimeo_width).replace(/{height}/g,r.height).replace(/{path}/g,movie);break;case"quicktime":r=j(movie_width,movie_height),r.height+=15,r.contentHeight+=15,r.containerHeight+=15,toInject=settings.quicktime_markup.replace(/{width}/g,r.width).replace(/{height}/g,r.height).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,pp_images[set_position]).replace(/{autoplay}/g,settings.autoplay);break;case"flash":r=j(movie_width,movie_height),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,r.width).replace(/{height}/g,r.height).replace(/{wmode}/g,settings.wmode).replace(/{path}/g,filename+"?"+flash_vars);break;case"iframe":r=j(movie_width,movie_height),frame_url=pp_images[set_position],frame_url=frame_url.substr(0,frame_url.indexOf("iframe")-1),toInject=settings.iframe_markup.replace(/{width}/g,r.width).replace(/{height}/g,r.height).replace(/{path}/g,frame_url);break;case"ajax":doresize=!1,r=j(movie_width,movie_height),doresize=!0,skipInjection=!0,a.get(pp_images[set_position],function(a){toInject=settings.inline_markup.replace(/{content}/g,a),$pp_pic_holder.find("#pp_full_res")[0].innerHTML=toInject,g()});break;case"custom":r=j(movie_width,movie_height),toInject=settings.custom_markup;break;case"inline":myClone=a(pp_images[set_position]).clone().append('
    ').css({width:settings.default_width}).wrapInner('
    ').appendTo(a("body")).show(),doresize=!1,r=j(a(myClone).width(),a(myClone).height()),doresize=!0,a(myClone).remove(),toInject=settings.inline_markup.replace(/{content}/g,a(pp_images[set_position]).html())}imgPreloader||skipInjection||($pp_pic_holder.find("#pp_full_res")[0].innerHTML=toInject,g())}),!1},a.prettyPhoto.changePage=function(b){currentGalleryPage=0,"previous"==b?(set_position--,set_position<0&&(set_position=a(pp_images).length-1)):"next"==b?(set_position++,set_position>a(pp_images).length-1&&(set_position=0)):set_position=b,rel_index=set_position,doresize||(doresize=!0),settings.allow_expand&&a(".pp_contract").removeClass("pp_contract").addClass("pp_expand"),h(function(){a.prettyPhoto.open()})},a.prettyPhoto.changeGalleryPage=function(a){"next"==a?(currentGalleryPage++,currentGalleryPage>totalPage&&(currentGalleryPage=0)):"previous"==a?(currentGalleryPage--,currentGalleryPage<0&&(currentGalleryPage=totalPage)):currentGalleryPage=a,slide_speed="next"==a||"previous"==a?settings.animation_speed:0,slide_to=currentGalleryPage*(itemsPerPage*itemWidth),$pp_gallery.find("ul").animate({left:-slide_to},slide_speed)},a.prettyPhoto.startSlideshow=function(){"undefined"==typeof x?($pp_pic_holder.find(".pp_play").unbind("click").removeClass("pp_play").addClass("pp_pause").click(function(){return a.prettyPhoto.stopSlideshow(),!1}),x=setInterval(a.prettyPhoto.startSlideshow,settings.slideshow)):a.prettyPhoto.changePage("next")},a.prettyPhoto.stopSlideshow=function(){$pp_pic_holder.find(".pp_pause").unbind("click").removeClass("pp_pause").addClass("pp_play").click(function(){return a.prettyPhoto.startSlideshow(),!1}),clearInterval(x),x=void 0},a.prettyPhoto.close=function(){$pp_overlay.is(":animated")||(a.prettyPhoto.stopSlideshow(),$pp_pic_holder.stop().find("object,embed").css("visibility","hidden"),a("div.pp_pic_holder,div.ppt,.pp_fade").fadeOut(settings.animation_speed,function(){a(this).remove()}),$pp_overlay.fadeOut(settings.animation_speed,function(){settings.hideflash&&a("object,embed,iframe[src*=youtube],iframe[src*=vimeo]").css("visibility","visible"),a(this).remove(),a(window).unbind("scroll.prettyphoto"),d(),settings.callback(),doresize=!0,s=!1,delete settings}))},!pp_alreadyInitialized&&b()&&(pp_alreadyInitialized=!0,hashIndex=b(),hashRel=hashIndex,hashIndex=hashIndex.substring(hashIndex.indexOf("/")+1,hashIndex.length-1),hashRel=hashRel.substring(0,hashRel.indexOf("/")),setTimeout(function(){a("a["+f.hook+"^='"+hashRel+"']:eq("+hashIndex+")").trigger("click")},50)),this.unbind("click.prettyphoto").bind("click.prettyphoto",a.prettyPhoto.initialize)}}(jQuery);var pp_alreadyInitialized=!1; \ No newline at end of file diff --git a/assets/js/round/round.min.js b/assets/js/round/round.min.js index 5ba3659d429..e73d9974be4 100644 --- a/assets/js/round/round.min.js +++ b/assets/js/round/round.min.js @@ -1 +1 @@ -function round(a,b,c){var d,e,f,g;if(b|=0,d=Math.pow(10,b),a*=d,g=a>0|-(0>a),f=a%1===.5*g,e=Math.floor(a),f)switch(c){case"2":case"PHP_ROUND_HALF_DOWN":a=e+(0>g);break;case"3":case"PHP_ROUND_HALF_EVEN":a=e+e%2*g;break;case"4":case"PHP_ROUND_HALF_ODD":a=e+!(e%2);break;default:a=e+(g>0)}return(f?a:Math.round(a))/d} \ No newline at end of file +function round(a,b,c){var d,e,f,g;if(b|=0,d=Math.pow(10,b),a*=d,g=a>0|-(a<0),f=a%1===.5*g,e=Math.floor(a),f)switch(c){case"2":case"PHP_ROUND_HALF_DOWN":a=e+(g<0);break;case"3":case"PHP_ROUND_HALF_EVEN":a=e+e%2*g;break;case"4":case"PHP_ROUND_HALF_ODD":a=e+!(e%2);break;default:a=e+(g>0)}return(f?a:Math.round(a))/d} \ No newline at end of file diff --git a/assets/js/select2/select2.min.js b/assets/js/select2/select2.min.js index 45d154bd44f..13e872a1954 100755 --- a/assets/js/select2/select2.min.js +++ b/assets/js/select2/select2.min.js @@ -1,3 +1,3 @@ -!function(a){"undefined"==typeof a.fn.each2&&a.extend(a.fn,{each2:function(b){for(var c=a([0]),d=-1,e=this.length;++dc;c+=1)if(g(a,b[c]))return c;return-1}function f(){var b=a(N);b.appendTo(document.body);var c={width:b.width()-b[0].clientWidth,height:b.height()-b[0].clientHeight};return b.remove(),c}function g(a,c){return a===c?!0:a===b||c===b?!1:null===a||null===c?!1:a.constructor===String?a+""==c+"":c.constructor===String?c+""==a+"":!1}function h(a,b,c){var d,e,f;if(null===a||a.length<1)return[];for(d=a.split(b),e=0,f=d.length;f>e;e+=1)d[e]=c(d[e]);return d}function i(a){return a.outerWidth(!1)-a.width()}function j(c){var d="keyup-change-value";c.on("keydown",function(){a.data(c,d)===b&&a.data(c,d,c.val())}),c.on("keyup",function(){var e=a.data(c,d);e!==b&&c.val()!==e&&(a.removeData(c,d),c.trigger("keyup-change"))})}function k(c){c.on("mousemove",function(c){var d=L;d!==b&&d.x===c.pageX&&d.y===c.pageY||a(c.target).trigger("mousemove-filtered",c)})}function l(a,c,d){d=d||b;var e;return function(){var b=arguments;window.clearTimeout(e),e=window.setTimeout(function(){c.apply(d,b)},a)}}function m(a,b){var c=l(a,function(a){b.trigger("scroll-debounced",a)});b.on("scroll",function(a){e(a.target,b.get())>=0&&c(a)})}function n(a){a[0]!==document.activeElement&&window.setTimeout(function(){var b,c=a[0],d=a.val().length;a.focus();var e=c.offsetWidth>0||c.offsetHeight>0;e&&c===document.activeElement&&(c.setSelectionRange?c.setSelectionRange(d,d):c.createTextRange&&(b=c.createTextRange(),b.collapse(!1),b.select()))},0)}function o(b){b=a(b)[0];var c=0,d=0;if("selectionStart"in b)c=b.selectionStart,d=b.selectionEnd-c;else if("selection"in document){b.focus();var e=document.selection.createRange();d=document.selection.createRange().text.length,e.moveStart("character",-b.value.length),c=e.text.length-d}return{offset:c,length:d}}function p(a){a.preventDefault(),a.stopPropagation()}function q(a){a.preventDefault(),a.stopImmediatePropagation()}function r(b){if(!I){var c=b[0].currentStyle||window.getComputedStyle(b[0],null);I=a(document.createElement("div")).css({position:"absolute",left:"-10000px",top:"-10000px",display:"none",fontSize:c.fontSize,fontFamily:c.fontFamily,fontStyle:c.fontStyle,fontWeight:c.fontWeight,letterSpacing:c.letterSpacing,textTransform:c.textTransform,whiteSpace:"nowrap"}),I.attr("class","select2-sizer"),a(document.body).append(I)}return I.text(b.val()),I.width()}function s(b,c,d){var e,f,g=[];e=a.trim(b.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each2(function(){0===this.indexOf("select2-")&&g.push(this)})),e=a.trim(c.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each2(function(){0!==this.indexOf("select2-")&&(f=d(this),f&&g.push(f))})),b.attr("class",g.join(" "))}function t(a,b,c,e){var f=d(a.toUpperCase()).indexOf(d(b.toUpperCase())),g=b.length;return 0>f?void c.push(e(a)):(c.push(e(a.substring(0,f))),c.push(""),c.push(e(a.substring(f,f+g))),c.push(""),void c.push(e(a.substring(f+g,a.length))))}function u(a){var b={"\\":"\","&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})}function v(c){var d,e=null,f=c.quietMillis||100,g=c.url,h=this;return function(i){window.clearTimeout(d),d=window.setTimeout(function(){var d=c.data,f=g,j=c.transport||a.fn.select2.ajaxDefaults.transport,k={type:c.type||"GET",cache:c.cache||!1,jsonpCallback:c.jsonpCallback||b,dataType:c.dataType||"json"},l=a.extend({},a.fn.select2.ajaxDefaults.params,k);d=d?d.call(h,i.term,i.page,i.context):null,f="function"==typeof f?f.call(h,i.term,i.page,i.context):f,e&&"function"==typeof e.abort&&e.abort(),c.params&&(a.isFunction(c.params)?a.extend(l,c.params.call(h)):a.extend(l,c.params)),a.extend(l,{url:f,dataType:c.dataType,data:d,success:function(a){var b=c.results(a,i.page,i);i.callback(b)},error:function(a,b,c){var d={hasError:!0,jqXHR:a,textStatus:b,errorThrown:c};i.callback(d)}}),e=j.call(h,l)},f)}}function w(b){var c,d,e=b,f=function(a){return""+a.text};a.isArray(e)&&(d=e,e={results:d}),a.isFunction(e)===!1&&(d=e,e=function(){return d});var g=e();return g.text&&(f=g.text,a.isFunction(f)||(c=g.text,f=function(a){return a[c]})),function(b){var c,d=b.term,g={results:[]};return""===d?void b.callback(e()):(c=function(e,g){var h,i;if(e=e[0],e.children){h={};for(i in e)e.hasOwnProperty(i)&&(h[i]=e[i]);h.children=[],a(e.children).each2(function(a,b){c(b,h.children)}),(h.children.length||b.matcher(d,f(h),e))&&g.push(h)}else b.matcher(d,f(e),e)&&g.push(e)},a(e().results).each2(function(a,b){c(b,g.results)}),void b.callback(g))}}function x(c){var d=a.isFunction(c);return function(e){var f=e.term,g={results:[]},h=d?c(e):c;a.isArray(h)&&(a(h).each(function(){var a=this.text!==b,c=a?this.text:this;(""===f||e.matcher(f,c))&&g.results.push(a?this:{id:this,text:this})}),e.callback(g))}}function y(b,c){if(a.isFunction(b))return!0;if(!b)return!1;if("string"==typeof b)return!0;throw new Error(c+" must be a string, function, or falsy value")}function z(b,c){if(a.isFunction(b)){var d=Array.prototype.slice.call(arguments,2);return b.apply(c,d)}return b}function A(b){var c=0;return a.each(b,function(a,b){b.children?c+=A(b.children):c++}),c}function B(a,c,d,e){var f,h,i,j,k,l=a,m=!1;if(!e.createSearchChoice||!e.tokenSeparators||e.tokenSeparators.length<1)return b;for(;;){for(h=-1,i=0,j=e.tokenSeparators.length;j>i&&(k=e.tokenSeparators[i],h=a.indexOf(k),!(h>=0));i++);if(0>h)break;if(f=a.substring(0,h),a=a.substring(h+k.length),f.length>0&&(f=e.createSearchChoice.call(this,f,c),f!==b&&null!==f&&e.id(f)!==b&&null!==e.id(f))){for(m=!1,i=0,j=c.length;j>i;i++)if(g(e.id(f),e.id(c[i]))){m=!0;break}m||d(f)}}return l!==a?a:void 0}function C(){var b=this;a.each(arguments,function(a,c){b[c].remove(),b[c]=null})}function D(b,c){var d=function(){};return d.prototype=new b,d.prototype.constructor=d,d.prototype.parent=b.prototype,d.prototype=a.extend(d.prototype,c),d}if(window.Select2===b){var E,F,G,H,I,J,K,L={x:0,y:0},M={TAB:9,ENTER:13,ESC:27,SPACE:32,LEFT:37,UP:38,RIGHT:39,DOWN:40,SHIFT:16,CTRL:17,ALT:18,PAGE_UP:33,PAGE_DOWN:34,HOME:36,END:35,BACKSPACE:8,DELETE:46,isArrow:function(a){switch(a=a.which?a.which:a){case M.LEFT:case M.RIGHT:case M.UP:case M.DOWN:return!0}return!1},isControl:function(a){var b=a.which;switch(b){case M.SHIFT:case M.CTRL:case M.ALT:return!0}return!!a.metaKey},isFunctionKey:function(a){return a=a.which?a.which:a,a>=112&&123>=a}},N="
    ",O={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"};J=a(document),H=function(){var a=1;return function(){return a++}}(),E=D(Object,{bind:function(a){var b=this;return function(){a.apply(b,arguments)}},init:function(c){var d,e,g=".select2-results";this.opts=c=this.prepareOpts(c),this.id=c.id,c.element.data("select2")!==b&&null!==c.element.data("select2")&&c.element.data("select2").destroy(),this.container=this.createContainer(),this.liveRegion=a(".select2-hidden-accessible"),0==this.liveRegion.length&&(this.liveRegion=a("",{role:"status","aria-live":"polite"}).addClass("select2-hidden-accessible").appendTo(document.body)),this.containerId="s2id_"+(c.element.attr("id")||"autogen"+H()),this.containerEventName=this.containerId.replace(/([.])/g,"_").replace(/([;&,\-\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g,"\\$1"),this.container.attr("id",this.containerId),this.container.attr("title",c.element.attr("title")),this.body=a(document.body),s(this.container,this.opts.element,this.opts.adaptContainerCssClass),this.container.attr("style",c.element.attr("style")),this.container.css(z(c.containerCss,this.opts.element)),this.container.addClass(z(c.containerCssClass,this.opts.element)),this.elementTabIndex=this.opts.element.attr("tabindex"),this.opts.element.data("select2",this).attr("tabindex","-1").before(this.container).on("click.select2",p),this.container.data("select2",this),this.dropdown=this.container.find(".select2-drop"),s(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass),this.dropdown.addClass(z(c.dropdownCssClass,this.opts.element)),this.dropdown.data("select2",this),this.dropdown.on("click",p),this.results=d=this.container.find(g),this.search=e=this.container.find("input.select2-input"),this.queryCount=0,this.resultsPage=0,this.context=null,this.initContainer(),this.container.on("click",p),k(this.results),this.dropdown.on("mousemove-filtered",g,this.bind(this.highlightUnderEvent)),this.dropdown.on("touchstart touchmove touchend",g,this.bind(function(a){this._touchEvent=!0,this.highlightUnderEvent(a)})),this.dropdown.on("touchmove",g,this.bind(this.touchMoved)),this.dropdown.on("touchstart touchend",g,this.bind(this.clearTouchMoved)),this.dropdown.on("click",this.bind(function(a){this._touchEvent&&(this._touchEvent=!1,this.selectHighlighted())})),m(80,this.results),this.dropdown.on("scroll-debounced",g,this.bind(this.loadMoreIfNeeded)),a(this.container).on("change",".select2-input",function(a){a.stopPropagation()}),a(this.dropdown).on("change",".select2-input",function(a){a.stopPropagation()}),a.fn.mousewheel&&d.mousewheel(function(a,b,c,e){var f=d.scrollTop();e>0&&0>=f-e?(d.scrollTop(0),p(a)):0>e&&d.get(0).scrollHeight-d.scrollTop()+e<=d.height()&&(d.scrollTop(d.get(0).scrollHeight-d.height()),p(a))}),j(e),e.on("keyup-change input paste",this.bind(this.updateResults)),e.on("focus",function(){e.addClass("select2-focused")}),e.on("blur",function(){e.removeClass("select2-focused")}),this.dropdown.on("mouseup",g,this.bind(function(b){a(b.target).closest(".select2-result-selectable").length>0&&(this.highlightUnderEvent(b),this.selectHighlighted(b))})),this.dropdown.on("click mouseup mousedown touchstart touchend focusin",function(a){a.stopPropagation()}),this.lastSearchTerm=b,a.isFunction(this.opts.initSelection)&&(this.initSelection(),this.monitorSource()),null!==c.maximumInputLength&&this.search.attr("maxlength",c.maximumInputLength);var h=c.element.prop("disabled");h===b&&(h=!1),this.enable(!h);var i=c.element.prop("readonly");i===b&&(i=!1),this.readonly(i),K=K||f(),this.autofocus=c.element.prop("autofocus"),c.element.prop("autofocus",!1),this.autofocus&&this.focus(),this.search.attr("placeholder",c.searchInputPlaceholder)},destroy:function(){var a=this.opts.element,c=a.data("select2"),d=this;this.close(),a.length&&a[0].detachEvent&&d._sync&&a.each(function(){d._sync&&this.detachEvent("onpropertychange",d._sync)}),this.propertyObserver&&(this.propertyObserver.disconnect(),this.propertyObserver=null),this._sync=null,c!==b&&(c.container.remove(),c.liveRegion.remove(),c.dropdown.remove(),a.removeData("select2").off(".select2"),a.is("input[type='hidden']")?a.css("display",""):(a.show().prop("autofocus",this.autofocus||!1),this.elementTabIndex?a.attr({tabindex:this.elementTabIndex}):a.removeAttr("tabindex"),a.show())),C.call(this,"container","liveRegion","dropdown","results","search")},optionToData:function(a){return a.is("option")?{id:a.prop("value"),text:a.text(),element:a.get(),css:a.attr("class"),disabled:a.prop("disabled"),locked:g(a.attr("locked"),"locked")||g(a.data("locked"),!0)}:a.is("optgroup")?{text:a.attr("label"),children:[],element:a.get(),css:a.attr("class")}:void 0},prepareOpts:function(c){var d,e,f,i,j=this;if(d=c.element,"select"===d.get(0).tagName.toLowerCase()&&(this.select=e=c.element),e&&a.each(["id","multiple","ajax","query","createSearchChoice","initSelection","data","tags"],function(){if(this in c)throw new Error("Option '"+this+"' is not allowed for Select2 when attached to a ","
    "," ","
      ","
    ","
    "].join(""));return b},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.focusser.prop("disabled",!this.isInterfaceEnabled())},opening:function(){var b,c,d;this.opts.minimumResultsForSearch>=0&&this.showSearch(!0),this.parent.opening.apply(this,arguments),this.showSearchInput!==!1&&this.search.val(this.focusser.val()),this.opts.shouldFocusInput(this)&&(this.search.focus(),b=this.search.get(0),b.createTextRange?(c=b.createTextRange(),c.collapse(!1),c.select()):b.setSelectionRange&&(d=this.search.val().length,b.setSelectionRange(d,d))),this.prefillNextSearchTerm(),this.focusser.prop("disabled",!0).val(""),this.updateResults(!0),this.opts.element.trigger(a.Event("select2-open"))},close:function(){this.opened()&&(this.parent.close.apply(this,arguments),this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus())},focus:function(){this.opened()?this.close():(this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus())},isFocused:function(){return this.container.hasClass("select2-container-active")},cancel:function(){this.parent.cancel.apply(this,arguments),this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus()},destroy:function(){a("label[for='"+this.focusser.attr("id")+"']").attr("for",this.opts.element.attr("id")),this.parent.destroy.apply(this,arguments),C.call(this,"selection","focusser")},initContainer:function(){var b,d,e=this.container,f=this.dropdown,g=H();this.opts.minimumResultsForSearch<0?this.showSearch(!1):this.showSearch(!0),this.selection=b=e.find(".select2-choice"),this.focusser=e.find(".select2-focusser"),b.find(".select2-chosen").attr("id","select2-chosen-"+g),this.focusser.attr("aria-labelledby","select2-chosen-"+g),this.results.attr("id","select2-results-"+g),this.search.attr("aria-owns","select2-results-"+g),this.focusser.attr("id","s2id_autogen"+g),d=a("label[for='"+this.opts.element.attr("id")+"']"),this.opts.element.on("focus.select2",this.bind(function(){this.focus()})),this.focusser.prev().text(d.text()).attr("for",this.focusser.attr("id"));var h=this.opts.element.attr("title");this.opts.element.attr("title",h||d.text()),this.focusser.attr("tabindex",this.elementTabIndex),this.search.attr("id",this.focusser.attr("id")+"_search"),this.search.prev().text(a("label[for='"+this.focusser.attr("id")+"']").text()).attr("for",this.search.attr("id")),this.search.on("keydown",this.bind(function(a){if(this.isInterfaceEnabled()&&229!=a.keyCode){if(a.which===M.PAGE_UP||a.which===M.PAGE_DOWN)return void p(a);switch(a.which){case M.UP:case M.DOWN:return this.moveHighlight(a.which===M.UP?-1:1),void p(a);case M.ENTER:return this.selectHighlighted(),void p(a);case M.TAB:return void this.selectHighlighted({noFocus:!0});case M.ESC:return this.cancel(a),void p(a)}}})),this.search.on("blur",this.bind(function(a){document.activeElement===this.body.get(0)&&window.setTimeout(this.bind(function(){this.opened()&&this.results&&this.results.length>1&&this.search.focus()}),0)})),this.focusser.on("keydown",this.bind(function(a){if(this.isInterfaceEnabled()&&a.which!==M.TAB&&!M.isControl(a)&&!M.isFunctionKey(a)&&a.which!==M.ESC){if(this.opts.openOnEnter===!1&&a.which===M.ENTER)return void p(a);if(a.which==M.DOWN||a.which==M.UP||a.which==M.ENTER&&this.opts.openOnEnter){if(a.altKey||a.ctrlKey||a.shiftKey||a.metaKey)return;return this.open(),void p(a)}return a.which==M.DELETE||a.which==M.BACKSPACE?(this.opts.allowClear&&this.clear(),void p(a)):void 0}})),j(this.focusser),this.focusser.on("keyup-change input",this.bind(function(a){if(this.opts.minimumResultsForSearch>=0){if(a.stopPropagation(),this.opened())return;this.open()}})),b.on("mousedown touchstart","abbr",this.bind(function(a){this.isInterfaceEnabled()&&(this.clear(),q(a),this.close(),this.selection&&this.selection.focus())})),this.supportsTouchEvents?b.on("mousedown touchstart",this.bind(function(d){c(b),this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.opened()?this.close():this.isInterfaceEnabled()&&this.open(),p(d)})):b.on("mousedown",this.bind(function(d){c(b),this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.opened()?this.close():this.isInterfaceEnabled()&&this.open(),p(d)})),f.on("mousedown touchstart",this.bind(function(){this.opts.shouldFocusInput(this)&&this.search.focus()})),b.on("focus",this.bind(function(a){p(a)})),this.focusser.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active")})).on("blur",this.bind(function(){this.opened()||(this.container.removeClass("select2-container-active"),this.opts.element.trigger(a.Event("select2-blur")))})),this.search.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active")})),this.initContainerWidth(),this.opts.element.hide(),this.setPlaceholder()},clear:function(b){var c=this.selection.data("select2-data");if(c){var d=a.Event("select2-clearing");if(this.opts.element.trigger(d),d.isDefaultPrevented())return;var e=this.getPlaceholderOption();this.opts.element.val(e?e.val():""),this.selection.find(".select2-chosen").empty(),this.selection.removeData("select2-data"),this.setPlaceholder(),b!==!1&&(this.opts.element.trigger({type:"select2-removed",val:this.id(c),choice:c}),this.triggerChange({removed:c}))}},initSelection:function(){if(this.isPlaceholderOptionSelected())this.updateSelection(null),this.close(),this.setPlaceholder();else{var a=this;this.opts.initSelection.call(null,this.opts.element,function(c){c!==b&&null!==c&&(a.updateSelection(c),a.close(),a.setPlaceholder(),a.lastSearchTerm=a.search.val())})}},isPlaceholderOptionSelected:function(){var a;return this.getPlaceholder()===b?!1:(a=this.getPlaceholderOption())!==b&&a.prop("selected")||""===this.opts.element.val()||this.opts.element.val()===b||null===this.opts.element.val()},prepareOpts:function(){var b=this.parent.prepareOpts.apply(this,arguments),c=this;return"select"===b.element.get(0).tagName.toLowerCase()?b.initSelection=function(a,b){var d=a.find("option").filter(function(){return this.selected&&!this.disabled});b(c.optionToData(d))}:"data"in b&&(b.initSelection=b.initSelection||function(c,d){var e=c.val(),f=null;b.query({matcher:function(a,c,d){var h=g(e,b.id(d));return h&&(f=d),h},callback:a.isFunction(d)?function(){d(f)}:a.noop})}),b},getPlaceholder:function(){return this.select&&this.getPlaceholderOption()===b?b:this.parent.getPlaceholder.apply(this,arguments)},setPlaceholder:function(){var a=this.getPlaceholder();if(this.isPlaceholderOptionSelected()&&a!==b){if(this.select&&this.getPlaceholderOption()===b)return;this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(a)),this.selection.addClass("select2-default"),this.container.removeClass("select2-allowclear")}},postprocessResults:function(a,b,c){var d=0,e=this;if(this.findHighlightableChoices().each2(function(a,b){return g(e.id(b.data("select2-data")),e.opts.element.val())?(d=a,!1):void 0}),c!==!1&&(b===!0&&d>=0?this.highlight(d):this.highlight(0)),b===!0){var f=this.opts.minimumResultsForSearch;f>=0&&this.showSearch(A(a.results)>=f)}},showSearch:function(b){this.showSearchInput!==b&&(this.showSearchInput=b,this.dropdown.find(".select2-search").toggleClass("select2-search-hidden",!b),this.dropdown.find(".select2-search").toggleClass("select2-offscreen",!b),a(this.dropdown,this.container).toggleClass("select2-with-searchbox",b))},onSelect:function(a,b){if(this.triggerSelect(a)){var c=this.opts.element.val(),d=this.data();this.opts.element.val(this.id(a)),this.updateSelection(a),this.opts.element.trigger({type:"select2-selected",val:this.id(a),choice:a}),this.lastSearchTerm=this.search.val(),this.close(),b&&b.noFocus||!this.opts.shouldFocusInput(this)||this.focusser.focus(),g(c,this.id(a))||this.triggerChange({added:a,removed:d})}},updateSelection:function(a){var c,d,e=this.selection.find(".select2-chosen");this.selection.data("select2-data",a),e.empty(),null!==a&&(c=this.opts.formatSelection(a,e,this.opts.escapeMarkup)),c!==b&&e.append(c),d=this.opts.formatSelectionCssClass(a,e),d!==b&&e.addClass(d),this.selection.removeClass("select2-default"),this.opts.allowClear&&this.getPlaceholder()!==b&&this.container.addClass("select2-allowclear")},val:function(){var a,c=!1,d=null,e=this,f=this.data();if(0===arguments.length)return this.opts.element.val();if(a=arguments[0],arguments.length>1&&(c=arguments[1],this.opts.debug&&console&&console.warn&&console.warn('Select2: The second option to `select2("val")` is not supported in Select2 4.0.0. The `change` event will always be triggered in 4.0.0.')),this.select)this.opts.debug&&console&&console.warn&&console.warn('Select2: Setting the value on a "," ","","
    ","
      ","
    ","
    "].join(""));return b},prepareOpts:function(){var b=this.parent.prepareOpts.apply(this,arguments),c=this;return"select"===b.element.get(0).tagName.toLowerCase()?b.initSelection=function(a,b){var d=[];a.find("option").filter(function(){return this.selected&&!this.disabled}).each2(function(a,b){d.push(c.optionToData(b))}),b(d)}:"data"in b&&(b.initSelection=b.initSelection||function(c,d){var e=h(c.val(),b.separator,b.transformVal),f=[];b.query({matcher:function(c,d,h){var i=a.grep(e,function(a){return g(a,b.id(h))}).length;return i&&f.push(h),i},callback:a.isFunction(d)?function(){for(var a=[],c=0;c0||(this.selectChoice(null),this.clearPlaceholder(),this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.open(),this.focusSearch(),b.preventDefault()))})),this.container.on("focus",c,this.bind(function(){this.isInterfaceEnabled()&&(this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"),this.clearPlaceholder())})),this.initContainerWidth(),this.opts.element.hide(),this.clearSearch()},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.search.prop("disabled",!this.isInterfaceEnabled())},initSelection:function(){if(""===this.opts.element.val()&&""===this.opts.element.text()&&(this.updateSelection([]),this.close(),this.clearSearch()),this.select||""!==this.opts.element.val()){var a=this;this.opts.initSelection.call(null,this.opts.element,function(c){c!==b&&null!==c&&(a.updateSelection(c),a.close(),a.clearSearch())})}},clearSearch:function(){var a=this.getPlaceholder(),c=this.getMaxSearchWidth();a!==b&&0===this.getVal().length&&this.search.hasClass("select2-focused")===!1?(this.search.val(a).addClass("select2-default"),this.search.width(c>0?c:this.container.css("width"))):this.search.val("").width(10)},clearPlaceholder:function(){this.search.hasClass("select2-default")&&this.search.val("").removeClass("select2-default")},opening:function(){this.clearPlaceholder(),this.resizeSearch(),this.parent.opening.apply(this,arguments),this.focusSearch(),this.prefillNextSearchTerm(),this.updateResults(!0),this.opts.shouldFocusInput(this)&&this.search.focus(),this.opts.element.trigger(a.Event("select2-open"))},close:function(){this.opened()&&this.parent.close.apply(this,arguments)},focus:function(){this.close(),this.search.focus()},isFocused:function(){return this.search.hasClass("select2-focused")},updateSelection:function(b){var c={},d=[],e=this;a(b).each(function(){e.id(this)in c||(c[e.id(this)]=0,d.push(this))}),this.selection.find(".select2-search-choice").remove(),this.addSelectedChoice(d),e.postprocessResults()},tokenize:function(){var a=this.search.val();a=this.opts.tokenizer.call(this,a,this.data(),this.bind(this.onSelect),this.opts),null!=a&&a!=b&&(this.search.val(a),a.length>0&&this.open())},onSelect:function(a,b){this.triggerSelect(a)&&""!==a.text&&(this.addSelectedChoice(a),this.opts.element.trigger({type:"selected",val:this.id(a),choice:a}),this.lastSearchTerm=this.search.val(),this.clearSearch(),this.updateResults(),!this.select&&this.opts.closeOnSelect||this.postprocessResults(a,!1,this.opts.closeOnSelect===!0),this.opts.closeOnSelect?(this.close(),this.search.width(10)):this.countSelectableResults()>0?(this.search.width(10),this.resizeSearch(),this.getMaximumSelectionSize()>0&&this.val().length>=this.getMaximumSelectionSize()?this.updateResults(!0):this.prefillNextSearchTerm()&&this.updateResults(),this.positionDropdown()):(this.close(),this.search.width(10)),this.triggerChange({added:a}),b&&b.noFocus||this.focusSearch())},cancel:function(){this.close(),this.focusSearch()},addSelectedChoice:function(b){var c=this.getVal(),d=this;a(b).each(function(){c.push(d.createChoice(this))}),this.setVal(c)},createChoice:function(c){var d,e,f=!c.locked,g=a("
  • "),h=a("
  • "),i=f?g:h,j=this.id(c);return d=this.opts.formatSelection(c,i.find("div"),this.opts.escapeMarkup),d!=b&&i.find("div").replaceWith(a("
    ").html(d)),e=this.opts.formatSelectionCssClass(c,i.find("div")),e!=b&&i.addClass(e),f&&i.find(".select2-search-choice-close").on("mousedown",p).on("click dblclick",this.bind(function(b){this.isInterfaceEnabled()&&(this.unselect(a(b.target)),this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus"),p(b),this.close(),this.focusSearch())})).on("focus",this.bind(function(){this.isInterfaceEnabled()&&(this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"))})),i.data("select2-data",c),i.insertBefore(this.searchContainer),j},unselect:function(b){var c,d,f=this.getVal();if(b=b.closest(".select2-search-choice"),0===b.length)throw"Invalid argument: "+b+". Must be .select2-search-choice";if(c=b.data("select2-data")){var g=a.Event("select2-removing");if(g.val=this.id(c),g.choice=c,this.opts.element.trigger(g),g.isDefaultPrevented())return!1;for(;(d=e(this.id(c),f))>=0;)f.splice(d,1),this.setVal(f),this.select&&this.postprocessResults();return b.remove(),this.opts.element.trigger({type:"select2-removed",val:this.id(c),choice:c}),this.triggerChange({removed:c}),!0}},postprocessResults:function(a,b,c){var d=this.getVal(),f=this.results.find(".select2-result"),g=this.results.find(".select2-result-with-children"),h=this;f.each2(function(a,b){var c=h.id(b.data("select2-data"));e(c,d)>=0&&(b.addClass("select2-selected"),b.find(".select2-result-selectable").addClass("select2-selected"))}),g.each2(function(a,b){b.is(".select2-result-selectable")||0!==b.find(".select2-result-selectable:not(.select2-selected)").length||b.addClass("select2-selected")}),-1==this.highlight()&&c!==!1&&this.opts.closeOnSelect===!0&&h.highlight(0),!this.opts.createSearchChoice&&!f.filter(".select2-result:not(.select2-selected)").length>0&&(!a||a&&!a.more&&0===this.results.find(".select2-no-results").length)&&y(h.opts.formatNoMatches,"formatNoMatches")&&this.results.append("
  • "+z(h.opts.formatNoMatches,h.opts.element,h.search.val())+"
  • ")},getMaxSearchWidth:function(){return this.selection.width()-i(this.search)},resizeSearch:function(){var a,b,c,d,e,f=i(this.search);a=r(this.search)+10,b=this.search.offset().left,c=this.selection.width(),d=this.selection.offset().left,e=c-(b-d)-f,a>e&&(e=c-f),40>e&&(e=c-f),0>=e&&(e=a),this.search.width(Math.floor(e))},getVal:function(){var a;return this.select?(a=this.select.val(),null===a?[]:a):(a=this.opts.element.val(),h(a,this.opts.separator,this.opts.transformVal))},setVal:function(b){if(this.select)this.select.val(b);else{var c=[],d={};a(b).each(function(){this in d||(c.push(this),d[this]=0)}),this.opts.element.val(0===c.length?"":c.join(this.opts.separator))}},buildChangeDetails:function(a,b){for(var b=b.slice(0),a=a.slice(0),c=0;c. Attach to instead.");this.search.width(0),this.searchContainer.hide()},onSortEnd:function(){var b=[],c=this;this.searchContainer.show(),this.searchContainer.appendTo(this.searchContainer.parent()),this.resizeSearch(),this.selection.find(".select2-search-choice").each(function(){b.push(c.opts.id(a(this).data("select2-data")))}),this.setVal(b),this.triggerChange()},data:function(b,c){var d,e,f=this;return 0===arguments.length?this.selection.children(".select2-search-choice").map(function(){return a(this).data("select2-data")}).get():(e=this.data(),b||(b=[]),d=a.map(b,function(a){return f.opts.id(a)}),this.setVal(d),this.updateSelection(b),this.clearSearch(),c&&this.triggerChange(this.buildChangeDetails(e,this.data())),void 0)}}),a.fn.select2=function(){var c,d,f,g,h,i=Array.prototype.slice.call(arguments,0),j=["val","destroy","opened","open","close","focus","isFocused","container","dropdown","onSortStart","onSortEnd","enable","disable","readonly","positionDropdown","data","search"],k=["opened","isFocused","container","dropdown"],l=["val","data"],m={search:"externalSearch"};return this.each(function(){if(0===i.length||"object"==typeof i[0])c=0===i.length?{}:a.extend({},i[0]),c.element=a(this),"select"===c.element.get(0).tagName.toLowerCase()?h=c.element.prop("multiple"):(h=c.multiple||!1,"tags"in c&&(c.multiple=h=!0)),d=h?new window.Select2["class"].multi:new window.Select2["class"].single,d.init(c);else{if("string"!=typeof i[0])throw"Invalid arguments to select2 plugin: "+i;if(e(i[0],j)<0)throw"Unknown method: "+i[0];if(g=b,d=a(this).data("select2"),d===b)return;if(f=i[0],"container"===f?g=d.container:"dropdown"===f?g=d.dropdown:(m[f]&&(f=m[f]),g=d[f].apply(d,i.slice(1))),e(i[0],k)>=0||e(i[0],l)>=0&&1==i.length)return!1}}),g===b?this:g},a.fn.select2.defaults={debug:!1,width:"copy",loadMorePadding:0,closeOnSelect:!0,openOnEnter:!0,containerCss:{},dropdownCss:{},containerCssClass:"",dropdownCssClass:"",formatResult:function(a,b,c,d){var e=[];return t(this.text(a),c.term,e,d),e.join("")},transformVal:function(b){return a.trim(b)},formatSelection:function(a,c,d){return a?d(this.text(a)):b},sortResults:function(a,b,c){return a},formatResultCssClass:function(a){return a.css},formatSelectionCssClass:function(a,c){return b},minimumResultsForSearch:0,minimumInputLength:0,maximumInputLength:null,maximumSelectionSize:0,id:function(a){return a==b?null:a.id},text:function(b){return b&&this.data&&this.data.text?a.isFunction(this.data.text)?this.data.text(b):b[this.data.text]:b.text},matcher:function(a,b){return d(""+b).toUpperCase().indexOf(d(""+a).toUpperCase())>=0},separator:",",tokenSeparators:[],tokenizer:B,escapeMarkup:u,blurOnChange:!1,selectOnBlur:!1,adaptContainerCssClass:function(a){return a},adaptDropdownCssClass:function(a){return null},nextSearchTerm:function(a,c){return b},searchInputPlaceholder:"", -createSearchChoicePosition:"top",shouldFocusInput:function(a){var b="ontouchstart"in window||navigator.msMaxTouchPoints>0;return b?!(a.opts.minimumResultsForSearch<0):!0}},a.fn.select2.locales=[],a.fn.select2.locales.en={formatMatches:function(a){return 1===a?"One result is available, press enter to select it.":a+" results are available, use up and down arrow keys to navigate."},formatNoMatches:function(){return"No matches found"},formatAjaxError:function(a,b,c){return"Loading failed"},formatInputTooShort:function(a,b){var c=b-a.length;return"Please enter "+c+" or more character"+(1==c?"":"s")},formatInputTooLong:function(a,b){var c=a.length-b;return"Please delete "+c+" character"+(1==c?"":"s")},formatSelectionTooBig:function(a){return"You can only select "+a+" item"+(1==a?"":"s")},formatLoadMore:function(a){return"Loading more results…"},formatSearching:function(){return"Searching…"}},a.extend(a.fn.select2.defaults,a.fn.select2.locales.en),a.fn.select2.ajaxDefaults={transport:a.ajax,params:{type:"GET",cache:!1,dataType:"json"}},window.Select2={query:{ajax:v,local:w,tags:x},util:{debounce:l,markMatch:t,escapeMarkup:u,stripDiacritics:d},"class":{"abstract":E,single:F,multi:G}}}}(jQuery); \ No newline at end of file +!function(a){"undefined"==typeof a.fn.each2&&a.extend(a.fn,{each2:function(b){for(var c=a([0]),d=-1,e=this.length;++d=0&&c(a)})}function n(a){a[0]!==document.activeElement&&window.setTimeout(function(){var b,c=a[0],d=a.val().length;a.focus();var e=c.offsetWidth>0||c.offsetHeight>0;e&&c===document.activeElement&&(c.setSelectionRange?c.setSelectionRange(d,d):c.createTextRange&&(b=c.createTextRange(),b.collapse(!1),b.select()))},0)}function o(b){b=a(b)[0];var c=0,d=0;if("selectionStart"in b)c=b.selectionStart,d=b.selectionEnd-c;else if("selection"in document){b.focus();var e=document.selection.createRange();d=document.selection.createRange().text.length,e.moveStart("character",-b.value.length),c=e.text.length-d}return{offset:c,length:d}}function p(a){a.preventDefault(),a.stopPropagation()}function q(a){a.preventDefault(),a.stopImmediatePropagation()}function r(b){if(!I){var c=b[0].currentStyle||window.getComputedStyle(b[0],null);I=a(document.createElement("div")).css({position:"absolute",left:"-10000px",top:"-10000px",display:"none",fontSize:c.fontSize,fontFamily:c.fontFamily,fontStyle:c.fontStyle,fontWeight:c.fontWeight,letterSpacing:c.letterSpacing,textTransform:c.textTransform,whiteSpace:"nowrap"}),I.attr("class","select2-sizer"),a(document.body).append(I)}return I.text(b.val()),I.width()}function s(b,c,d){var e,f,g=[];e=a.trim(b.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each2(function(){0===this.indexOf("select2-")&&g.push(this)})),e=a.trim(c.attr("class")),e&&(e=""+e,a(e.split(/\s+/)).each2(function(){0!==this.indexOf("select2-")&&(f=d(this),f&&g.push(f))})),b.attr("class",g.join(" "))}function t(a,b,c,e){var f=d(a.toUpperCase()).indexOf(d(b.toUpperCase())),g=b.length;return f<0?void c.push(e(a)):(c.push(e(a.substring(0,f))),c.push(""),c.push(e(a.substring(f,f+g))),c.push(""),void c.push(e(a.substring(f+g,a.length))))}function u(a){var b={"\\":"\","&":"&","<":"<",">":">",'"':""","'":"'","/":"/"};return String(a).replace(/[&<>"'\/\\]/g,function(a){return b[a]})}function v(c){var d,e=null,f=c.quietMillis||100,g=c.url,h=this;return function(i){window.clearTimeout(d),d=window.setTimeout(function(){var d=c.data,f=g,j=c.transport||a.fn.select2.ajaxDefaults.transport,k={type:c.type||"GET",cache:c.cache||!1,jsonpCallback:c.jsonpCallback||b,dataType:c.dataType||"json"},l=a.extend({},a.fn.select2.ajaxDefaults.params,k);d=d?d.call(h,i.term,i.page,i.context):null,f="function"==typeof f?f.call(h,i.term,i.page,i.context):f,e&&"function"==typeof e.abort&&e.abort(),c.params&&(a.isFunction(c.params)?a.extend(l,c.params.call(h)):a.extend(l,c.params)),a.extend(l,{url:f,dataType:c.dataType,data:d,success:function(a){var b=c.results(a,i.page,i);i.callback(b)},error:function(a,b,c){var d={hasError:!0,jqXHR:a,textStatus:b,errorThrown:c};i.callback(d)}}),e=j.call(h,l)},f)}}function w(b){var c,d,e=b,f=function(a){return""+a.text};a.isArray(e)&&(d=e,e={results:d}),a.isFunction(e)===!1&&(d=e,e=function(){return d});var g=e();return g.text&&(f=g.text,a.isFunction(f)||(c=g.text,f=function(a){return a[c]})),function(b){var c,d=b.term,g={results:[]};return""===d?void b.callback(e()):(c=function(e,g){var h,i;if(e=e[0],e.children){h={};for(i in e)e.hasOwnProperty(i)&&(h[i]=e[i]);h.children=[],a(e.children).each2(function(a,b){c(b,h.children)}),(h.children.length||b.matcher(d,f(h),e))&&g.push(h)}else b.matcher(d,f(e),e)&&g.push(e)},a(e().results).each2(function(a,b){c(b,g.results)}),void b.callback(g))}}function x(c){var d=a.isFunction(c);return function(e){var f=e.term,g={results:[]},h=d?c(e):c;a.isArray(h)&&(a(h).each(function(){var a=this.text!==b,c=a?this.text:this;(""===f||e.matcher(f,c))&&g.results.push(a?this:{id:this,text:this})}),e.callback(g))}}function y(b,c){if(a.isFunction(b))return!0;if(!b)return!1;if("string"==typeof b)return!0;throw new Error(c+" must be a string, function, or falsy value")}function z(b,c){if(a.isFunction(b)){var d=Array.prototype.slice.call(arguments,2);return b.apply(c,d)}return b}function A(b){var c=0;return a.each(b,function(a,b){b.children?c+=A(b.children):c++}),c}function B(a,c,d,e){var f,h,i,j,k,l=a,m=!1;if(!e.createSearchChoice||!e.tokenSeparators||e.tokenSeparators.length<1)return b;for(;;){for(h=-1,i=0,j=e.tokenSeparators.length;i=0));i++);if(h<0)break;if(f=a.substring(0,h),a=a.substring(h+k.length),f.length>0&&(f=e.createSearchChoice.call(this,f,c),f!==b&&null!==f&&e.id(f)!==b&&null!==e.id(f))){for(m=!1,i=0,j=c.length;i=112&&a<=123}},N="
    ",O={"Ⓐ":"A","A":"A","À":"A","Á":"A","Â":"A","Ầ":"A","Ấ":"A","Ẫ":"A","Ẩ":"A","Ã":"A","Ā":"A","Ă":"A","Ằ":"A","Ắ":"A","Ẵ":"A","Ẳ":"A","Ȧ":"A","Ǡ":"A","Ä":"A","Ǟ":"A","Ả":"A","Å":"A","Ǻ":"A","Ǎ":"A","Ȁ":"A","Ȃ":"A","Ạ":"A","Ậ":"A","Ặ":"A","Ḁ":"A","Ą":"A","Ⱥ":"A","Ɐ":"A","Ꜳ":"AA","Æ":"AE","Ǽ":"AE","Ǣ":"AE","Ꜵ":"AO","Ꜷ":"AU","Ꜹ":"AV","Ꜻ":"AV","Ꜽ":"AY","Ⓑ":"B","B":"B","Ḃ":"B","Ḅ":"B","Ḇ":"B","Ƀ":"B","Ƃ":"B","Ɓ":"B","Ⓒ":"C","C":"C","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","Ç":"C","Ḉ":"C","Ƈ":"C","Ȼ":"C","Ꜿ":"C","Ⓓ":"D","D":"D","Ḋ":"D","Ď":"D","Ḍ":"D","Ḑ":"D","Ḓ":"D","Ḏ":"D","Đ":"D","Ƌ":"D","Ɗ":"D","Ɖ":"D","Ꝺ":"D","DZ":"DZ","DŽ":"DZ","Dz":"Dz","Dž":"Dz","Ⓔ":"E","E":"E","È":"E","É":"E","Ê":"E","Ề":"E","Ế":"E","Ễ":"E","Ể":"E","Ẽ":"E","Ē":"E","Ḕ":"E","Ḗ":"E","Ĕ":"E","Ė":"E","Ë":"E","Ẻ":"E","Ě":"E","Ȅ":"E","Ȇ":"E","Ẹ":"E","Ệ":"E","Ȩ":"E","Ḝ":"E","Ę":"E","Ḙ":"E","Ḛ":"E","Ɛ":"E","Ǝ":"E","Ⓕ":"F","F":"F","Ḟ":"F","Ƒ":"F","Ꝼ":"F","Ⓖ":"G","G":"G","Ǵ":"G","Ĝ":"G","Ḡ":"G","Ğ":"G","Ġ":"G","Ǧ":"G","Ģ":"G","Ǥ":"G","Ɠ":"G","Ꞡ":"G","Ᵹ":"G","Ꝿ":"G","Ⓗ":"H","H":"H","Ĥ":"H","Ḣ":"H","Ḧ":"H","Ȟ":"H","Ḥ":"H","Ḩ":"H","Ḫ":"H","Ħ":"H","Ⱨ":"H","Ⱶ":"H","Ɥ":"H","Ⓘ":"I","I":"I","Ì":"I","Í":"I","Î":"I","Ĩ":"I","Ī":"I","Ĭ":"I","İ":"I","Ï":"I","Ḯ":"I","Ỉ":"I","Ǐ":"I","Ȉ":"I","Ȋ":"I","Ị":"I","Į":"I","Ḭ":"I","Ɨ":"I","Ⓙ":"J","J":"J","Ĵ":"J","Ɉ":"J","Ⓚ":"K","K":"K","Ḱ":"K","Ǩ":"K","Ḳ":"K","Ķ":"K","Ḵ":"K","Ƙ":"K","Ⱪ":"K","Ꝁ":"K","Ꝃ":"K","Ꝅ":"K","Ꞣ":"K","Ⓛ":"L","L":"L","Ŀ":"L","Ĺ":"L","Ľ":"L","Ḷ":"L","Ḹ":"L","Ļ":"L","Ḽ":"L","Ḻ":"L","Ł":"L","Ƚ":"L","Ɫ":"L","Ⱡ":"L","Ꝉ":"L","Ꝇ":"L","Ꞁ":"L","LJ":"LJ","Lj":"Lj","Ⓜ":"M","M":"M","Ḿ":"M","Ṁ":"M","Ṃ":"M","Ɱ":"M","Ɯ":"M","Ⓝ":"N","N":"N","Ǹ":"N","Ń":"N","Ñ":"N","Ṅ":"N","Ň":"N","Ṇ":"N","Ņ":"N","Ṋ":"N","Ṉ":"N","Ƞ":"N","Ɲ":"N","Ꞑ":"N","Ꞥ":"N","NJ":"NJ","Nj":"Nj","Ⓞ":"O","O":"O","Ò":"O","Ó":"O","Ô":"O","Ồ":"O","Ố":"O","Ỗ":"O","Ổ":"O","Õ":"O","Ṍ":"O","Ȭ":"O","Ṏ":"O","Ō":"O","Ṑ":"O","Ṓ":"O","Ŏ":"O","Ȯ":"O","Ȱ":"O","Ö":"O","Ȫ":"O","Ỏ":"O","Ő":"O","Ǒ":"O","Ȍ":"O","Ȏ":"O","Ơ":"O","Ờ":"O","Ớ":"O","Ỡ":"O","Ở":"O","Ợ":"O","Ọ":"O","Ộ":"O","Ǫ":"O","Ǭ":"O","Ø":"O","Ǿ":"O","Ɔ":"O","Ɵ":"O","Ꝋ":"O","Ꝍ":"O","Ƣ":"OI","Ꝏ":"OO","Ȣ":"OU","Ⓟ":"P","P":"P","Ṕ":"P","Ṗ":"P","Ƥ":"P","Ᵽ":"P","Ꝑ":"P","Ꝓ":"P","Ꝕ":"P","Ⓠ":"Q","Q":"Q","Ꝗ":"Q","Ꝙ":"Q","Ɋ":"Q","Ⓡ":"R","R":"R","Ŕ":"R","Ṙ":"R","Ř":"R","Ȑ":"R","Ȓ":"R","Ṛ":"R","Ṝ":"R","Ŗ":"R","Ṟ":"R","Ɍ":"R","Ɽ":"R","Ꝛ":"R","Ꞧ":"R","Ꞃ":"R","Ⓢ":"S","S":"S","ẞ":"S","Ś":"S","Ṥ":"S","Ŝ":"S","Ṡ":"S","Š":"S","Ṧ":"S","Ṣ":"S","Ṩ":"S","Ș":"S","Ş":"S","Ȿ":"S","Ꞩ":"S","Ꞅ":"S","Ⓣ":"T","T":"T","Ṫ":"T","Ť":"T","Ṭ":"T","Ț":"T","Ţ":"T","Ṱ":"T","Ṯ":"T","Ŧ":"T","Ƭ":"T","Ʈ":"T","Ⱦ":"T","Ꞇ":"T","Ꜩ":"TZ","Ⓤ":"U","U":"U","Ù":"U","Ú":"U","Û":"U","Ũ":"U","Ṹ":"U","Ū":"U","Ṻ":"U","Ŭ":"U","Ü":"U","Ǜ":"U","Ǘ":"U","Ǖ":"U","Ǚ":"U","Ủ":"U","Ů":"U","Ű":"U","Ǔ":"U","Ȕ":"U","Ȗ":"U","Ư":"U","Ừ":"U","Ứ":"U","Ữ":"U","Ử":"U","Ự":"U","Ụ":"U","Ṳ":"U","Ų":"U","Ṷ":"U","Ṵ":"U","Ʉ":"U","Ⓥ":"V","V":"V","Ṽ":"V","Ṿ":"V","Ʋ":"V","Ꝟ":"V","Ʌ":"V","Ꝡ":"VY","Ⓦ":"W","W":"W","Ẁ":"W","Ẃ":"W","Ŵ":"W","Ẇ":"W","Ẅ":"W","Ẉ":"W","Ⱳ":"W","Ⓧ":"X","X":"X","Ẋ":"X","Ẍ":"X","Ⓨ":"Y","Y":"Y","Ỳ":"Y","Ý":"Y","Ŷ":"Y","Ỹ":"Y","Ȳ":"Y","Ẏ":"Y","Ÿ":"Y","Ỷ":"Y","Ỵ":"Y","Ƴ":"Y","Ɏ":"Y","Ỿ":"Y","Ⓩ":"Z","Z":"Z","Ź":"Z","Ẑ":"Z","Ż":"Z","Ž":"Z","Ẓ":"Z","Ẕ":"Z","Ƶ":"Z","Ȥ":"Z","Ɀ":"Z","Ⱬ":"Z","Ꝣ":"Z","ⓐ":"a","a":"a","ẚ":"a","à":"a","á":"a","â":"a","ầ":"a","ấ":"a","ẫ":"a","ẩ":"a","ã":"a","ā":"a","ă":"a","ằ":"a","ắ":"a","ẵ":"a","ẳ":"a","ȧ":"a","ǡ":"a","ä":"a","ǟ":"a","ả":"a","å":"a","ǻ":"a","ǎ":"a","ȁ":"a","ȃ":"a","ạ":"a","ậ":"a","ặ":"a","ḁ":"a","ą":"a","ⱥ":"a","ɐ":"a","ꜳ":"aa","æ":"ae","ǽ":"ae","ǣ":"ae","ꜵ":"ao","ꜷ":"au","ꜹ":"av","ꜻ":"av","ꜽ":"ay","ⓑ":"b","b":"b","ḃ":"b","ḅ":"b","ḇ":"b","ƀ":"b","ƃ":"b","ɓ":"b","ⓒ":"c","c":"c","ć":"c","ĉ":"c","ċ":"c","č":"c","ç":"c","ḉ":"c","ƈ":"c","ȼ":"c","ꜿ":"c","ↄ":"c","ⓓ":"d","d":"d","ḋ":"d","ď":"d","ḍ":"d","ḑ":"d","ḓ":"d","ḏ":"d","đ":"d","ƌ":"d","ɖ":"d","ɗ":"d","ꝺ":"d","dz":"dz","dž":"dz","ⓔ":"e","e":"e","è":"e","é":"e","ê":"e","ề":"e","ế":"e","ễ":"e","ể":"e","ẽ":"e","ē":"e","ḕ":"e","ḗ":"e","ĕ":"e","ė":"e","ë":"e","ẻ":"e","ě":"e","ȅ":"e","ȇ":"e","ẹ":"e","ệ":"e","ȩ":"e","ḝ":"e","ę":"e","ḙ":"e","ḛ":"e","ɇ":"e","ɛ":"e","ǝ":"e","ⓕ":"f","f":"f","ḟ":"f","ƒ":"f","ꝼ":"f","ⓖ":"g","g":"g","ǵ":"g","ĝ":"g","ḡ":"g","ğ":"g","ġ":"g","ǧ":"g","ģ":"g","ǥ":"g","ɠ":"g","ꞡ":"g","ᵹ":"g","ꝿ":"g","ⓗ":"h","h":"h","ĥ":"h","ḣ":"h","ḧ":"h","ȟ":"h","ḥ":"h","ḩ":"h","ḫ":"h","ẖ":"h","ħ":"h","ⱨ":"h","ⱶ":"h","ɥ":"h","ƕ":"hv","ⓘ":"i","i":"i","ì":"i","í":"i","î":"i","ĩ":"i","ī":"i","ĭ":"i","ï":"i","ḯ":"i","ỉ":"i","ǐ":"i","ȉ":"i","ȋ":"i","ị":"i","į":"i","ḭ":"i","ɨ":"i","ı":"i","ⓙ":"j","j":"j","ĵ":"j","ǰ":"j","ɉ":"j","ⓚ":"k","k":"k","ḱ":"k","ǩ":"k","ḳ":"k","ķ":"k","ḵ":"k","ƙ":"k","ⱪ":"k","ꝁ":"k","ꝃ":"k","ꝅ":"k","ꞣ":"k","ⓛ":"l","l":"l","ŀ":"l","ĺ":"l","ľ":"l","ḷ":"l","ḹ":"l","ļ":"l","ḽ":"l","ḻ":"l","ſ":"l","ł":"l","ƚ":"l","ɫ":"l","ⱡ":"l","ꝉ":"l","ꞁ":"l","ꝇ":"l","lj":"lj","ⓜ":"m","m":"m","ḿ":"m","ṁ":"m","ṃ":"m","ɱ":"m","ɯ":"m","ⓝ":"n","n":"n","ǹ":"n","ń":"n","ñ":"n","ṅ":"n","ň":"n","ṇ":"n","ņ":"n","ṋ":"n","ṉ":"n","ƞ":"n","ɲ":"n","ʼn":"n","ꞑ":"n","ꞥ":"n","nj":"nj","ⓞ":"o","o":"o","ò":"o","ó":"o","ô":"o","ồ":"o","ố":"o","ỗ":"o","ổ":"o","õ":"o","ṍ":"o","ȭ":"o","ṏ":"o","ō":"o","ṑ":"o","ṓ":"o","ŏ":"o","ȯ":"o","ȱ":"o","ö":"o","ȫ":"o","ỏ":"o","ő":"o","ǒ":"o","ȍ":"o","ȏ":"o","ơ":"o","ờ":"o","ớ":"o","ỡ":"o","ở":"o","ợ":"o","ọ":"o","ộ":"o","ǫ":"o","ǭ":"o","ø":"o","ǿ":"o","ɔ":"o","ꝋ":"o","ꝍ":"o","ɵ":"o","ƣ":"oi","ȣ":"ou","ꝏ":"oo","ⓟ":"p","p":"p","ṕ":"p","ṗ":"p","ƥ":"p","ᵽ":"p","ꝑ":"p","ꝓ":"p","ꝕ":"p","ⓠ":"q","q":"q","ɋ":"q","ꝗ":"q","ꝙ":"q","ⓡ":"r","r":"r","ŕ":"r","ṙ":"r","ř":"r","ȑ":"r","ȓ":"r","ṛ":"r","ṝ":"r","ŗ":"r","ṟ":"r","ɍ":"r","ɽ":"r","ꝛ":"r","ꞧ":"r","ꞃ":"r","ⓢ":"s","s":"s","ß":"s","ś":"s","ṥ":"s","ŝ":"s","ṡ":"s","š":"s","ṧ":"s","ṣ":"s","ṩ":"s","ș":"s","ş":"s","ȿ":"s","ꞩ":"s","ꞅ":"s","ẛ":"s","ⓣ":"t","t":"t","ṫ":"t","ẗ":"t","ť":"t","ṭ":"t","ț":"t","ţ":"t","ṱ":"t","ṯ":"t","ŧ":"t","ƭ":"t","ʈ":"t","ⱦ":"t","ꞇ":"t","ꜩ":"tz","ⓤ":"u","u":"u","ù":"u","ú":"u","û":"u","ũ":"u","ṹ":"u","ū":"u","ṻ":"u","ŭ":"u","ü":"u","ǜ":"u","ǘ":"u","ǖ":"u","ǚ":"u","ủ":"u","ů":"u","ű":"u","ǔ":"u","ȕ":"u","ȗ":"u","ư":"u","ừ":"u","ứ":"u","ữ":"u","ử":"u","ự":"u","ụ":"u","ṳ":"u","ų":"u","ṷ":"u","ṵ":"u","ʉ":"u","ⓥ":"v","v":"v","ṽ":"v","ṿ":"v","ʋ":"v","ꝟ":"v","ʌ":"v","ꝡ":"vy","ⓦ":"w","w":"w","ẁ":"w","ẃ":"w","ŵ":"w","ẇ":"w","ẅ":"w","ẘ":"w","ẉ":"w","ⱳ":"w","ⓧ":"x","x":"x","ẋ":"x","ẍ":"x","ⓨ":"y","y":"y","ỳ":"y","ý":"y","ŷ":"y","ỹ":"y","ȳ":"y","ẏ":"y","ÿ":"y","ỷ":"y","ẙ":"y","ỵ":"y","ƴ":"y","ɏ":"y","ỿ":"y","ⓩ":"z","z":"z","ź":"z","ẑ":"z","ż":"z","ž":"z","ẓ":"z","ẕ":"z","ƶ":"z","ȥ":"z","ɀ":"z","ⱬ":"z","ꝣ":"z","Ά":"Α","Έ":"Ε","Ή":"Η","Ί":"Ι","Ϊ":"Ι","Ό":"Ο","Ύ":"Υ","Ϋ":"Υ","Ώ":"Ω","ά":"α","έ":"ε","ή":"η","ί":"ι","ϊ":"ι","ΐ":"ι","ό":"ο","ύ":"υ","ϋ":"υ","ΰ":"υ","ω":"ω","ς":"σ"};J=a(document),H=function(){var a=1;return function(){return a++}}(),E=D(Object,{bind:function(a){var b=this;return function(){a.apply(b,arguments)}},init:function(c){var d,e,g=".select2-results";this.opts=c=this.prepareOpts(c),this.id=c.id,c.element.data("select2")!==b&&null!==c.element.data("select2")&&c.element.data("select2").destroy(),this.container=this.createContainer(),this.liveRegion=a(".select2-hidden-accessible"),0==this.liveRegion.length&&(this.liveRegion=a("",{role:"status","aria-live":"polite"}).addClass("select2-hidden-accessible").appendTo(document.body)),this.containerId="s2id_"+(c.element.attr("id")||"autogen"+H()),this.containerEventName=this.containerId.replace(/([.])/g,"_").replace(/([;&,\-\.\+\*\~':"\!\^#$%@\[\]\(\)=>\|])/g,"\\$1"),this.container.attr("id",this.containerId),this.container.attr("title",c.element.attr("title")),this.body=a(document.body),s(this.container,this.opts.element,this.opts.adaptContainerCssClass),this.container.attr("style",c.element.attr("style")),this.container.css(z(c.containerCss,this.opts.element)),this.container.addClass(z(c.containerCssClass,this.opts.element)),this.elementTabIndex=this.opts.element.attr("tabindex"),this.opts.element.data("select2",this).attr("tabindex","-1").before(this.container).on("click.select2",p),this.container.data("select2",this),this.dropdown=this.container.find(".select2-drop"),s(this.dropdown,this.opts.element,this.opts.adaptDropdownCssClass),this.dropdown.addClass(z(c.dropdownCssClass,this.opts.element)),this.dropdown.data("select2",this),this.dropdown.on("click",p),this.results=d=this.container.find(g),this.search=e=this.container.find("input.select2-input"),this.queryCount=0,this.resultsPage=0,this.context=null,this.initContainer(),this.container.on("click",p),k(this.results),this.dropdown.on("mousemove-filtered",g,this.bind(this.highlightUnderEvent)),this.dropdown.on("touchstart touchmove touchend",g,this.bind(function(a){this._touchEvent=!0,this.highlightUnderEvent(a)})),this.dropdown.on("touchmove",g,this.bind(this.touchMoved)),this.dropdown.on("touchstart touchend",g,this.bind(this.clearTouchMoved)),this.dropdown.on("click",this.bind(function(a){this._touchEvent&&(this._touchEvent=!1,this.selectHighlighted())})),m(80,this.results),this.dropdown.on("scroll-debounced",g,this.bind(this.loadMoreIfNeeded)),a(this.container).on("change",".select2-input",function(a){a.stopPropagation()}),a(this.dropdown).on("change",".select2-input",function(a){a.stopPropagation()}),a.fn.mousewheel&&d.mousewheel(function(a,b,c,e){var f=d.scrollTop();e>0&&f-e<=0?(d.scrollTop(0),p(a)):e<0&&d.get(0).scrollHeight-d.scrollTop()+e<=d.height()&&(d.scrollTop(d.get(0).scrollHeight-d.height()),p(a))}),j(e),e.on("keyup-change input paste",this.bind(this.updateResults)),e.on("focus",function(){e.addClass("select2-focused")}),e.on("blur",function(){e.removeClass("select2-focused")}),this.dropdown.on("mouseup",g,this.bind(function(b){a(b.target).closest(".select2-result-selectable").length>0&&(this.highlightUnderEvent(b),this.selectHighlighted(b))})),this.dropdown.on("click mouseup mousedown touchstart touchend focusin",function(a){a.stopPropagation()}),this.lastSearchTerm=b,a.isFunction(this.opts.initSelection)&&(this.initSelection(),this.monitorSource()),null!==c.maximumInputLength&&this.search.attr("maxlength",c.maximumInputLength);var h=c.element.prop("disabled");h===b&&(h=!1),this.enable(!h);var i=c.element.prop("readonly");i===b&&(i=!1),this.readonly(i),K=K||f(),this.autofocus=c.element.prop("autofocus"),c.element.prop("autofocus",!1),this.autofocus&&this.focus(),this.search.attr("placeholder",c.searchInputPlaceholder)},destroy:function(){var a=this.opts.element,c=a.data("select2"),d=this;this.close(),a.length&&a[0].detachEvent&&d._sync&&a.each(function(){d._sync&&this.detachEvent("onpropertychange",d._sync)}),this.propertyObserver&&(this.propertyObserver.disconnect(),this.propertyObserver=null),this._sync=null,c!==b&&(c.container.remove(),c.liveRegion.remove(),c.dropdown.remove(),a.removeData("select2").off(".select2"),a.is("input[type='hidden']")?a.css("display",""):(a.show().prop("autofocus",this.autofocus||!1),this.elementTabIndex?a.attr({tabindex:this.elementTabIndex}):a.removeAttr("tabindex"),a.show())),C.call(this,"container","liveRegion","dropdown","results","search")},optionToData:function(a){return a.is("option")?{id:a.prop("value"),text:a.text(),element:a.get(),css:a.attr("class"),disabled:a.prop("disabled"),locked:g(a.attr("locked"),"locked")||g(a.data("locked"),!0)}:a.is("optgroup")?{text:a.attr("label"),children:[],element:a.get(),css:a.attr("class")}:void 0},prepareOpts:function(c){var d,e,f,i,j=this;if(d=c.element,"select"===d.get(0).tagName.toLowerCase()&&(this.select=e=c.element),e&&a.each(["id","multiple","ajax","query","createSearchChoice","initSelection","data","tags"],function(){if(this in c)throw new Error("Option '"+this+"' is not allowed for Select2 when attached to a ","
    "," ","
      ","
    ","
    "].join(""));return b},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.focusser.prop("disabled",!this.isInterfaceEnabled())},opening:function(){var b,c,d;this.opts.minimumResultsForSearch>=0&&this.showSearch(!0),this.parent.opening.apply(this,arguments),this.showSearchInput!==!1&&this.search.val(this.focusser.val()),this.opts.shouldFocusInput(this)&&(this.search.focus(),b=this.search.get(0),b.createTextRange?(c=b.createTextRange(),c.collapse(!1),c.select()):b.setSelectionRange&&(d=this.search.val().length,b.setSelectionRange(d,d))),this.prefillNextSearchTerm(),this.focusser.prop("disabled",!0).val(""),this.updateResults(!0),this.opts.element.trigger(a.Event("select2-open"))},close:function(){this.opened()&&(this.parent.close.apply(this,arguments),this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus())},focus:function(){this.opened()?this.close():(this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus())},isFocused:function(){return this.container.hasClass("select2-container-active")},cancel:function(){this.parent.cancel.apply(this,arguments),this.focusser.prop("disabled",!1),this.opts.shouldFocusInput(this)&&this.focusser.focus()},destroy:function(){a("label[for='"+this.focusser.attr("id")+"']").attr("for",this.opts.element.attr("id")),this.parent.destroy.apply(this,arguments),C.call(this,"selection","focusser")},initContainer:function(){var b,d,e=this.container,f=this.dropdown,g=H();this.opts.minimumResultsForSearch<0?this.showSearch(!1):this.showSearch(!0),this.selection=b=e.find(".select2-choice"),this.focusser=e.find(".select2-focusser"),b.find(".select2-chosen").attr("id","select2-chosen-"+g),this.focusser.attr("aria-labelledby","select2-chosen-"+g),this.results.attr("id","select2-results-"+g),this.search.attr("aria-owns","select2-results-"+g),this.focusser.attr("id","s2id_autogen"+g),d=a("label[for='"+this.opts.element.attr("id")+"']"),this.opts.element.on("focus.select2",this.bind(function(){this.focus()})),this.focusser.prev().text(d.text()).attr("for",this.focusser.attr("id"));var h=this.opts.element.attr("title");this.opts.element.attr("title",h||d.text()),this.focusser.attr("tabindex",this.elementTabIndex),this.search.attr("id",this.focusser.attr("id")+"_search"),this.search.prev().text(a("label[for='"+this.focusser.attr("id")+"']").text()).attr("for",this.search.attr("id")),this.search.on("keydown",this.bind(function(a){if(this.isInterfaceEnabled()&&229!=a.keyCode){if(a.which===M.PAGE_UP||a.which===M.PAGE_DOWN)return void p(a);switch(a.which){case M.UP:case M.DOWN:return this.moveHighlight(a.which===M.UP?-1:1),void p(a);case M.ENTER:return this.selectHighlighted(),void p(a);case M.TAB:return void this.selectHighlighted({noFocus:!0});case M.ESC:return this.cancel(a),void p(a)}}})),this.search.on("blur",this.bind(function(a){document.activeElement===this.body.get(0)&&window.setTimeout(this.bind(function(){this.opened()&&this.results&&this.results.length>1&&this.search.focus()}),0)})),this.focusser.on("keydown",this.bind(function(a){if(this.isInterfaceEnabled()&&a.which!==M.TAB&&!M.isControl(a)&&!M.isFunctionKey(a)&&a.which!==M.ESC){if(this.opts.openOnEnter===!1&&a.which===M.ENTER)return void p(a);if(a.which==M.DOWN||a.which==M.UP||a.which==M.ENTER&&this.opts.openOnEnter){if(a.altKey||a.ctrlKey||a.shiftKey||a.metaKey)return;return this.open(),void p(a)}return a.which==M.DELETE||a.which==M.BACKSPACE?(this.opts.allowClear&&this.clear(),void p(a)):void 0}})),j(this.focusser),this.focusser.on("keyup-change input",this.bind(function(a){if(this.opts.minimumResultsForSearch>=0){if(a.stopPropagation(),this.opened())return;this.open()}})),b.on("mousedown touchstart","abbr",this.bind(function(a){this.isInterfaceEnabled()&&(this.clear(),q(a),this.close(),this.selection&&this.selection.focus())})),this.supportsTouchEvents?b.on("mousedown touchstart",this.bind(function(d){c(b),this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.opened()?this.close():this.isInterfaceEnabled()&&this.open(),p(d)})):b.on("mousedown",this.bind(function(d){c(b),this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.opened()?this.close():this.isInterfaceEnabled()&&this.open(),p(d)})),f.on("mousedown touchstart",this.bind(function(){this.opts.shouldFocusInput(this)&&this.search.focus()})),b.on("focus",this.bind(function(a){p(a)})),this.focusser.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active")})).on("blur",this.bind(function(){this.opened()||(this.container.removeClass("select2-container-active"),this.opts.element.trigger(a.Event("select2-blur")))})),this.search.on("focus",this.bind(function(){this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active")})),this.initContainerWidth(),this.opts.element.hide(),this.setPlaceholder()},clear:function(b){var c=this.selection.data("select2-data");if(c){var d=a.Event("select2-clearing");if(this.opts.element.trigger(d),d.isDefaultPrevented())return;var e=this.getPlaceholderOption();this.opts.element.val(e?e.val():""),this.selection.find(".select2-chosen").empty(),this.selection.removeData("select2-data"),this.setPlaceholder(),b!==!1&&(this.opts.element.trigger({type:"select2-removed",val:this.id(c),choice:c}),this.triggerChange({removed:c}))}},initSelection:function(){if(this.isPlaceholderOptionSelected())this.updateSelection(null),this.close(),this.setPlaceholder();else{var a=this;this.opts.initSelection.call(null,this.opts.element,function(c){c!==b&&null!==c&&(a.updateSelection(c),a.close(),a.setPlaceholder(),a.lastSearchTerm=a.search.val())})}},isPlaceholderOptionSelected:function(){var a;return this.getPlaceholder()!==b&&((a=this.getPlaceholderOption())!==b&&a.prop("selected")||""===this.opts.element.val()||this.opts.element.val()===b||null===this.opts.element.val())},prepareOpts:function(){var b=this.parent.prepareOpts.apply(this,arguments),c=this;return"select"===b.element.get(0).tagName.toLowerCase()?b.initSelection=function(a,b){var d=a.find("option").filter(function(){return this.selected&&!this.disabled});b(c.optionToData(d))}:"data"in b&&(b.initSelection=b.initSelection||function(c,d){var e=c.val(),f=null;b.query({matcher:function(a,c,d){var h=g(e,b.id(d));return h&&(f=d),h},callback:a.isFunction(d)?function(){d(f)}:a.noop})}),b},getPlaceholder:function(){return this.select&&this.getPlaceholderOption()===b?b:this.parent.getPlaceholder.apply(this,arguments)},setPlaceholder:function(){var a=this.getPlaceholder();if(this.isPlaceholderOptionSelected()&&a!==b){if(this.select&&this.getPlaceholderOption()===b)return;this.selection.find(".select2-chosen").html(this.opts.escapeMarkup(a)),this.selection.addClass("select2-default"),this.container.removeClass("select2-allowclear")}},postprocessResults:function(a,b,c){var d=0,e=this;if(this.findHighlightableChoices().each2(function(a,b){if(g(e.id(b.data("select2-data")),e.opts.element.val()))return d=a,!1}),c!==!1&&(b===!0&&d>=0?this.highlight(d):this.highlight(0)),b===!0){var f=this.opts.minimumResultsForSearch;f>=0&&this.showSearch(A(a.results)>=f)}},showSearch:function(b){this.showSearchInput!==b&&(this.showSearchInput=b,this.dropdown.find(".select2-search").toggleClass("select2-search-hidden",!b),this.dropdown.find(".select2-search").toggleClass("select2-offscreen",!b),a(this.dropdown,this.container).toggleClass("select2-with-searchbox",b))},onSelect:function(a,b){if(this.triggerSelect(a)){var c=this.opts.element.val(),d=this.data();this.opts.element.val(this.id(a)),this.updateSelection(a),this.opts.element.trigger({type:"select2-selected",val:this.id(a),choice:a}),this.lastSearchTerm=this.search.val(),this.close(),b&&b.noFocus||!this.opts.shouldFocusInput(this)||this.focusser.focus(),g(c,this.id(a))||this.triggerChange({added:a,removed:d})}},updateSelection:function(a){var c,d,e=this.selection.find(".select2-chosen");this.selection.data("select2-data",a),e.empty(),null!==a&&(c=this.opts.formatSelection(a,e,this.opts.escapeMarkup)),c!==b&&e.append(c),d=this.opts.formatSelectionCssClass(a,e),d!==b&&e.addClass(d),this.selection.removeClass("select2-default"),this.opts.allowClear&&this.getPlaceholder()!==b&&this.container.addClass("select2-allowclear")},val:function(){var a,c=!1,d=null,e=this,f=this.data();if(0===arguments.length)return this.opts.element.val();if(a=arguments[0],arguments.length>1&&(c=arguments[1],this.opts.debug&&console&&console.warn&&console.warn('Select2: The second option to `select2("val")` is not supported in Select2 4.0.0. The `change` event will always be triggered in 4.0.0.')),this.select)this.opts.debug&&console&&console.warn&&console.warn('Select2: Setting the value on a "," ","","
    ","
      ","
    ","
    "].join(""));return b},prepareOpts:function(){var b=this.parent.prepareOpts.apply(this,arguments),c=this;return"select"===b.element.get(0).tagName.toLowerCase()?b.initSelection=function(a,b){var d=[];a.find("option").filter(function(){return this.selected&&!this.disabled}).each2(function(a,b){d.push(c.optionToData(b))}),b(d)}:"data"in b&&(b.initSelection=b.initSelection||function(c,d){var e=h(c.val(),b.separator,b.transformVal),f=[];b.query({matcher:function(c,d,h){var i=a.grep(e,function(a){return g(a,b.id(h))}).length;return i&&f.push(h),i},callback:a.isFunction(d)?function(){for(var a=[],c=0;c0||(this.selectChoice(null),this.clearPlaceholder(),this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.open(),this.focusSearch(),b.preventDefault()))})),this.container.on("focus",c,this.bind(function(){this.isInterfaceEnabled()&&(this.container.hasClass("select2-container-active")||this.opts.element.trigger(a.Event("select2-focus")),this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"),this.clearPlaceholder())})),this.initContainerWidth(),this.opts.element.hide(),this.clearSearch()},enableInterface:function(){this.parent.enableInterface.apply(this,arguments)&&this.search.prop("disabled",!this.isInterfaceEnabled())},initSelection:function(){if(""===this.opts.element.val()&&""===this.opts.element.text()&&(this.updateSelection([]),this.close(),this.clearSearch()),this.select||""!==this.opts.element.val()){var a=this;this.opts.initSelection.call(null,this.opts.element,function(c){c!==b&&null!==c&&(a.updateSelection(c),a.close(),a.clearSearch())})}},clearSearch:function(){var a=this.getPlaceholder(),c=this.getMaxSearchWidth();a!==b&&0===this.getVal().length&&this.search.hasClass("select2-focused")===!1?(this.search.val(a).addClass("select2-default"),this.search.width(c>0?c:this.container.css("width"))):this.search.val("").width(10)},clearPlaceholder:function(){this.search.hasClass("select2-default")&&this.search.val("").removeClass("select2-default")},opening:function(){this.clearPlaceholder(),this.resizeSearch(),this.parent.opening.apply(this,arguments),this.focusSearch(),this.prefillNextSearchTerm(),this.updateResults(!0),this.opts.shouldFocusInput(this)&&this.search.focus(),this.opts.element.trigger(a.Event("select2-open"))},close:function(){this.opened()&&this.parent.close.apply(this,arguments)},focus:function(){this.close(),this.search.focus()},isFocused:function(){return this.search.hasClass("select2-focused")},updateSelection:function(b){var c={},d=[],e=this;a(b).each(function(){e.id(this)in c||(c[e.id(this)]=0,d.push(this))}),this.selection.find(".select2-search-choice").remove(),this.addSelectedChoice(d),e.postprocessResults()},tokenize:function(){var a=this.search.val();a=this.opts.tokenizer.call(this,a,this.data(),this.bind(this.onSelect),this.opts),null!=a&&a!=b&&(this.search.val(a),a.length>0&&this.open())},onSelect:function(a,b){this.triggerSelect(a)&&""!==a.text&&(this.addSelectedChoice(a),this.opts.element.trigger({type:"selected",val:this.id(a),choice:a}),this.lastSearchTerm=this.search.val(),this.clearSearch(),this.updateResults(),!this.select&&this.opts.closeOnSelect||this.postprocessResults(a,!1,this.opts.closeOnSelect===!0),this.opts.closeOnSelect?(this.close(),this.search.width(10)):this.countSelectableResults()>0?(this.search.width(10),this.resizeSearch(),this.getMaximumSelectionSize()>0&&this.val().length>=this.getMaximumSelectionSize()?this.updateResults(!0):this.prefillNextSearchTerm()&&this.updateResults(),this.positionDropdown()):(this.close(),this.search.width(10)),this.triggerChange({added:a}),b&&b.noFocus||this.focusSearch())},cancel:function(){this.close(),this.focusSearch()},addSelectedChoice:function(b){var c=this.getVal(),d=this;a(b).each(function(){c.push(d.createChoice(this))}),this.setVal(c)},createChoice:function(c){var d,e,f=!c.locked,g=a("
  • "),h=a("
  • "),i=f?g:h,j=this.id(c);return d=this.opts.formatSelection(c,i.find("div"),this.opts.escapeMarkup),d!=b&&i.find("div").replaceWith(a("
    ").html(d)),e=this.opts.formatSelectionCssClass(c,i.find("div")),e!=b&&i.addClass(e),f&&i.find(".select2-search-choice-close").on("mousedown",p).on("click dblclick",this.bind(function(b){this.isInterfaceEnabled()&&(this.unselect(a(b.target)),this.selection.find(".select2-search-choice-focus").removeClass("select2-search-choice-focus"),p(b),this.close(),this.focusSearch())})).on("focus",this.bind(function(){this.isInterfaceEnabled()&&(this.container.addClass("select2-container-active"),this.dropdown.addClass("select2-drop-active"))})),i.data("select2-data",c),i.insertBefore(this.searchContainer),j},unselect:function(b){var c,d,f=this.getVal();if(b=b.closest(".select2-search-choice"),0===b.length)throw"Invalid argument: "+b+". Must be .select2-search-choice";if(c=b.data("select2-data")){var g=a.Event("select2-removing");if(g.val=this.id(c),g.choice=c,this.opts.element.trigger(g),g.isDefaultPrevented())return!1;for(;(d=e(this.id(c),f))>=0;)f.splice(d,1),this.setVal(f),this.select&&this.postprocessResults();return b.remove(),this.opts.element.trigger({type:"select2-removed",val:this.id(c),choice:c}),this.triggerChange({removed:c}),!0}},postprocessResults:function(a,b,c){var d=this.getVal(),f=this.results.find(".select2-result"),g=this.results.find(".select2-result-with-children"),h=this;f.each2(function(a,b){var c=h.id(b.data("select2-data"));e(c,d)>=0&&(b.addClass("select2-selected"),b.find(".select2-result-selectable").addClass("select2-selected"))}),g.each2(function(a,b){b.is(".select2-result-selectable")||0!==b.find(".select2-result-selectable:not(.select2-selected)").length||b.addClass("select2-selected")}),this.highlight()==-1&&c!==!1&&this.opts.closeOnSelect===!0&&h.highlight(0),!this.opts.createSearchChoice&&!f.filter(".select2-result:not(.select2-selected)").length>0&&(!a||a&&!a.more&&0===this.results.find(".select2-no-results").length)&&y(h.opts.formatNoMatches,"formatNoMatches")&&this.results.append("
  • "+z(h.opts.formatNoMatches,h.opts.element,h.search.val())+"
  • ")},getMaxSearchWidth:function(){return this.selection.width()-i(this.search)},resizeSearch:function(){var a,b,c,d,e,f=i(this.search);a=r(this.search)+10,b=this.search.offset().left,c=this.selection.width(),d=this.selection.offset().left,e=c-(b-d)-f,e. Attach to instead.");this.search.width(0),this.searchContainer.hide()},onSortEnd:function(){var b=[],c=this;this.searchContainer.show(),this.searchContainer.appendTo(this.searchContainer.parent()),this.resizeSearch(),this.selection.find(".select2-search-choice").each(function(){b.push(c.opts.id(a(this).data("select2-data")))}),this.setVal(b),this.triggerChange()},data:function(b,c){var d,e,f=this;return 0===arguments.length?this.selection.children(".select2-search-choice").map(function(){return a(this).data("select2-data")}).get():(e=this.data(),b||(b=[]),d=a.map(b,function(a){return f.opts.id(a)}),this.setVal(d),this.updateSelection(b),this.clearSearch(),c&&this.triggerChange(this.buildChangeDetails(e,this.data())),void 0)}}),a.fn.select2=function(){var c,d,f,g,h,i=Array.prototype.slice.call(arguments,0),j=["val","destroy","opened","open","close","focus","isFocused","container","dropdown","onSortStart","onSortEnd","enable","disable","readonly","positionDropdown","data","search"],k=["opened","isFocused","container","dropdown"],l=["val","data"],m={search:"externalSearch"};return this.each(function(){if(0===i.length||"object"==typeof i[0])c=0===i.length?{}:a.extend({},i[0]),c.element=a(this),"select"===c.element.get(0).tagName.toLowerCase()?h=c.element.prop("multiple"):(h=c.multiple||!1,"tags"in c&&(c.multiple=h=!0)),d=h?new window.Select2["class"].multi:new window.Select2["class"].single,d.init(c);else{if("string"!=typeof i[0])throw"Invalid arguments to select2 plugin: "+i;if(e(i[0],j)<0)throw"Unknown method: "+i[0];if(g=b,d=a(this).data("select2"),d===b)return;if(f=i[0],"container"===f?g=d.container:"dropdown"===f?g=d.dropdown:(m[f]&&(f=m[f]),g=d[f].apply(d,i.slice(1))),e(i[0],k)>=0||e(i[0],l)>=0&&1==i.length)return!1}}),g===b?this:g},a.fn.select2.defaults={debug:!1,width:"copy",loadMorePadding:0,closeOnSelect:!0,openOnEnter:!0,containerCss:{},dropdownCss:{},containerCssClass:"",dropdownCssClass:"",formatResult:function(a,b,c,d){var e=[];return t(this.text(a),c.term,e,d),e.join("")},transformVal:function(b){return a.trim(b)},formatSelection:function(a,c,d){return a?d(this.text(a)):b},sortResults:function(a,b,c){return a},formatResultCssClass:function(a){return a.css},formatSelectionCssClass:function(a,c){return b},minimumResultsForSearch:0,minimumInputLength:0,maximumInputLength:null,maximumSelectionSize:0,id:function(a){return a==b?null:a.id},text:function(b){return b&&this.data&&this.data.text?a.isFunction(this.data.text)?this.data.text(b):b[this.data.text]:b.text},matcher:function(a,b){return d(""+b).toUpperCase().indexOf(d(""+a).toUpperCase())>=0},separator:",",tokenSeparators:[],tokenizer:B,escapeMarkup:u,blurOnChange:!1,selectOnBlur:!1,adaptContainerCssClass:function(a){return a},adaptDropdownCssClass:function(a){return null},nextSearchTerm:function(a,c){return b},searchInputPlaceholder:"",createSearchChoicePosition:"top",shouldFocusInput:function(a){ +var b="ontouchstart"in window||navigator.msMaxTouchPoints>0;return!b||!(a.opts.minimumResultsForSearch<0)}},a.fn.select2.locales=[],a.fn.select2.locales.en={formatMatches:function(a){return 1===a?"One result is available, press enter to select it.":a+" results are available, use up and down arrow keys to navigate."},formatNoMatches:function(){return"No matches found"},formatAjaxError:function(a,b,c){return"Loading failed"},formatInputTooShort:function(a,b){var c=b-a.length;return"Please enter "+c+" or more character"+(1==c?"":"s")},formatInputTooLong:function(a,b){var c=a.length-b;return"Please delete "+c+" character"+(1==c?"":"s")},formatSelectionTooBig:function(a){return"You can only select "+a+" item"+(1==a?"":"s")},formatLoadMore:function(a){return"Loading more results…"},formatSearching:function(){return"Searching…"}},a.extend(a.fn.select2.defaults,a.fn.select2.locales.en),a.fn.select2.ajaxDefaults={transport:a.ajax,params:{type:"GET",cache:!1,dataType:"json"}},window.Select2={query:{ajax:v,local:w,tags:x},util:{debounce:l,markMatch:t,escapeMarkup:u,stripDiacritics:d},"class":{"abstract":E,single:F,multi:G}}}}(jQuery); \ No newline at end of file diff --git a/assets/js/zeroclipboard/jquery.zeroclipboard.min.js b/assets/js/zeroclipboard/jquery.zeroclipboard.min.js index 6f77845220e..cb50c94cc34 100644 --- a/assets/js/zeroclipboard/jquery.zeroclipboard.min.js +++ b/assets/js/zeroclipboard/jquery.zeroclipboard.min.js @@ -14,4 +14,4 @@ * http://zeroclipboard.org/ * v2.1.2 */ -!function(a,b){var c,e=a,f=e.document,g=e.navigator,h=e.setTimeout,i=e.encodeURIComponent,j=e.ActiveXObject,k=e.Number.parseInt||e.parseInt,l=e.Number.parseFloat||e.parseFloat,m=e.Number.isNaN||e.isNaN,n=e.Math.round,o=e.Date.now,p=e.Object.keys,q=e.Object.defineProperty,r=e.Object.prototype.hasOwnProperty,s=e.Array.prototype.slice,t=function(a){return s.call(a,0)},u=function(){var a,c,d,e,f,g,h=t(arguments),i=h[0]||{};for(a=1,c=h.length;c>a;a++)if(null!=(d=h[a]))for(e in d)r.call(d,e)&&(f=i[e],g=d[e],i!==g&&g!==b&&(i[e]=g));return i},v=function(a){var b,c,d,e;if("object"!=typeof a||null==a)b=a;else if("number"==typeof a.length)for(b=[],c=0,d=a.length;d>c;c++)r.call(a,c)&&(b[c]=v(a[c]));else{b={};for(e in a)r.call(a,e)&&(b[e]=v(a[e]))}return b},w=function(a,b){for(var c={},d=0,e=b.length;e>d;d++)b[d]in a&&(c[b[d]]=a[b[d]]);return c},x=function(a,b){var c={};for(var d in a)-1===b.indexOf(d)&&(c[d]=a[d]);return c},y=function(a){if(a)for(var b in a)r.call(a,b)&&delete a[b];return a},z=function(a,b){if(a&&1===a.nodeType&&a.ownerDocument&&b&&(1===b.nodeType&&b.ownerDocument&&b.ownerDocument===a.ownerDocument||9===b.nodeType&&!b.ownerDocument&&b===a.ownerDocument))do{if(a===b)return!0;a=a.parentNode}while(a);return!1},A={bridge:null,version:"0.0.0",pluginType:"unknown",disabled:null,outdated:null,unavailable:null,deactivated:null,overdue:null,ready:null},B="11.0.0",C={},D={},E=null,F={ready:"Flash communication is established",error:{"flash-disabled":"Flash is disabled or not installed","flash-outdated":"Flash is too outdated to support ZeroClipboard","flash-unavailable":"Flash is unable to communicate bidirectionally with JavaScript","flash-deactivated":"Flash is too outdated for your browser and/or is configured as click-to-activate","flash-overdue":"Flash communication was established but NOT within the acceptable time limit"}},G=function(){var a,b,c,d,e="ZeroClipboard.swf";if(!f.currentScript||!(d=f.currentScript.src)){var g=f.getElementsByTagName("script");if("readyState"in g[0])for(a=g.length;a--&&("interactive"!==g[a].readyState||!(d=g[a].src)););else if("loading"===f.readyState)d=g[g.length-1].src;else{for(a=g.length;a--;){if(c=g[a].src,!c){b=null;break}if(c=c.split("#")[0].split("?")[0],c=c.slice(0,c.lastIndexOf("/")+1),null==b)b=c;else if(b!==c){b=null;break}}null!==b&&(d=b)}}return d&&(d=d.split("#")[0].split("?")[0],e=d.slice(0,d.lastIndexOf("/")+1)+e),e}(),H={swfPath:G,trustedDomains:a.location.host?[a.location.host]:[],cacheBust:!0,forceEnhancedClipboard:!1,flashLoadTimeout:3e4,autoActivate:!0,bubbleEvents:!0,containerId:"global-zeroclipboard-html-bridge",containerClass:"global-zeroclipboard-container",swfObjectId:"global-zeroclipboard-flash-bridge",hoverClass:"zeroclipboard-is-hover",activeClass:"zeroclipboard-is-active",forceHandCursor:!1,title:null,zIndex:999999999},I=function(a){if("object"==typeof a&&null!==a)for(var b in a)if(r.call(a,b))if(/^(?:forceHandCursor|title|zIndex|bubbleEvents)$/.test(b))H[b]=a[b];else if(null==A.bridge)if("containerId"===b||"swfObjectId"===b){if(!X(a[b]))throw new Error("The specified `"+b+"` value is not valid as an HTML4 Element ID");H[b]=a[b]}else H[b]=a[b];{if("string"!=typeof a||!a)return v(H);if(r.call(H,a))return H[a]}},J=function(){return{browser:w(g,["userAgent","platform","appName"]),flash:x(A,["bridge"]),zeroclipboard:{version:ya.version,config:ya.config()}}},K=function(){return!!(A.disabled||A.outdated||A.unavailable||A.deactivated)},L=function(a,b){var c,d,e,f={};if("string"==typeof a&&a)e=a.toLowerCase().split(/\s+/);else if("object"==typeof a&&a&&"undefined"==typeof b)for(c in a)r.call(a,c)&&"string"==typeof c&&c&&"function"==typeof a[c]&&ya.on(c,a[c]);if(e&&e.length){for(c=0,d=e.length;d>c;c++)a=e[c].replace(/^on/,""),f[a]=!0,C[a]||(C[a]=[]),C[a].push(b);if(f.ready&&A.ready&&ya.emit({type:"ready"}),f.error){var g=["disabled","outdated","unavailable","deactivated","overdue"];for(c=0,d=g.length;d>c;c++)if(A[g[c]]===!0){ya.emit({type:"error",name:"flash-"+g[c]});break}}}return ya},M=function(a,b){var c,d,e,f,g;if(0===arguments.length)f=p(C);else if("string"==typeof a&&a)f=a.split(/\s+/);else if("object"==typeof a&&a&&"undefined"==typeof b)for(c in a)r.call(a,c)&&"string"==typeof c&&c&&"function"==typeof a[c]&&ya.off(c,a[c]);if(f&&f.length)for(c=0,d=f.length;d>c;c++)if(a=f[c].toLowerCase().replace(/^on/,""),g=C[a],g&&g.length)if(b)for(e=g.indexOf(b);-1!==e;)g.splice(e,1),e=g.indexOf(b,e);else g.length=0;return ya},N=function(a){var b;return b="string"==typeof a&&a?v(C[a])||null:v(C)},O=function(a){var b,c,d;return a=Y(a),a&&!ca(a)?"ready"===a.type&&A.overdue===!0?ya.emit({type:"error",name:"flash-overdue"}):(b=u({},a),ba.call(this,b),"copy"===a.type&&(d=ia(D),c=d.data,E=d.formatMap),c):void 0},P=function(){if("boolean"!=typeof A.ready&&(A.ready=!1),!ya.isFlashUnusable()&&null===A.bridge){var a=H.flashLoadTimeout;"number"==typeof a&&a>=0&&h(function(){"boolean"!=typeof A.deactivated&&(A.deactivated=!0),A.deactivated===!0&&ya.emit({type:"error",name:"flash-deactivated"})},a),A.overdue=!1,ga()}},Q=function(){ya.clearData(),ya.blur(),ya.emit("destroy"),ha(),ya.off()},R=function(a,b){var c;if("object"==typeof a&&a&&"undefined"==typeof b)c=a,ya.clearData();else{if("string"!=typeof a||!a)return;c={},c[a]=b}for(var d in c)"string"==typeof d&&d&&r.call(c,d)&&"string"==typeof c[d]&&c[d]&&(D[d]=c[d])},S=function(a){"undefined"==typeof a?(y(D),E=null):"string"==typeof a&&r.call(D,a)&&delete D[a]},T=function(a){return"undefined"==typeof a?v(D):"string"==typeof a&&r.call(D,a)?D[a]:void 0},U=function(a){if(a&&1===a.nodeType){c&&(qa(c,H.activeClass),c!==a&&qa(c,H.hoverClass)),c=a,pa(a,H.hoverClass);var b=a.getAttribute("title")||H.title;if("string"==typeof b&&b){var d=fa(A.bridge);d&&d.setAttribute("title",b)}var e=H.forceHandCursor===!0||"pointer"===ra(a,"cursor");va(e),ua()}},V=function(){var a=fa(A.bridge);a&&(a.removeAttribute("title"),a.style.left="0px",a.style.top="-9999px",a.style.width="1px",a.style.top="1px"),c&&(qa(c,H.hoverClass),qa(c,H.activeClass),c=null)},W=function(){return c||null},X=function(a){return"string"==typeof a&&a&&/^[A-Za-z][A-Za-z0-9_:\-\.]*$/.test(a)},Y=function(a){var b;if("string"==typeof a&&a?(b=a,a={}):"object"==typeof a&&a&&"string"==typeof a.type&&a.type&&(b=a.type),b){u(a,{type:b.toLowerCase(),target:a.target||c||null,relatedTarget:a.relatedTarget||null,currentTarget:A&&A.bridge||null,timeStamp:a.timeStamp||o()||null});var d=F[a.type];return"error"===a.type&&a.name&&d&&(d=d[a.name]),d&&(a.message=d),"ready"===a.type&&u(a,{target:null,version:A.version}),"error"===a.type&&(/^flash-(disabled|outdated|unavailable|deactivated|overdue)$/.test(a.name)&&u(a,{target:null,minimumVersion:B}),/^flash-(outdated|unavailable|deactivated|overdue)$/.test(a.name)&&u(a,{version:A.version})),"copy"===a.type&&(a.clipboardData={setData:ya.setData,clearData:ya.clearData}),"aftercopy"===a.type&&(a=ja(a,E)),a.target&&!a.relatedTarget&&(a.relatedTarget=Z(a.target)),a=$(a)}},Z=function(a){var b=a&&a.getAttribute&&a.getAttribute("data-clipboard-target");return b?f.getElementById(b):null},$=function(a){if(a&&/^_(?:click|mouse(?:over|out|down|up|move))$/.test(a.type)){var c=a.target,d="_mouseover"===a.type&&a.relatedTarget?a.relatedTarget:b,g="_mouseout"===a.type&&a.relatedTarget?a.relatedTarget:b,h=ta(c),i=e.screenLeft||e.screenX||0,j=e.screenTop||e.screenY||0,k=f.body.scrollLeft+f.documentElement.scrollLeft,l=f.body.scrollTop+f.documentElement.scrollTop,m=h.left+("number"==typeof a._stageX?a._stageX:0),n=h.top+("number"==typeof a._stageY?a._stageY:0),o=m-k,p=n-l,q=i+o,r=j+p,s="number"==typeof a.movementX?a.movementX:0,t="number"==typeof a.movementY?a.movementY:0;delete a._stageX,delete a._stageY,u(a,{srcElement:c,fromElement:d,toElement:g,screenX:q,screenY:r,pageX:m,pageY:n,clientX:o,clientY:p,x:o,y:p,movementX:s,movementY:t,offsetX:0,offsetY:0,layerX:0,layerY:0})}return a},_=function(a){var b=a&&"string"==typeof a.type&&a.type||"";return!/^(?:(?:before)?copy|destroy)$/.test(b)},aa=function(a,b,c,d){d?h(function(){a.apply(b,c)},0):a.apply(b,c)},ba=function(a){if("object"==typeof a&&a&&a.type){var b=_(a),c=C["*"]||[],d=C[a.type]||[],f=c.concat(d);if(f&&f.length){var g,h,i,j,k,l=this;for(g=0,h=f.length;h>g;g++)i=f[g],j=l,"string"==typeof i&&"function"==typeof e[i]&&(i=e[i]),"object"==typeof i&&i&&"function"==typeof i.handleEvent&&(j=i,i=i.handleEvent),"function"==typeof i&&(k=u({},a),aa(i,j,[k],b))}return this}},ca=function(a){var b=a.target||c||null,d="swf"===a._source;delete a._source;var e=["flash-disabled","flash-outdated","flash-unavailable","flash-deactivated","flash-overdue"];switch(a.type){case"error":-1!==e.indexOf(a.name)&&u(A,{disabled:"flash-disabled"===a.name,outdated:"flash-outdated"===a.name,unavailable:"flash-unavailable"===a.name,deactivated:"flash-deactivated"===a.name,overdue:"flash-overdue"===a.name,ready:!1});break;case"ready":var f=A.deactivated===!0;u(A,{disabled:!1,outdated:!1,unavailable:!1,deactivated:!1,overdue:f,ready:!f});break;case"copy":var g,h,i=a.relatedTarget;!D["text/html"]&&!D["text/plain"]&&i&&(h=i.value||i.outerHTML||i.innerHTML)&&(g=i.value||i.textContent||i.innerText)?(a.clipboardData.clearData(),a.clipboardData.setData("text/plain",g),h!==g&&a.clipboardData.setData("text/html",h)):!D["text/plain"]&&a.target&&(g=a.target.getAttribute("data-clipboard-text"))&&(a.clipboardData.clearData(),a.clipboardData.setData("text/plain",g));break;case"aftercopy":ya.clearData(),b&&b!==oa()&&b.focus&&b.focus();break;case"_mouseover":ya.focus(b),H.bubbleEvents===!0&&d&&(b&&b!==a.relatedTarget&&!z(a.relatedTarget,b)&&da(u({},a,{type:"mouseenter",bubbles:!1,cancelable:!1})),da(u({},a,{type:"mouseover"})));break;case"_mouseout":ya.blur(),H.bubbleEvents===!0&&d&&(b&&b!==a.relatedTarget&&!z(a.relatedTarget,b)&&da(u({},a,{type:"mouseleave",bubbles:!1,cancelable:!1})),da(u({},a,{type:"mouseout"})));break;case"_mousedown":pa(b,H.activeClass),H.bubbleEvents===!0&&d&&da(u({},a,{type:a.type.slice(1)}));break;case"_mouseup":qa(b,H.activeClass),H.bubbleEvents===!0&&d&&da(u({},a,{type:a.type.slice(1)}));break;case"_click":case"_mousemove":H.bubbleEvents===!0&&d&&da(u({},a,{type:a.type.slice(1)}))}return/^_(?:click|mouse(?:over|out|down|up|move))$/.test(a.type)?!0:void 0},da=function(a){if(a&&"string"==typeof a.type&&a){var b,c=a.target||null,d=c&&c.ownerDocument||f,g={view:d.defaultView||e,canBubble:!0,cancelable:!0,detail:"click"===a.type?1:0,button:"number"==typeof a.which?a.which-1:"number"==typeof a.button?a.button:d.createEvent?0:1},h=u(g,a);c&&d.createEvent&&c.dispatchEvent&&(h=[h.type,h.canBubble,h.cancelable,h.view,h.detail,h.screenX,h.screenY,h.clientX,h.clientY,h.ctrlKey,h.altKey,h.shiftKey,h.metaKey,h.button,h.relatedTarget],b=d.createEvent("MouseEvents"),b.initMouseEvent&&(b.initMouseEvent.apply(b,h),b._source="js",c.dispatchEvent(b)))}},ea=function(){var a=f.createElement("div");return a.id=H.containerId,a.className=H.containerClass,a.style.position="absolute",a.style.left="0px",a.style.top="-9999px",a.style.width="1px",a.style.height="1px",a.style.zIndex=""+wa(H.zIndex),a},fa=function(a){for(var b=a&&a.parentNode;b&&"OBJECT"===b.nodeName&&b.parentNode;)b=b.parentNode;return b||null},ga=function(){var a,b=A.bridge,c=fa(b);if(!b){var d=na(e.location.host,H),g="never"===d?"none":"all",h=la(H),i=H.swfPath+ka(H.swfPath,H);c=ea();var j=f.createElement("div");c.appendChild(j),f.body.appendChild(c);var k=f.createElement("div"),l="activex"===A.pluginType;k.innerHTML='"+(l?'':"")+'',b=k.firstChild,k=null,b.ZeroClipboard=ya,c.replaceChild(b,j)}return b||(b=f[H.swfObjectId],b&&(a=b.length)&&(b=b[a-1]),!b&&c&&(b=c.firstChild)),A.bridge=b||null,b},ha=function(){var a=A.bridge;if(a){var b=fa(a);b&&("activex"===A.pluginType&&"readyState"in a?(a.style.display="none",function c(){if(4===a.readyState){for(var d in a)"function"==typeof a[d]&&(a[d]=null);a.parentNode&&a.parentNode.removeChild(a),b.parentNode&&b.parentNode.removeChild(b)}else h(c,10)}()):(a.parentNode&&a.parentNode.removeChild(a),b.parentNode&&b.parentNode.removeChild(b))),A.ready=null,A.bridge=null,A.deactivated=null}},ia=function(a){var b={},c={};if("object"==typeof a&&a){for(var d in a)if(d&&r.call(a,d)&&"string"==typeof a[d]&&a[d])switch(d.toLowerCase()){case"text/plain":case"text":case"air:text":case"flash:text":b.text=a[d],c.text=d;break;case"text/html":case"html":case"air:html":case"flash:html":b.html=a[d],c.html=d;break;case"application/rtf":case"text/rtf":case"rtf":case"richtext":case"air:rtf":case"flash:rtf":b.rtf=a[d],c.rtf=d}return{data:b,formatMap:c}}},ja=function(a,b){if("object"!=typeof a||!a||"object"!=typeof b||!b)return a;var c={};for(var d in a)if(r.call(a,d)){if("success"!==d&&"data"!==d){c[d]=a[d];continue}c[d]={};var e=a[d];for(var f in e)f&&r.call(e,f)&&r.call(b,f)&&(c[d][b[f]]=e[f])}return c},ka=function(a,b){var c=null==b||b&&b.cacheBust===!0;return c?(-1===a.indexOf("?")?"?":"&")+"noCache="+o():""},la=function(a){var b,c,d,f,g="",h=[];if(a.trustedDomains&&("string"==typeof a.trustedDomains?f=[a.trustedDomains]:"object"==typeof a.trustedDomains&&"length"in a.trustedDomains&&(f=a.trustedDomains)),f&&f.length)for(b=0,c=f.length;c>b;b++)if(r.call(f,b)&&f[b]&&"string"==typeof f[b]){if(d=ma(f[b]),!d)continue;if("*"===d){h.length=0,h.push(d);break}h.push.apply(h,[d,"//"+d,e.location.protocol+"//"+d])}return h.length&&(g+="trustedOrigins="+i(h.join(","))),a.forceEnhancedClipboard===!0&&(g+=(g?"&":"")+"forceEnhancedClipboard=true"),"string"==typeof a.swfObjectId&&a.swfObjectId&&(g+=(g?"&":"")+"swfObjectId="+i(a.swfObjectId)),g},ma=function(a){if(null==a||""===a)return null;if(a=a.replace(/^\s+|\s+$/g,""),""===a)return null;var b=a.indexOf("//");a=-1===b?a:a.slice(b+2);var c=a.indexOf("/");return a=-1===c?a:-1===b||0===c?null:a.slice(0,c),a&&".swf"===a.slice(-4).toLowerCase()?null:a||null},na=function(){var a=function(a){var b,c,d,e=[];if("string"==typeof a&&(a=[a]),"object"!=typeof a||!a||"number"!=typeof a.length)return e;for(b=0,c=a.length;c>b;b++)if(r.call(a,b)&&(d=ma(a[b]))){if("*"===d){e.length=0,e.push("*");break}-1===e.indexOf(d)&&e.push(d)}return e};return function(b,c){var d=ma(c.swfPath);null===d&&(d=b);var e=a(c.trustedDomains),f=e.length;if(f>0){if(1===f&&"*"===e[0])return"always";if(-1!==e.indexOf(b))return 1===f&&b===d?"sameDomain":"always"}return"never"}}(),oa=function(){try{return f.activeElement}catch(a){return null}},pa=function(a,b){if(!a||1!==a.nodeType)return a;if(a.classList)return a.classList.contains(b)||a.classList.add(b),a;if(b&&"string"==typeof b){var c=(b||"").split(/\s+/);if(1===a.nodeType)if(a.className){for(var d=" "+a.className+" ",e=a.className,f=0,g=c.length;g>f;f++)d.indexOf(" "+c[f]+" ")<0&&(e+=" "+c[f]);a.className=e.replace(/^\s+|\s+$/g,"")}else a.className=b}return a},qa=function(a,b){if(!a||1!==a.nodeType)return a;if(a.classList)return a.classList.contains(b)&&a.classList.remove(b),a;if("string"==typeof b&&b){var c=b.split(/\s+/);if(1===a.nodeType&&a.className){for(var d=(" "+a.className+" ").replace(/[\n\t]/g," "),e=0,f=c.length;f>e;e++)d=d.replace(" "+c[e]+" "," ");a.className=d.replace(/^\s+|\s+$/g,"")}}return a},ra=function(a,b){var c=e.getComputedStyle(a,null).getPropertyValue(b);return"cursor"!==b||c&&"auto"!==c||"A"!==a.nodeName?c:"pointer"},sa=function(){var a,b,c,d=1;return"function"==typeof f.body.getBoundingClientRect&&(a=f.body.getBoundingClientRect(),b=a.right-a.left,c=f.body.offsetWidth,d=n(b/c*100)/100),d},ta=function(a){var b={left:0,top:0,width:0,height:0};if(a.getBoundingClientRect){var c,d,g,h=a.getBoundingClientRect();"pageXOffset"in e&&"pageYOffset"in e?(c=e.pageXOffset,d=e.pageYOffset):(g=sa(),c=n(f.documentElement.scrollLeft/g),d=n(f.documentElement.scrollTop/g));var i=f.documentElement.clientLeft||0,j=f.documentElement.clientTop||0;b.left=h.left+c-i,b.top=h.top+d-j,b.width="width"in h?h.width:h.right-h.left,b.height="height"in h?h.height:h.bottom-h.top}return b},ua=function(){var a;if(c&&(a=fa(A.bridge))){var b=ta(c);u(a.style,{width:b.width+"px",height:b.height+"px",top:b.top+"px",left:b.left+"px",zIndex:""+wa(H.zIndex)})}},va=function(a){A.ready===!0&&(A.bridge&&"function"==typeof A.bridge.setHandCursor?A.bridge.setHandCursor(a):A.ready=!1)},wa=function(a){if(/^(?:auto|inherit)$/.test(a))return a;var b;return"number"!=typeof a||m(a)?"string"==typeof a&&(b=wa(k(a,10))):b=a,"number"==typeof b?b:"auto"},xa=function(a){function b(a){var b=a.match(/[\d]+/g);return b.length=3,b.join(".")}function c(a){return!!a&&(a=a.toLowerCase())&&(/^(pepflashplayer\.dll|libpepflashplayer\.so|pepperflashplayer\.plugin)$/.test(a)||"chrome.plugin"===a.slice(-13))}function d(a){a&&(i=!0,a.version&&(m=b(a.version)),!m&&a.description&&(m=b(a.description)),a.filename&&(k=c(a.filename)))}var e,f,h,i=!1,j=!1,k=!1,m="";if(g.plugins&&g.plugins.length)e=g.plugins["Shockwave Flash"],d(e),g.plugins["Shockwave Flash 2.0"]&&(i=!0,m="2.0.0.11");else if(g.mimeTypes&&g.mimeTypes.length)h=g.mimeTypes["application/x-shockwave-flash"],e=h&&h.enabledPlugin,d(e);else if("undefined"!=typeof a){j=!0;try{f=new a("ShockwaveFlash.ShockwaveFlash.7"),i=!0,m=b(f.GetVariable("$version"))}catch(n){try{f=new a("ShockwaveFlash.ShockwaveFlash.6"),i=!0,m="6.0.21"}catch(o){try{f=new a("ShockwaveFlash.ShockwaveFlash"),i=!0,m=b(f.GetVariable("$version"))}catch(p){j=!1}}}}A.disabled=i!==!0,A.outdated=m&&l(m)g;g++)a=e.getRangeAt(g),c+=a.toString(),f.appendChild(a.cloneContents());return d["text/plain"]=c,c.replace(/\s/g,"")&&(d["text/html"]=f.innerHTML),d}function e(a){if("string"!=typeof a||!a)return null;var b,c,d=a;return d=d.replace(/<(?:hr)(?:\s+[^>]*)?\s*[\/]?>/gi,"{\\pard \\brdrb \\brdrs \\brdrw10 \\brsp20 \\par}\n{\\pard\\par}\n"),d=d.replace(/<(?:br)(?:\s+[^>]*)?\s*[\/]?>/gi,"{\\pard\\par}\n"),d=d.replace(/<(?:p|div|section|article)(?:\s+[^>]*)?\s*[\/]>/gi,"{\\pard\\par}\n"),d=d.replace(/<(?:[^>]+)\/>/g,""),d=d.replace(/]*)?(?:\s+href=(["'])(?:javascript:void\(0?\);?|#|return false;?|void\(0?\);?|)\1)(?:\s+[^>]*)?>/gi,"{{{\n"),b=d,d=d.replace(/]*)?(?:\s+href=(["'])(.+)\1)(?:\s+[^>]*)?>/gi,'{\\field{\\*\\fldinst{HYPERLINK\n "$2"\n}}{\\fldrslt{\\ul\\cf1\n'),c=d!==b,d=d.replace(/]*)?>/gi,"{{{\n"),d=d.replace(/<\/a(?:\s+[^>]*)?>/gi,"\n}}}"),d=d.replace(/<(?:b|strong)(?:\s+[^>]*)?>/gi,"{\\b\n"),d=d.replace(/<(?:i|em)(?:\s+[^>]*)?>/gi,"{\\i\n"),d=d.replace(/<(?:u|ins)(?:\s+[^>]*)?>/gi,"{\\ul\n"),d=d.replace(/<(?:strike|del)(?:\s+[^>]*)?>/gi,"{\\strike\n"),d=d.replace(/]*)?>/gi,"{\\super\n"),d=d.replace(/]*)?>/gi,"{\\sub\n"),d=d.replace(/<(?:p|div|section|article)(?:\s+[^>]*)?>/gi,"{\\pard\n"),d=d.replace(/<\/(?:p|div|section|article)(?:\s+[^>]*)?>/gi,"\n\\par}\n"),d=d.replace(/<\/(?:b|strong|i|em|u|ins|strike|del|sup|sub)(?:\s+[^>]*)?>/gi,"\n}"),d=d.replace(/<(?:[^>]+)>/g,""),d="{\\rtf1\\ansi\n"+(c?"{\\colortbl\n;\n\\red0\\green0\\blue255;\n}\n":"")+d+"\n}"}function f(b){var c=a.Event(b.type,a.extend(b,{_source:"swf"}));if(a(b.target).trigger(c),"copy"===c.type){if(a.event.special.copy.options.requirePreventDefault===!0&&!c.isDefaultPrevented()){b.clipboardData.clearData();var f=d();(f["text/plain"]||f["text/html"])&&b.clipboardData.setData(f)}var g=o.getData();if(a.event.special.copy.options.autoConvertHtmlToRtf===!0&&g["text/html"]&&!g["application/rtf"]){var h=e(g["text/html"]);b.clipboardData.setData("application/rtf",h)}}}function g(b){var c=a.Event("copy-error",a.extend(b,{type:"copy-error",_source:"swf"}));a(b.target).trigger(c)}function h(){a.event.props.push("clipboardData"),o.config(a.extend(!0,{autoActivate:!1},q.options)),o.on("beforecopy copy aftercopy",f),o.on("error",g),o.create()}function i(){o.destroy();var b=a.event.props.indexOf("clipboardData");-1!==b&&a.event.props.splice(b,1)}function j(b){l(b),b.target&&b.target!==o.activeElement()&&b.target!==a("#"+o.config("containerId"))[0]&&b.target!==a("#"+o.config("swfObjectId"))[0]&&o.focus(b.target)}function k(b){l(b),b.relatedTarget&&b.relatedTarget!==o.activeElement()&&b.relatedTarget!==a("#"+o.config("containerId"))[0]&&b.relatedTarget!==a("#"+o.config("swfObjectId"))[0]&&o.blur()}function l(a){o.isFlashUnusable()||"js"===a.originalEvent._source||(a.stopImmediatePropagation(),a.preventDefault())}var m=0,n=".zeroclipboard",o=b.ZeroClipboard,p=o.config("trustedDomains"),q={add:function(b){0===m++&&h();var c=n+(b.namespace?"."+b.namespace:""),d=b.selector,e="zc|{"+d+"}|{"+c+"}|count",f=a(this);"number"!=typeof f.data(e)&&f.data(e,0),0===f.data(e)&&(f.on("mouseenter"+c,d,j),f.on("mouseleave"+c,d,k),f.on("mouseover"+c,d,l),f.on("mouseout"+c,d,l),f.on("mousemove"+c,d,l),f.on("mousedown"+c,d,l),f.on("mouseup"+c,d,l),f.on("click"+c,d,l)),f.data(e,f.data(e)+1)},remove:function(b){var c=n+(b.namespace?"."+b.namespace:""),d=b.selector,e="zc|{"+d+"}|{"+c+"}|count",f=a(this);f.data(e,f.data(e)-1),0===f.data(e)&&(f.off("click"+c,d,l),f.off("mouseup"+c,d,l),f.off("mousedown"+c,d,l),f.off("mousemove"+c,d,l),f.off("mouseout"+c,d,l),f.off("mouseover"+c,d,l),f.off("mouseleave"+c,d,k),f.off("mouseenter"+c,d,j),f.removeData(e)),0===--m&&i()},trigger:function(b){if("copy"===b.type){var c=a(this),d="swf"===b._source;delete b._source,d||(c.trigger(a.extend(!0,{},b,{type:"beforecopy"})),c.one("copy",function(){var d={},e=o.getData();a.each(e,function(a){d[a]=!1});var f=a.extend(!0,{},b,{type:"aftercopy",data:a.extend(!0,{},e),success:d});c.trigger(f)}))}},_default:function(){return!0},options:{requirePreventDefault:!0,autoConvertHtmlToRtf:!0,trustedDomains:p,hoverClass:"hover",activeClass:"active"}};a.event.special.beforecopy=q,a.event.special.copy=q,a.event.special.aftercopy=q,a.event.special["copy-error"]=q}(jQuery,function(){return this||b}()),e||delete b.ZeroClipboard}(jQuery,function(){return this||window}()); \ No newline at end of file +!function(a,b){var c,e=a,f=e.document,g=e.navigator,h=e.setTimeout,i=e.encodeURIComponent,j=e.ActiveXObject,k=e.Number.parseInt||e.parseInt,l=e.Number.parseFloat||e.parseFloat,m=e.Number.isNaN||e.isNaN,n=e.Math.round,o=e.Date.now,p=e.Object.keys,q=e.Object.defineProperty,r=e.Object.prototype.hasOwnProperty,s=e.Array.prototype.slice,t=function(a){return s.call(a,0)},u=function(){var a,c,d,e,f,g,h=t(arguments),i=h[0]||{};for(a=1,c=h.length;a=0&&h(function(){"boolean"!=typeof A.deactivated&&(A.deactivated=!0),A.deactivated===!0&&ya.emit({type:"error",name:"flash-deactivated"})},a),A.overdue=!1,ga()}},Q=function(){ya.clearData(),ya.blur(),ya.emit("destroy"),ha(),ya.off()},R=function(a,b){var c;if("object"==typeof a&&a&&"undefined"==typeof b)c=a,ya.clearData();else{if("string"!=typeof a||!a)return;c={},c[a]=b}for(var d in c)"string"==typeof d&&d&&r.call(c,d)&&"string"==typeof c[d]&&c[d]&&(D[d]=c[d])},S=function(a){"undefined"==typeof a?(y(D),E=null):"string"==typeof a&&r.call(D,a)&&delete D[a]},T=function(a){return"undefined"==typeof a?v(D):"string"==typeof a&&r.call(D,a)?D[a]:void 0},U=function(a){if(a&&1===a.nodeType){c&&(qa(c,H.activeClass),c!==a&&qa(c,H.hoverClass)),c=a,pa(a,H.hoverClass);var b=a.getAttribute("title")||H.title;if("string"==typeof b&&b){var d=fa(A.bridge);d&&d.setAttribute("title",b)}var e=H.forceHandCursor===!0||"pointer"===ra(a,"cursor");va(e),ua()}},V=function(){var a=fa(A.bridge);a&&(a.removeAttribute("title"),a.style.left="0px",a.style.top="-9999px",a.style.width="1px",a.style.top="1px"),c&&(qa(c,H.hoverClass),qa(c,H.activeClass),c=null)},W=function(){return c||null},X=function(a){return"string"==typeof a&&a&&/^[A-Za-z][A-Za-z0-9_:\-\.]*$/.test(a)},Y=function(a){var b;if("string"==typeof a&&a?(b=a,a={}):"object"==typeof a&&a&&"string"==typeof a.type&&a.type&&(b=a.type),b){u(a,{type:b.toLowerCase(),target:a.target||c||null,relatedTarget:a.relatedTarget||null,currentTarget:A&&A.bridge||null,timeStamp:a.timeStamp||o()||null});var d=F[a.type];return"error"===a.type&&a.name&&d&&(d=d[a.name]),d&&(a.message=d),"ready"===a.type&&u(a,{target:null,version:A.version}),"error"===a.type&&(/^flash-(disabled|outdated|unavailable|deactivated|overdue)$/.test(a.name)&&u(a,{target:null,minimumVersion:B}),/^flash-(outdated|unavailable|deactivated|overdue)$/.test(a.name)&&u(a,{version:A.version})),"copy"===a.type&&(a.clipboardData={setData:ya.setData,clearData:ya.clearData}),"aftercopy"===a.type&&(a=ja(a,E)),a.target&&!a.relatedTarget&&(a.relatedTarget=Z(a.target)),a=$(a)}},Z=function(a){var b=a&&a.getAttribute&&a.getAttribute("data-clipboard-target");return b?f.getElementById(b):null},$=function(a){if(a&&/^_(?:click|mouse(?:over|out|down|up|move))$/.test(a.type)){var c=a.target,d="_mouseover"===a.type&&a.relatedTarget?a.relatedTarget:b,g="_mouseout"===a.type&&a.relatedTarget?a.relatedTarget:b,h=ta(c),i=e.screenLeft||e.screenX||0,j=e.screenTop||e.screenY||0,k=f.body.scrollLeft+f.documentElement.scrollLeft,l=f.body.scrollTop+f.documentElement.scrollTop,m=h.left+("number"==typeof a._stageX?a._stageX:0),n=h.top+("number"==typeof a._stageY?a._stageY:0),o=m-k,p=n-l,q=i+o,r=j+p,s="number"==typeof a.movementX?a.movementX:0,t="number"==typeof a.movementY?a.movementY:0;delete a._stageX,delete a._stageY,u(a,{srcElement:c,fromElement:d,toElement:g,screenX:q,screenY:r,pageX:m,pageY:n,clientX:o,clientY:p,x:o,y:p,movementX:s,movementY:t,offsetX:0,offsetY:0,layerX:0,layerY:0})}return a},_=function(a){var b=a&&"string"==typeof a.type&&a.type||"";return!/^(?:(?:before)?copy|destroy)$/.test(b)},aa=function(a,b,c,d){d?h(function(){a.apply(b,c)},0):a.apply(b,c)},ba=function(a){if("object"==typeof a&&a&&a.type){var b=_(a),c=C["*"]||[],d=C[a.type]||[],f=c.concat(d);if(f&&f.length){var g,h,i,j,k,l=this;for(g=0,h=f.length;g"+(l?'':"")+'',b=k.firstChild,k=null,b.ZeroClipboard=ya,c.replaceChild(b,j)}return b||(b=f[H.swfObjectId],b&&(a=b.length)&&(b=b[a-1]),!b&&c&&(b=c.firstChild)),A.bridge=b||null,b},ha=function(){var a=A.bridge;if(a){var b=fa(a);b&&("activex"===A.pluginType&&"readyState"in a?(a.style.display="none",function c(){if(4===a.readyState){for(var d in a)"function"==typeof a[d]&&(a[d]=null);a.parentNode&&a.parentNode.removeChild(a),b.parentNode&&b.parentNode.removeChild(b)}else h(c,10)}()):(a.parentNode&&a.parentNode.removeChild(a),b.parentNode&&b.parentNode.removeChild(b))),A.ready=null,A.bridge=null,A.deactivated=null}},ia=function(a){var b={},c={};if("object"==typeof a&&a){for(var d in a)if(d&&r.call(a,d)&&"string"==typeof a[d]&&a[d])switch(d.toLowerCase()){case"text/plain":case"text":case"air:text":case"flash:text":b.text=a[d],c.text=d;break;case"text/html":case"html":case"air:html":case"flash:html":b.html=a[d],c.html=d;break;case"application/rtf":case"text/rtf":case"rtf":case"richtext":case"air:rtf":case"flash:rtf":b.rtf=a[d],c.rtf=d}return{data:b,formatMap:c}}},ja=function(a,b){if("object"!=typeof a||!a||"object"!=typeof b||!b)return a;var c={};for(var d in a)if(r.call(a,d)){if("success"!==d&&"data"!==d){c[d]=a[d];continue}c[d]={};var e=a[d];for(var f in e)f&&r.call(e,f)&&r.call(b,f)&&(c[d][b[f]]=e[f])}return c},ka=function(a,b){var c=null==b||b&&b.cacheBust===!0;return c?(a.indexOf("?")===-1?"?":"&")+"noCache="+o():""},la=function(a){var b,c,d,f,g="",h=[];if(a.trustedDomains&&("string"==typeof a.trustedDomains?f=[a.trustedDomains]:"object"==typeof a.trustedDomains&&"length"in a.trustedDomains&&(f=a.trustedDomains)),f&&f.length)for(b=0,c=f.length;b0){if(1===f&&"*"===e[0])return"always";if(e.indexOf(b)!==-1)return 1===f&&b===d?"sameDomain":"always"}return"never"}}(),oa=function(){try{return f.activeElement}catch(a){return null}},pa=function(a,b){if(!a||1!==a.nodeType)return a;if(a.classList)return a.classList.contains(b)||a.classList.add(b),a;if(b&&"string"==typeof b){var c=(b||"").split(/\s+/);if(1===a.nodeType)if(a.className){for(var d=" "+a.className+" ",e=a.className,f=0,g=c.length;f]*)?\s*[\/]?>/gi,"{\\pard \\brdrb \\brdrs \\brdrw10 \\brsp20 \\par}\n{\\pard\\par}\n"),d=d.replace(/<(?:br)(?:\s+[^>]*)?\s*[\/]?>/gi,"{\\pard\\par}\n"),d=d.replace(/<(?:p|div|section|article)(?:\s+[^>]*)?\s*[\/]>/gi,"{\\pard\\par}\n"),d=d.replace(/<(?:[^>]+)\/>/g,""),d=d.replace(/]*)?(?:\s+href=(["'])(?:javascript:void\(0?\);?|#|return false;?|void\(0?\);?|)\1)(?:\s+[^>]*)?>/gi,"{{{\n"),b=d,d=d.replace(/]*)?(?:\s+href=(["'])(.+)\1)(?:\s+[^>]*)?>/gi,'{\\field{\\*\\fldinst{HYPERLINK\n "$2"\n}}{\\fldrslt{\\ul\\cf1\n'),c=d!==b,d=d.replace(/]*)?>/gi,"{{{\n"),d=d.replace(/<\/a(?:\s+[^>]*)?>/gi,"\n}}}"),d=d.replace(/<(?:b|strong)(?:\s+[^>]*)?>/gi,"{\\b\n"),d=d.replace(/<(?:i|em)(?:\s+[^>]*)?>/gi,"{\\i\n"),d=d.replace(/<(?:u|ins)(?:\s+[^>]*)?>/gi,"{\\ul\n"),d=d.replace(/<(?:strike|del)(?:\s+[^>]*)?>/gi,"{\\strike\n"),d=d.replace(/]*)?>/gi,"{\\super\n"),d=d.replace(/]*)?>/gi,"{\\sub\n"),d=d.replace(/<(?:p|div|section|article)(?:\s+[^>]*)?>/gi,"{\\pard\n"),d=d.replace(/<\/(?:p|div|section|article)(?:\s+[^>]*)?>/gi,"\n\\par}\n"),d=d.replace(/<\/(?:b|strong|i|em|u|ins|strike|del|sup|sub)(?:\s+[^>]*)?>/gi,"\n}"),d=d.replace(/<(?:[^>]+)>/g,""),d="{\\rtf1\\ansi\n"+(c?"{\\colortbl\n;\n\\red0\\green0\\blue255;\n}\n":"")+d+"\n}"}function f(b){var c=a.Event(b.type,a.extend(b,{_source:"swf"}));if(a(b.target).trigger(c),"copy"===c.type){if(a.event.special.copy.options.requirePreventDefault===!0&&!c.isDefaultPrevented()){b.clipboardData.clearData();var f=d();(f["text/plain"]||f["text/html"])&&b.clipboardData.setData(f)}var g=o.getData();if(a.event.special.copy.options.autoConvertHtmlToRtf===!0&&g["text/html"]&&!g["application/rtf"]){var h=e(g["text/html"]);b.clipboardData.setData("application/rtf",h)}}}function g(b){var c=a.Event("copy-error",a.extend(b,{type:"copy-error",_source:"swf"}));a(b.target).trigger(c)}function h(){a.event.props.push("clipboardData"),o.config(a.extend(!0,{autoActivate:!1},q.options)),o.on("beforecopy copy aftercopy",f),o.on("error",g),o.create()}function i(){o.destroy();var b=a.event.props.indexOf("clipboardData");b!==-1&&a.event.props.splice(b,1)}function j(b){l(b),b.target&&b.target!==o.activeElement()&&b.target!==a("#"+o.config("containerId"))[0]&&b.target!==a("#"+o.config("swfObjectId"))[0]&&o.focus(b.target)}function k(b){l(b),b.relatedTarget&&b.relatedTarget!==o.activeElement()&&b.relatedTarget!==a("#"+o.config("containerId"))[0]&&b.relatedTarget!==a("#"+o.config("swfObjectId"))[0]&&o.blur()}function l(a){o.isFlashUnusable()||"js"===a.originalEvent._source||(a.stopImmediatePropagation(),a.preventDefault())}var m=0,n=".zeroclipboard",o=b.ZeroClipboard,p=o.config("trustedDomains"),q={add:function(b){0===m++&&h();var c=n+(b.namespace?"."+b.namespace:""),d=b.selector,e="zc|{"+d+"}|{"+c+"}|count",f=a(this);"number"!=typeof f.data(e)&&f.data(e,0),0===f.data(e)&&(f.on("mouseenter"+c,d,j),f.on("mouseleave"+c,d,k),f.on("mouseover"+c,d,l),f.on("mouseout"+c,d,l),f.on("mousemove"+c,d,l),f.on("mousedown"+c,d,l),f.on("mouseup"+c,d,l),f.on("click"+c,d,l)),f.data(e,f.data(e)+1)},remove:function(b){var c=n+(b.namespace?"."+b.namespace:""),d=b.selector,e="zc|{"+d+"}|{"+c+"}|count",f=a(this);f.data(e,f.data(e)-1),0===f.data(e)&&(f.off("click"+c,d,l),f.off("mouseup"+c,d,l),f.off("mousedown"+c,d,l),f.off("mousemove"+c,d,l),f.off("mouseout"+c,d,l),f.off("mouseover"+c,d,l),f.off("mouseleave"+c,d,k),f.off("mouseenter"+c,d,j),f.removeData(e)),0===--m&&i()},trigger:function(b){if("copy"===b.type){var c=a(this),d="swf"===b._source;delete b._source,d||(c.trigger(a.extend(!0,{},b,{type:"beforecopy"})),c.one("copy",function(){var d={},e=o.getData();a.each(e,function(a){d[a]=!1});var f=a.extend(!0,{},b,{type:"aftercopy",data:a.extend(!0,{},e),success:d});c.trigger(f)}))}},_default:function(){return!0},options:{requirePreventDefault:!0,autoConvertHtmlToRtf:!0,trustedDomains:p,hoverClass:"hover",activeClass:"active"}};a.event.special.beforecopy=q,a.event.special.copy=q,a.event.special.aftercopy=q,a.event.special["copy-error"]=q}(jQuery,function(){return this||b}()),e||delete b.ZeroClipboard}(jQuery,function(){return this||window}()); \ No newline at end of file diff --git a/includes/admin/class-wc-admin-status.php b/includes/admin/class-wc-admin-status.php index 2e7e162dd7b..3299f4f7a9c 100644 --- a/includes/admin/class-wc-admin-status.php +++ b/includes/admin/class-wc-admin-status.php @@ -186,11 +186,6 @@ class WC_Admin_Status { 'name' => __( 'Reset Usage Tracking Settings', 'woocommerce' ), 'button' => __( 'Reset usage tracking settings', 'woocommerce' ), 'desc' => __( 'This will reset your usage tracking settings, causing it to show the opt-in banner again and not sending any data.', 'woocommerce' ), - ), - 'delete_geoip_log' => array( - 'name' => __( 'Delete GeoIP Log', 'woocommerce' ), - 'button' => __( 'Delete GeoIP Log', 'woocommerce' ), - 'desc' => __( 'This will delete the GeoIP log created by WooCommerce.', 'woocommerce' ), ) ); @@ -367,7 +362,7 @@ class WC_Admin_Status { /** * Remove/delete the chosen file. */ - public function remove_log() { + public static function remove_log() { if ( empty( $_REQUEST[ '_wpnonce' ] ) || ! wp_verify_nonce( $_REQUEST[ '_wpnonce' ], 'remove_log' ) ) { wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) ); } diff --git a/includes/admin/views/html-admin-page-status-logs.php b/includes/admin/views/html-admin-page-status-logs.php index b53b80a8166..d48b16ca1fc 100644 --- a/includes/admin/views/html-admin-page-status-logs.php +++ b/includes/admin/views/html-admin-page-status-logs.php @@ -11,7 +11,12 @@ if ( ! defined( 'ABSPATH' ) ) {
    -

    +

    + + + + +

    @@ -21,15 +26,12 @@ if ( ! defined( 'ABSPATH' ) ) { - - -
    - +

    diff --git a/includes/class-wc-logger.php b/includes/class-wc-logger.php index ebb69cc2b91..54a3b810a59 100644 --- a/includes/class-wc-logger.php +++ b/includes/class-wc-logger.php @@ -138,8 +138,10 @@ class WC_Logger { if ( is_file( $file ) && is_writable( $file ) ) { // Close first to be certain no processes keep it alive after it is unlinked. $this->close( $handle ); - $removed = unlink( $file ); + } elseif ( is_file( trailingslashit( WC_LOG_DIR ) . $handle . '.log' ) && is_writable( trailingslashit( WC_LOG_DIR ) . $handle . '.log' ) ) { + $this->close( $handle ); + $removed = unlink( trailingslashit( WC_LOG_DIR ) . $handle . '.log' ); } do_action( 'woocommerce_log_remove', $handle, $removed ); @@ -147,4 +149,4 @@ class WC_Logger { return $removed; } -} \ No newline at end of file +} diff --git a/includes/gateways/simplify-commerce/assets/js/simplify-commerce.min.js b/includes/gateways/simplify-commerce/assets/js/simplify-commerce.min.js index 2cb20ab21ec..823ea5391b6 100644 --- a/includes/gateways/simplify-commerce/assets/js/simplify-commerce.min.js +++ b/includes/gateways/simplify-commerce/assets/js/simplify-commerce.min.js @@ -1 +1 @@ -!function(a){function b(){var b=a("form.checkout, form#order_review, form#add_payment_method");if((a("#payment_method_simplify_commerce").is(":checked")&&"new"===a('input[name="wc-simplify_commerce-payment-token"]:checked').val()||"1"===a("#woocommerce_add_payment_method").val())&&0===a("input.simplify-token").length){b.block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var d=a("#simplify_commerce-card-number").val(),e=a("#simplify_commerce-card-cvc").val(),f=a.payment.cardExpiryVal(a("#simplify_commerce-card-expiry").val()),g=b.find("#billing_address_1").val()||"",h=b.find("#billing_address_2").val()||"",i=b.find("#billing_country").val()||"",j=b.find("#billing_state").val()||"",k=b.find("#billing_city").val()||"",l=b.find("#billing_postcode").val()||"";return l=l.replace(/-/g,""),d=d.replace(/\s/g,""),SimplifyCommerce.generateToken({key:Simplify_commerce_params.key,card:{number:d,cvc:e,expMonth:f.month,expYear:f.year-2e3,addressLine1:g,addressLine2:h,addressCountry:i,addressState:j,addressZip:l,addressCity:k}},c),!1}return!0}function c(b){var c=a("form.checkout, form#order_review, form#add_payment_method"),d=a("#wc-simplify_commerce-cc-form");if(b.error){if(a(".woocommerce-error, .simplify-token",d).remove(),c.unblock(),"validation"===b.error.code){for(var e=b.error.fieldErrors,f=e.length,g="",h=0;f>h;h++)g+="
  • "+Simplify_commerce_params[e[h].field]+" "+Simplify_commerce_params.is_invalid+" - "+e[h].message+".
  • ";d.prepend('
      '+g+"
    ")}}else d.append(''),c.submit()}a(function(){a(document.body).on("checkout_error",function(){a(".simplify-token").remove()}),a("form.checkout").on("checkout_place_order_simplify_commerce",function(){return b()}),a("form#order_review").on("submit",function(){return b()}),a("form#add_payment_method").on("submit",function(){return b()}),a("form.checkout, form#order_review, form#add_payment_method").on("change","#wc-simplify_commerce-cc-form input",function(){a(".simplify-token").remove()})})}(jQuery); \ No newline at end of file +!function(a){function b(){var b=a("form.checkout, form#order_review, form#add_payment_method");if((a("#payment_method_simplify_commerce").is(":checked")&&"new"===a('input[name="wc-simplify_commerce-payment-token"]:checked').val()||"1"===a("#woocommerce_add_payment_method").val())&&0===a("input.simplify-token").length){b.block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var d=a("#simplify_commerce-card-number").val(),e=a("#simplify_commerce-card-cvc").val(),f=a.payment.cardExpiryVal(a("#simplify_commerce-card-expiry").val()),g=b.find("#billing_address_1").val()||"",h=b.find("#billing_address_2").val()||"",i=b.find("#billing_country").val()||"",j=b.find("#billing_state").val()||"",k=b.find("#billing_city").val()||"",l=b.find("#billing_postcode").val()||"";return l=l.replace(/-/g,""),d=d.replace(/\s/g,""),SimplifyCommerce.generateToken({key:Simplify_commerce_params.key,card:{number:d,cvc:e,expMonth:f.month,expYear:f.year-2e3,addressLine1:g,addressLine2:h,addressCountry:i,addressState:j,addressZip:l,addressCity:k}},c),!1}return!0}function c(b){var c=a("form.checkout, form#order_review, form#add_payment_method"),d=a("#wc-simplify_commerce-cc-form");if(b.error){if(a(".woocommerce-error, .simplify-token",d).remove(),c.unblock(),"validation"===b.error.code){for(var e=b.error.fieldErrors,f=e.length,g="",h=0;h"+Simplify_commerce_params[e[h].field]+" "+Simplify_commerce_params.is_invalid+" - "+e[h].message+".";d.prepend('
      '+g+"
    ")}}else d.append(''),c.submit()}a(function(){a(document.body).on("checkout_error",function(){a(".simplify-token").remove()}),a("form.checkout").on("checkout_place_order_simplify_commerce",function(){return b()}),a("form#order_review").on("submit",function(){return b()}),a("form#add_payment_method").on("submit",function(){return b()}),a("form.checkout, form#order_review, form#add_payment_method").on("change","#wc-simplify_commerce-cc-form input",function(){a(".simplify-token").remove()})})}(jQuery); \ No newline at end of file From 6e1a640b1c768f9ee2642e446d17b8c8552ab5a0 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 2 Aug 2016 17:10:26 +0100 Subject: [PATCH 209/298] Prevent dirty sessions by removing data objects from the package hash Closes #11269 --- includes/class-wc-shipping.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/includes/class-wc-shipping.php b/includes/class-wc-shipping.php index 1bd54dd501b..0ffd8644b3f 100644 --- a/includes/class-wc-shipping.php +++ b/includes/class-wc-shipping.php @@ -331,7 +331,14 @@ class WC_Shipping { } // Check if we need to recalculate shipping for this package - $package_hash = 'wc_ship_' . md5( json_encode( $package ) . WC_Cache_Helper::get_transient_version( 'shipping' ) ); + $package_to_hash = $package; + + // Remove data objects so hashes are consistent + foreach ( $package_to_hash['contents'] as $item_id => $item ) { + unset( $package_to_hash['contents'][ $item_id ]['data'] ); + } + + $package_hash = 'wc_ship_' . md5( json_encode( $package_to_hash ) . WC_Cache_Helper::get_transient_version( 'shipping' ) ); $status_options = get_option( 'woocommerce_status_options', array() ); $session_key = 'shipping_for_package_' . $package_key; $stored_rates = WC()->session->get( $session_key ); From 1f25dc001b9096621ea5b0c70a610a28b1a28474 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Thu, 21 Jul 2016 10:39:34 -0700 Subject: [PATCH 210/298] After payment form fragments are updated, make sure to set the previously selected payment method back as the selected/default payment method. --- assets/js/frontend/checkout.js | 25 ++++++++++++++++--------- assets/js/frontend/checkout.min.js | 2 +- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/assets/js/frontend/checkout.js b/assets/js/frontend/checkout.js index 8eb88ea597e..3f38266b246 100644 --- a/assets/js/frontend/checkout.js +++ b/assets/js/frontend/checkout.js @@ -55,17 +55,21 @@ jQuery( function( $ ) { $( 'input#createaccount' ).change( this.toggle_create_account ).change(); } }, - init_payment_methods: function() { + init_payment_methods: function( selectedPaymentMethod ) { var $payment_methods = $( '.woocommerce-checkout' ).find( 'input[name="payment_method"]' ); - // If there is one method, we can hide the radio input - if ( 1 === $payment_methods.length ) { - $payment_methods.eq(0).hide(); - } + if ( selectedPaymentMethod ) { + $( '#' + selectedPaymentMethod ).prop( 'checked', true ); + } else { + // If there is one method, we can hide the radio input + if ( 1 === $payment_methods.length ) { + $payment_methods.eq(0).hide(); + } - // If there are none selected, select the first. - if ( 0 === $payment_methods.filter( ':checked' ).length ) { - $payment_methods.eq(0).prop( 'checked', true ); + // If there are none selected, select the first. + if ( 0 === $payment_methods.filter( ':checked' ).length ) { + $payment_methods.eq(0).prop( 'checked', true ); + } } // Trigger click event for selected method @@ -271,6 +275,9 @@ jQuery( function( $ ) { url: wc_checkout_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'update_order_review' ), data: data, success: function( data ) { + + var selectedPaymentMethod = $( '.woocommerce-checkout' ).find( 'input[name="payment_method"]' ).filter( ':checked' ).attr( 'id' ); + // Reload the page if requested if ( 'true' === data.reload ) { window.location.reload(); @@ -321,7 +328,7 @@ jQuery( function( $ ) { } // Re-init methods - wc_checkout_form.init_payment_methods(); + wc_checkout_form.init_payment_methods( selectedPaymentMethod ); // Fire updated_checkout e $( document.body ).trigger( 'updated_checkout' ); diff --git a/assets/js/frontend/checkout.min.js b/assets/js/frontend/checkout.min.js index 2f3c15b07ff..f10dce35ac4 100644 --- a/assets/js/frontend/checkout.min.js +++ b/assets/js/frontend/checkout.min.js @@ -1 +1 @@ -jQuery(function(a){if("undefined"==typeof wc_checkout_params)return!1;a.blockUI.defaults.overlayCSS.cursor="default";var b={updateTimer:!1,dirtyInput:!1,xhr:!1,$order_review:a("#order_review"),$checkout_form:a("form.checkout"),init:function(){a(document.body).bind("update_checkout",this.update_checkout),a(document.body).bind("init_checkout",this.init_checkout),this.$checkout_form.on("click",'input[name="payment_method"]',this.payment_method_selected),a(document.body).hasClass("woocommerce-order-pay")&&this.$order_review.on("click",'input[name="payment_method"]',this.payment_method_selected),this.$checkout_form.on("submit",this.submit),this.$checkout_form.on("blur change",".input-text, select, input:checkbox",this.validate_field),this.$checkout_form.on("update",this.trigger_update_checkout),this.$checkout_form.on("change",'select.shipping_method, input[name^="shipping_method"], #ship-to-different-address input, .update_totals_on_change select, .update_totals_on_change input[type="radio"]',this.trigger_update_checkout),this.$checkout_form.on("change",".address-field select",this.input_changed),this.$checkout_form.on("change",".address-field input.input-text, .update_totals_on_change input.input-text",this.maybe_input_changed),this.$checkout_form.on("change keydown",".address-field input.input-text, .update_totals_on_change input.input-text",this.queue_update_checkout),this.$checkout_form.on("change","#ship-to-different-address input",this.ship_to_different_address),this.$checkout_form.find("#ship-to-different-address input").change(),this.init_payment_methods(),"1"===wc_checkout_params.is_checkout&&a(document.body).trigger("init_checkout"),"yes"===wc_checkout_params.option_guest_checkout&&a("input#createaccount").change(this.toggle_create_account).change()},init_payment_methods:function(){var b=a(".woocommerce-checkout").find('input[name="payment_method"]');1===b.length&&b.eq(0).hide(),0===b.filter(":checked").length&&b.eq(0).prop("checked",!0),b.filter(":checked").eq(0).trigger("click")},get_payment_method:function(){return b.$order_review.find('input[name="payment_method"]:checked').val()},payment_method_selected:function(){if(a(".payment_methods input.input-radio").length>1){var b=a("div.payment_box."+a(this).attr("ID"));a(this).is(":checked")&&!b.is(":visible")&&(a("div.payment_box").filter(":visible").slideUp(250),a(this).is(":checked")&&a("div.payment_box."+a(this).attr("ID")).slideDown(250))}else a("div.payment_box").show();a(this).data("order_button_text")?a("#place_order").val(a(this).data("order_button_text")):a("#place_order").val(a("#place_order").data("value"))},toggle_create_account:function(){a("div.create-account").hide(),a(this).is(":checked")&&a("div.create-account").slideDown()},init_checkout:function(){a("#billing_country, #shipping_country, .country_to_state").change(),a(document.body).trigger("update_checkout")},maybe_input_changed:function(a){b.dirtyInput&&b.input_changed(a)},input_changed:function(a){b.dirtyInput=a.target,b.maybe_update_checkout()},queue_update_checkout:function(a){var c=a.keyCode||a.which||0;return 9===c||(b.dirtyInput=this,b.reset_update_checkout_timer(),void(b.updateTimer=setTimeout(b.maybe_update_checkout,"1000")))},trigger_update_checkout:function(){b.reset_update_checkout_timer(),b.dirtyInput=!1,a(document.body).trigger("update_checkout")},maybe_update_checkout:function(){var c=!0;if(a(b.dirtyInput).length){var d=a(b.dirtyInput).closest("div").find(".address-field.validate-required");d.length&&d.each(function(){""===a(this).find("input.input-text").val()&&(c=!1)})}c&&b.trigger_update_checkout()},ship_to_different_address:function(){a("div.shipping_address").hide(),a(this).is(":checked")&&a("div.shipping_address").slideDown()},reset_update_checkout_timer:function(){clearTimeout(b.updateTimer)},validate_field:function(){var b=a(this),c=b.closest(".form-row"),d=!0;if(c.is(".validate-required")&&("checkbox"!==b.attr("type")||b.is(":checked")?""===b.val()&&(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-required-field"),d=!1):(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-required-field"),d=!1)),c.is(".validate-email")&&b.val()){var e=new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);e.test(b.val())||(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-email"),d=!1)}d&&c.removeClass("woocommerce-invalid woocommerce-invalid-required-field").addClass("woocommerce-validated")},update_checkout:function(a,c){b.reset_update_checkout_timer(),b.updateTimer=setTimeout(b.update_checkout_action,"5",c)},update_checkout_action:function(c){if(b.xhr&&b.xhr.abort(),0!==a("form.checkout").length){c="undefined"!=typeof c?c:{update_shipping_method:!0};var d=a("#billing_country").val(),e=a("#billing_state").val(),f=a("input#billing_postcode").val(),g=a("#billing_city").val(),h=a("input#billing_address_1").val(),i=a("input#billing_address_2").val(),j=d,k=e,l=f,m=g,n=h,o=i;a("#ship-to-different-address").find("input").is(":checked")&&(j=a("#shipping_country").val(),k=a("#shipping_state").val(),l=a("input#shipping_postcode").val(),m=a("#shipping_city").val(),n=a("input#shipping_address_1").val(),o=a("input#shipping_address_2").val());var p={security:wc_checkout_params.update_order_review_nonce,payment_method:b.get_payment_method(),country:d,state:e,postcode:f,city:g,address:h,address_2:i,s_country:j,s_state:k,s_postcode:l,s_city:m,s_address:n,s_address_2:o,post_data:a("form.checkout").serialize()};if(!1!==c.update_shipping_method){var q={};a('select.shipping_method, input[name^="shipping_method"][type="radio"]:checked, input[name^="shipping_method"][type="hidden"]').each(function(){q[a(this).data("index")]=a(this).val()}),p.shipping_method=q}a(".woocommerce-checkout-payment, .woocommerce-checkout-review-order-table").block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),b.xhr=a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","update_order_review"),data:p,success:function(c){if("true"===c.reload)return void window.location.reload();a(".woocommerce-NoticeGroup-updateOrderReview").remove();var d=a("#terms").prop("checked");if(c&&c.fragments&&a.each(c.fragments,function(b,c){a(b).replaceWith(c),a(b).unblock()}),d&&a("#terms").prop("checked",!0),"failure"===c.result){var e=a("form.checkout");a(".woocommerce-error, .woocommerce-message").remove(),c.messages?e.prepend('
    '+c.messages+"
    "):e.prepend(c),e.find(".input-text, select, input:checkbox").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3)}b.init_payment_methods(),a(document.body).trigger("updated_checkout")}})}},submit:function(){b.reset_update_checkout_timer();var c=a(this);if(c.is(".processing"))return!1;if(c.triggerHandler("checkout_place_order")!==!1&&c.triggerHandler("checkout_place_order_"+b.get_payment_method())!==!1){c.addClass("processing");var d=c.data();1!==d["blockUI.isBlocked"]&&c.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),a.ajaxSetup({dataFilter:function(b,c){if("json"!==c)return b;try{var d=a.parseJSON(b);if(d&&"object"==typeof d)return b}catch(e){var f=b.match(/{"result.*"}/);null===f?console.log("Unable to fix malformed JSON"):(console.log("Fixed malformed JSON. Original:"),console.log(b),b=f[0])}return b}}),a.ajax({type:"POST",url:wc_checkout_params.checkout_url,data:c.serialize(),dataType:"json",success:function(c){try{if("success"!==c.result)throw"failure"===c.result?"Result failure":"Invalid response";-1===c.redirect.indexOf("https://")||-1===c.redirect.indexOf("http://")?window.location=c.redirect:window.location=decodeURI(c.redirect)}catch(d){if("true"===c.reload)return void window.location.reload();"true"===c.refresh&&a(document.body).trigger("update_checkout"),c.messages?b.submit_error(c.messages):b.submit_error('
    '+wc_checkout_params.i18n_checkout_error+"
    ")}},error:function(a,c,d){b.submit_error('
    '+d+"
    ")}})}return!1},submit_error:function(c){a(".woocommerce-error, .woocommerce-message").remove(),b.$checkout_form.prepend(c),b.$checkout_form.removeClass("processing").unblock(),b.$checkout_form.find(".input-text, select, input:checkbox").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3),a(document.body).trigger("checkout_error")}},c={init:function(){a(document.body).on("click","a.showcoupon",this.show_coupon_form),a(document.body).on("click",".woocommerce-remove-coupon",this.remove_coupon),a("form.checkout_coupon").hide().submit(this.submit)},show_coupon_form:function(){return a(".checkout_coupon").slideToggle(400,function(){a(".checkout_coupon").find(":input:eq(0)").focus()}),!1},submit:function(){var b=a(this);if(b.is(".processing"))return!1;b.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={security:wc_checkout_params.apply_coupon_nonce,coupon_code:b.find('input[name="coupon_code"]').val()};return a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),data:c,success:function(c){a(".woocommerce-error, .woocommerce-message").remove(),b.removeClass("processing").unblock(),c&&(b.before(c),b.slideUp(),a(document.body).trigger("update_checkout",{update_shipping_method:!1}))},dataType:"html"}),!1},remove_coupon:function(b){b.preventDefault();var c=a(this).parents(".woocommerce-checkout-review-order"),d=a(this).data("coupon");c.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var e={security:wc_checkout_params.remove_coupon_nonce,coupon:d};a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","remove_coupon"),data:e,success:function(b){a(".woocommerce-error, .woocommerce-message").remove(),c.removeClass("processing").unblock(),b&&(a("form.woocommerce-checkout").before(b),a(document.body).trigger("update_checkout",{update_shipping_method:!1}),a("form.checkout_coupon").find('input[name="coupon_code"]').val(""))},error:function(a){wc_checkout_params.debug_mode&&console.log(a.responseText)},dataType:"html"})}},d={init:function(){a(document.body).on("click","a.showlogin",this.show_login_form)},show_login_form:function(){return a("form.login").slideToggle(),!1}};b.init(),c.init(),d.init()}); \ No newline at end of file +jQuery(function(a){if("undefined"==typeof wc_checkout_params)return!1;a.blockUI.defaults.overlayCSS.cursor="default";var b={updateTimer:!1,dirtyInput:!1,xhr:!1,$order_review:a("#order_review"),$checkout_form:a("form.checkout"),init:function(){a(document.body).bind("update_checkout",this.update_checkout),a(document.body).bind("init_checkout",this.init_checkout),this.$checkout_form.on("click",'input[name="payment_method"]',this.payment_method_selected),a(document.body).hasClass("woocommerce-order-pay")&&this.$order_review.on("click",'input[name="payment_method"]',this.payment_method_selected),this.$checkout_form.on("submit",this.submit),this.$checkout_form.on("blur change",".input-text, select, input:checkbox",this.validate_field),this.$checkout_form.on("update",this.trigger_update_checkout),this.$checkout_form.on("change",'select.shipping_method, input[name^="shipping_method"], #ship-to-different-address input, .update_totals_on_change select, .update_totals_on_change input[type="radio"]',this.trigger_update_checkout),this.$checkout_form.on("change",".address-field select",this.input_changed),this.$checkout_form.on("change",".address-field input.input-text, .update_totals_on_change input.input-text",this.maybe_input_changed),this.$checkout_form.on("change keydown",".address-field input.input-text, .update_totals_on_change input.input-text",this.queue_update_checkout),this.$checkout_form.on("change","#ship-to-different-address input",this.ship_to_different_address),this.$checkout_form.find("#ship-to-different-address input").change(),this.init_payment_methods(),"1"===wc_checkout_params.is_checkout&&a(document.body).trigger("init_checkout"),"yes"===wc_checkout_params.option_guest_checkout&&a("input#createaccount").change(this.toggle_create_account).change()},init_payment_methods:function(b){var c=a(".woocommerce-checkout").find('input[name="payment_method"]');b?a("#"+b).prop("checked",!0):(1===c.length&&c.eq(0).hide(),0===c.filter(":checked").length&&c.eq(0).prop("checked",!0)),c.filter(":checked").eq(0).trigger("click")},get_payment_method:function(){return b.$order_review.find('input[name="payment_method"]:checked').val()},payment_method_selected:function(){if(a(".payment_methods input.input-radio").length>1){var b=a("div.payment_box."+a(this).attr("ID"));a(this).is(":checked")&&!b.is(":visible")&&(a("div.payment_box").filter(":visible").slideUp(250),a(this).is(":checked")&&a("div.payment_box."+a(this).attr("ID")).slideDown(250))}else a("div.payment_box").show();a(this).data("order_button_text")?a("#place_order").val(a(this).data("order_button_text")):a("#place_order").val(a("#place_order").data("value"))},toggle_create_account:function(){a("div.create-account").hide(),a(this).is(":checked")&&a("div.create-account").slideDown()},init_checkout:function(){a("#billing_country, #shipping_country, .country_to_state").change(),a(document.body).trigger("update_checkout")},maybe_input_changed:function(a){b.dirtyInput&&b.input_changed(a)},input_changed:function(a){b.dirtyInput=a.target,b.maybe_update_checkout()},queue_update_checkout:function(a){var c=a.keyCode||a.which||0;return 9===c||(b.dirtyInput=this,b.reset_update_checkout_timer(),void(b.updateTimer=setTimeout(b.maybe_update_checkout,"1000")))},trigger_update_checkout:function(){b.reset_update_checkout_timer(),b.dirtyInput=!1,a(document.body).trigger("update_checkout")},maybe_update_checkout:function(){var c=!0;if(a(b.dirtyInput).length){var d=a(b.dirtyInput).closest("div").find(".address-field.validate-required");d.length&&d.each(function(){""===a(this).find("input.input-text").val()&&(c=!1)})}c&&b.trigger_update_checkout()},ship_to_different_address:function(){a("div.shipping_address").hide(),a(this).is(":checked")&&a("div.shipping_address").slideDown()},reset_update_checkout_timer:function(){clearTimeout(b.updateTimer)},validate_field:function(){var b=a(this),c=b.closest(".form-row"),d=!0;if(c.is(".validate-required")&&("checkbox"!==b.attr("type")||b.is(":checked")?""===b.val()&&(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-required-field"),d=!1):(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-required-field"),d=!1)),c.is(".validate-email")&&b.val()){var e=new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);e.test(b.val())||(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-email"),d=!1)}d&&c.removeClass("woocommerce-invalid woocommerce-invalid-required-field").addClass("woocommerce-validated")},update_checkout:function(a,c){b.reset_update_checkout_timer(),b.updateTimer=setTimeout(b.update_checkout_action,"5",c)},update_checkout_action:function(c){if(b.xhr&&b.xhr.abort(),0!==a("form.checkout").length){c="undefined"!=typeof c?c:{update_shipping_method:!0};var d=a("#billing_country").val(),e=a("#billing_state").val(),f=a("input#billing_postcode").val(),g=a("#billing_city").val(),h=a("input#billing_address_1").val(),i=a("input#billing_address_2").val(),j=d,k=e,l=f,m=g,n=h,o=i;a("#ship-to-different-address").find("input").is(":checked")&&(j=a("#shipping_country").val(),k=a("#shipping_state").val(),l=a("input#shipping_postcode").val(),m=a("#shipping_city").val(),n=a("input#shipping_address_1").val(),o=a("input#shipping_address_2").val());var p={security:wc_checkout_params.update_order_review_nonce,payment_method:b.get_payment_method(),country:d,state:e,postcode:f,city:g,address:h,address_2:i,s_country:j,s_state:k,s_postcode:l,s_city:m,s_address:n,s_address_2:o,post_data:a("form.checkout").serialize()};if(!1!==c.update_shipping_method){var q={};a('select.shipping_method, input[name^="shipping_method"][type="radio"]:checked, input[name^="shipping_method"][type="hidden"]').each(function(){q[a(this).data("index")]=a(this).val()}),p.shipping_method=q}a(".woocommerce-checkout-payment, .woocommerce-checkout-review-order-table").block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),b.xhr=a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","update_order_review"),data:p,success:function(c){var d=a(".woocommerce-checkout").find('input[name="payment_method"]').filter(":checked").attr("id");if("true"===c.reload)return void window.location.reload();a(".woocommerce-NoticeGroup-updateOrderReview").remove();var e=a("#terms").prop("checked");if(c&&c.fragments&&a.each(c.fragments,function(b,c){a(b).replaceWith(c),a(b).unblock()}),e&&a("#terms").prop("checked",!0),"failure"===c.result){var f=a("form.checkout");a(".woocommerce-error, .woocommerce-message").remove(),c.messages?f.prepend('
    '+c.messages+"
    "):f.prepend(c),f.find(".input-text, select, input:checkbox").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3)}b.init_payment_methods(d),a(document.body).trigger("updated_checkout")}})}},submit:function(){b.reset_update_checkout_timer();var c=a(this);if(c.is(".processing"))return!1;if(c.triggerHandler("checkout_place_order")!==!1&&c.triggerHandler("checkout_place_order_"+b.get_payment_method())!==!1){c.addClass("processing");var d=c.data();1!==d["blockUI.isBlocked"]&&c.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),a.ajaxSetup({dataFilter:function(b,c){if("json"!==c)return b;try{var d=a.parseJSON(b);if(d&&"object"==typeof d)return b}catch(e){var f=b.match(/{"result.*"}/);null===f?console.log("Unable to fix malformed JSON"):(console.log("Fixed malformed JSON. Original:"),console.log(b),b=f[0])}return b}}),a.ajax({type:"POST",url:wc_checkout_params.checkout_url,data:c.serialize(),dataType:"json",success:function(c){try{if("success"!==c.result)throw"failure"===c.result?"Result failure":"Invalid response";-1===c.redirect.indexOf("https://")||-1===c.redirect.indexOf("http://")?window.location=c.redirect:window.location=decodeURI(c.redirect)}catch(d){if("true"===c.reload)return void window.location.reload();"true"===c.refresh&&a(document.body).trigger("update_checkout"),c.messages?b.submit_error(c.messages):b.submit_error('
    '+wc_checkout_params.i18n_checkout_error+"
    ")}},error:function(a,c,d){b.submit_error('
    '+d+"
    ")}})}return!1},submit_error:function(c){a(".woocommerce-error, .woocommerce-message").remove(),b.$checkout_form.prepend(c),b.$checkout_form.removeClass("processing").unblock(),b.$checkout_form.find(".input-text, select, input:checkbox").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3),a(document.body).trigger("checkout_error")}},c={init:function(){a(document.body).on("click","a.showcoupon",this.show_coupon_form),a(document.body).on("click",".woocommerce-remove-coupon",this.remove_coupon),a("form.checkout_coupon").hide().submit(this.submit)},show_coupon_form:function(){return a(".checkout_coupon").slideToggle(400,function(){a(".checkout_coupon").find(":input:eq(0)").focus()}),!1},submit:function(){var b=a(this);if(b.is(".processing"))return!1;b.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={security:wc_checkout_params.apply_coupon_nonce,coupon_code:b.find('input[name="coupon_code"]').val()};return a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),data:c,success:function(c){a(".woocommerce-error, .woocommerce-message").remove(),b.removeClass("processing").unblock(),c&&(b.before(c),b.slideUp(),a(document.body).trigger("update_checkout",{update_shipping_method:!1}))},dataType:"html"}),!1},remove_coupon:function(b){b.preventDefault();var c=a(this).parents(".woocommerce-checkout-review-order"),d=a(this).data("coupon");c.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var e={security:wc_checkout_params.remove_coupon_nonce,coupon:d};a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","remove_coupon"),data:e,success:function(b){a(".woocommerce-error, .woocommerce-message").remove(),c.removeClass("processing").unblock(),b&&(a("form.woocommerce-checkout").before(b),a(document.body).trigger("update_checkout",{update_shipping_method:!1}),a("form.checkout_coupon").find('input[name="coupon_code"]').val(""))},error:function(a){wc_checkout_params.debug_mode&&console.log(a.responseText)},dataType:"html"})}},d={init:function(){a(document.body).on("click","a.showlogin",this.show_login_form)},show_login_form:function(){return a("form.login").slideToggle(),!1}};b.init(),c.init(),d.init()}); \ No newline at end of file From a534512b8a3cded6232d3a8786f971928503d369 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 26 Jul 2016 12:37:16 -0700 Subject: [PATCH 211/298] Still hide checkboxes for single payment options, even if we select a "previously selected" option. --- assets/js/frontend/checkout.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/assets/js/frontend/checkout.js b/assets/js/frontend/checkout.js index 3f38266b246..6949de9cb37 100644 --- a/assets/js/frontend/checkout.js +++ b/assets/js/frontend/checkout.js @@ -58,14 +58,14 @@ jQuery( function( $ ) { init_payment_methods: function( selectedPaymentMethod ) { var $payment_methods = $( '.woocommerce-checkout' ).find( 'input[name="payment_method"]' ); + // If there is one method, we can hide the radio input + if ( 1 === $payment_methods.length ) { + $payment_methods.eq(0).hide(); + } + if ( selectedPaymentMethod ) { $( '#' + selectedPaymentMethod ).prop( 'checked', true ); } else { - // If there is one method, we can hide the radio input - if ( 1 === $payment_methods.length ) { - $payment_methods.eq(0).hide(); - } - // If there are none selected, select the first. if ( 0 === $payment_methods.filter( ':checked' ).length ) { $payment_methods.eq(0).prop( 'checked', true ); From e58c0f7f45086eae44543edffa0739ff79d68ceb Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 26 Jul 2016 13:41:55 -0700 Subject: [PATCH 212/298] Switch our selection for finding the checked box. :checked is faster than filtering. --- assets/js/frontend/checkout.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/frontend/checkout.js b/assets/js/frontend/checkout.js index 6949de9cb37..2aeffd30bbf 100644 --- a/assets/js/frontend/checkout.js +++ b/assets/js/frontend/checkout.js @@ -276,7 +276,7 @@ jQuery( function( $ ) { data: data, success: function( data ) { - var selectedPaymentMethod = $( '.woocommerce-checkout' ).find( 'input[name="payment_method"]' ).filter( ':checked' ).attr( 'id' ); + var selectedPaymentMethod = $( '.woocommerce-checkout input[name="payment_method"]:checked' ).attr( 'id' ); // Reload the page if requested if ( 'true' === data.reload ) { From b61d9cd5f1fbb76944b45e249d2c8db353ae7f77 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 2 Aug 2016 17:43:23 +0100 Subject: [PATCH 213/298] Add index to search form IDs Fixes #11557 --- includes/wc-template-functions.php | 10 +++++++++- templates/product-searchform.php | 6 ++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 461b590ebb4..82156adfa7b 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -2037,11 +2037,19 @@ if ( ! function_exists( 'get_product_search_form' ) ) { * @return string */ function get_product_search_form( $echo = true ) { + global $product_search_form_index; + ob_start(); + if ( empty( $product_search_form_index ) ) { + $product_search_form_index = 0; + } + do_action( 'pre_get_product_search_form' ); - wc_get_template( 'product-searchform.php' ); + wc_get_template( 'product-searchform.php', array( + 'index' => $product_search_form_index++, + ) ); $form = apply_filters( 'get_product_search_form', ob_get_clean() ); diff --git a/templates/product-searchform.php b/templates/product-searchform.php index 44ef0d09868..9a48388c40c 100644 --- a/templates/product-searchform.php +++ b/templates/product-searchform.php @@ -16,16 +16,14 @@ * @version 2.5.0 */ -// Exit if accessed directly if ( ! defined( 'ABSPATH' ) ) { exit; } ?> - From f77cdd366d2b835db5f689752777530a37306715 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 2 Aug 2016 10:05:18 -0700 Subject: [PATCH 214/298] Move our "if no other payment methods are found" selection logic, outside of the if/else block for selectedPaymentMethod. We want to make sure it still ruins, even if selectedPaymentMethod matches nothing. --- assets/js/frontend/checkout.js | 11 ++++++----- assets/js/frontend/checkout.min.js | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/assets/js/frontend/checkout.js b/assets/js/frontend/checkout.js index 2aeffd30bbf..97c2684449f 100644 --- a/assets/js/frontend/checkout.js +++ b/assets/js/frontend/checkout.js @@ -63,13 +63,14 @@ jQuery( function( $ ) { $payment_methods.eq(0).hide(); } + // If there was a previously selected method, check that one. if ( selectedPaymentMethod ) { $( '#' + selectedPaymentMethod ).prop( 'checked', true ); - } else { - // If there are none selected, select the first. - if ( 0 === $payment_methods.filter( ':checked' ).length ) { - $payment_methods.eq(0).prop( 'checked', true ); - } + } + + // If there are none selected, select the first. + if ( 0 === $payment_methods.filter( ':checked' ).length ) { + $payment_methods.eq(0).prop( 'checked', true ); } // Trigger click event for selected method diff --git a/assets/js/frontend/checkout.min.js b/assets/js/frontend/checkout.min.js index f10dce35ac4..cccd6795e65 100644 --- a/assets/js/frontend/checkout.min.js +++ b/assets/js/frontend/checkout.min.js @@ -1 +1 @@ -jQuery(function(a){if("undefined"==typeof wc_checkout_params)return!1;a.blockUI.defaults.overlayCSS.cursor="default";var b={updateTimer:!1,dirtyInput:!1,xhr:!1,$order_review:a("#order_review"),$checkout_form:a("form.checkout"),init:function(){a(document.body).bind("update_checkout",this.update_checkout),a(document.body).bind("init_checkout",this.init_checkout),this.$checkout_form.on("click",'input[name="payment_method"]',this.payment_method_selected),a(document.body).hasClass("woocommerce-order-pay")&&this.$order_review.on("click",'input[name="payment_method"]',this.payment_method_selected),this.$checkout_form.on("submit",this.submit),this.$checkout_form.on("blur change",".input-text, select, input:checkbox",this.validate_field),this.$checkout_form.on("update",this.trigger_update_checkout),this.$checkout_form.on("change",'select.shipping_method, input[name^="shipping_method"], #ship-to-different-address input, .update_totals_on_change select, .update_totals_on_change input[type="radio"]',this.trigger_update_checkout),this.$checkout_form.on("change",".address-field select",this.input_changed),this.$checkout_form.on("change",".address-field input.input-text, .update_totals_on_change input.input-text",this.maybe_input_changed),this.$checkout_form.on("change keydown",".address-field input.input-text, .update_totals_on_change input.input-text",this.queue_update_checkout),this.$checkout_form.on("change","#ship-to-different-address input",this.ship_to_different_address),this.$checkout_form.find("#ship-to-different-address input").change(),this.init_payment_methods(),"1"===wc_checkout_params.is_checkout&&a(document.body).trigger("init_checkout"),"yes"===wc_checkout_params.option_guest_checkout&&a("input#createaccount").change(this.toggle_create_account).change()},init_payment_methods:function(b){var c=a(".woocommerce-checkout").find('input[name="payment_method"]');b?a("#"+b).prop("checked",!0):(1===c.length&&c.eq(0).hide(),0===c.filter(":checked").length&&c.eq(0).prop("checked",!0)),c.filter(":checked").eq(0).trigger("click")},get_payment_method:function(){return b.$order_review.find('input[name="payment_method"]:checked').val()},payment_method_selected:function(){if(a(".payment_methods input.input-radio").length>1){var b=a("div.payment_box."+a(this).attr("ID"));a(this).is(":checked")&&!b.is(":visible")&&(a("div.payment_box").filter(":visible").slideUp(250),a(this).is(":checked")&&a("div.payment_box."+a(this).attr("ID")).slideDown(250))}else a("div.payment_box").show();a(this).data("order_button_text")?a("#place_order").val(a(this).data("order_button_text")):a("#place_order").val(a("#place_order").data("value"))},toggle_create_account:function(){a("div.create-account").hide(),a(this).is(":checked")&&a("div.create-account").slideDown()},init_checkout:function(){a("#billing_country, #shipping_country, .country_to_state").change(),a(document.body).trigger("update_checkout")},maybe_input_changed:function(a){b.dirtyInput&&b.input_changed(a)},input_changed:function(a){b.dirtyInput=a.target,b.maybe_update_checkout()},queue_update_checkout:function(a){var c=a.keyCode||a.which||0;return 9===c||(b.dirtyInput=this,b.reset_update_checkout_timer(),void(b.updateTimer=setTimeout(b.maybe_update_checkout,"1000")))},trigger_update_checkout:function(){b.reset_update_checkout_timer(),b.dirtyInput=!1,a(document.body).trigger("update_checkout")},maybe_update_checkout:function(){var c=!0;if(a(b.dirtyInput).length){var d=a(b.dirtyInput).closest("div").find(".address-field.validate-required");d.length&&d.each(function(){""===a(this).find("input.input-text").val()&&(c=!1)})}c&&b.trigger_update_checkout()},ship_to_different_address:function(){a("div.shipping_address").hide(),a(this).is(":checked")&&a("div.shipping_address").slideDown()},reset_update_checkout_timer:function(){clearTimeout(b.updateTimer)},validate_field:function(){var b=a(this),c=b.closest(".form-row"),d=!0;if(c.is(".validate-required")&&("checkbox"!==b.attr("type")||b.is(":checked")?""===b.val()&&(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-required-field"),d=!1):(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-required-field"),d=!1)),c.is(".validate-email")&&b.val()){var e=new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);e.test(b.val())||(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-email"),d=!1)}d&&c.removeClass("woocommerce-invalid woocommerce-invalid-required-field").addClass("woocommerce-validated")},update_checkout:function(a,c){b.reset_update_checkout_timer(),b.updateTimer=setTimeout(b.update_checkout_action,"5",c)},update_checkout_action:function(c){if(b.xhr&&b.xhr.abort(),0!==a("form.checkout").length){c="undefined"!=typeof c?c:{update_shipping_method:!0};var d=a("#billing_country").val(),e=a("#billing_state").val(),f=a("input#billing_postcode").val(),g=a("#billing_city").val(),h=a("input#billing_address_1").val(),i=a("input#billing_address_2").val(),j=d,k=e,l=f,m=g,n=h,o=i;a("#ship-to-different-address").find("input").is(":checked")&&(j=a("#shipping_country").val(),k=a("#shipping_state").val(),l=a("input#shipping_postcode").val(),m=a("#shipping_city").val(),n=a("input#shipping_address_1").val(),o=a("input#shipping_address_2").val());var p={security:wc_checkout_params.update_order_review_nonce,payment_method:b.get_payment_method(),country:d,state:e,postcode:f,city:g,address:h,address_2:i,s_country:j,s_state:k,s_postcode:l,s_city:m,s_address:n,s_address_2:o,post_data:a("form.checkout").serialize()};if(!1!==c.update_shipping_method){var q={};a('select.shipping_method, input[name^="shipping_method"][type="radio"]:checked, input[name^="shipping_method"][type="hidden"]').each(function(){q[a(this).data("index")]=a(this).val()}),p.shipping_method=q}a(".woocommerce-checkout-payment, .woocommerce-checkout-review-order-table").block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),b.xhr=a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","update_order_review"),data:p,success:function(c){var d=a(".woocommerce-checkout").find('input[name="payment_method"]').filter(":checked").attr("id");if("true"===c.reload)return void window.location.reload();a(".woocommerce-NoticeGroup-updateOrderReview").remove();var e=a("#terms").prop("checked");if(c&&c.fragments&&a.each(c.fragments,function(b,c){a(b).replaceWith(c),a(b).unblock()}),e&&a("#terms").prop("checked",!0),"failure"===c.result){var f=a("form.checkout");a(".woocommerce-error, .woocommerce-message").remove(),c.messages?f.prepend('
    '+c.messages+"
    "):f.prepend(c),f.find(".input-text, select, input:checkbox").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3)}b.init_payment_methods(d),a(document.body).trigger("updated_checkout")}})}},submit:function(){b.reset_update_checkout_timer();var c=a(this);if(c.is(".processing"))return!1;if(c.triggerHandler("checkout_place_order")!==!1&&c.triggerHandler("checkout_place_order_"+b.get_payment_method())!==!1){c.addClass("processing");var d=c.data();1!==d["blockUI.isBlocked"]&&c.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),a.ajaxSetup({dataFilter:function(b,c){if("json"!==c)return b;try{var d=a.parseJSON(b);if(d&&"object"==typeof d)return b}catch(e){var f=b.match(/{"result.*"}/);null===f?console.log("Unable to fix malformed JSON"):(console.log("Fixed malformed JSON. Original:"),console.log(b),b=f[0])}return b}}),a.ajax({type:"POST",url:wc_checkout_params.checkout_url,data:c.serialize(),dataType:"json",success:function(c){try{if("success"!==c.result)throw"failure"===c.result?"Result failure":"Invalid response";-1===c.redirect.indexOf("https://")||-1===c.redirect.indexOf("http://")?window.location=c.redirect:window.location=decodeURI(c.redirect)}catch(d){if("true"===c.reload)return void window.location.reload();"true"===c.refresh&&a(document.body).trigger("update_checkout"),c.messages?b.submit_error(c.messages):b.submit_error('
    '+wc_checkout_params.i18n_checkout_error+"
    ")}},error:function(a,c,d){b.submit_error('
    '+d+"
    ")}})}return!1},submit_error:function(c){a(".woocommerce-error, .woocommerce-message").remove(),b.$checkout_form.prepend(c),b.$checkout_form.removeClass("processing").unblock(),b.$checkout_form.find(".input-text, select, input:checkbox").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3),a(document.body).trigger("checkout_error")}},c={init:function(){a(document.body).on("click","a.showcoupon",this.show_coupon_form),a(document.body).on("click",".woocommerce-remove-coupon",this.remove_coupon),a("form.checkout_coupon").hide().submit(this.submit)},show_coupon_form:function(){return a(".checkout_coupon").slideToggle(400,function(){a(".checkout_coupon").find(":input:eq(0)").focus()}),!1},submit:function(){var b=a(this);if(b.is(".processing"))return!1;b.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={security:wc_checkout_params.apply_coupon_nonce,coupon_code:b.find('input[name="coupon_code"]').val()};return a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),data:c,success:function(c){a(".woocommerce-error, .woocommerce-message").remove(),b.removeClass("processing").unblock(),c&&(b.before(c),b.slideUp(),a(document.body).trigger("update_checkout",{update_shipping_method:!1}))},dataType:"html"}),!1},remove_coupon:function(b){b.preventDefault();var c=a(this).parents(".woocommerce-checkout-review-order"),d=a(this).data("coupon");c.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var e={security:wc_checkout_params.remove_coupon_nonce,coupon:d};a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","remove_coupon"),data:e,success:function(b){a(".woocommerce-error, .woocommerce-message").remove(),c.removeClass("processing").unblock(),b&&(a("form.woocommerce-checkout").before(b),a(document.body).trigger("update_checkout",{update_shipping_method:!1}),a("form.checkout_coupon").find('input[name="coupon_code"]').val(""))},error:function(a){wc_checkout_params.debug_mode&&console.log(a.responseText)},dataType:"html"})}},d={init:function(){a(document.body).on("click","a.showlogin",this.show_login_form)},show_login_form:function(){return a("form.login").slideToggle(),!1}};b.init(),c.init(),d.init()}); \ No newline at end of file +jQuery(function(a){if("undefined"==typeof wc_checkout_params)return!1;a.blockUI.defaults.overlayCSS.cursor="default";var b={updateTimer:!1,dirtyInput:!1,xhr:!1,$order_review:a("#order_review"),$checkout_form:a("form.checkout"),init:function(){a(document.body).bind("update_checkout",this.update_checkout),a(document.body).bind("init_checkout",this.init_checkout),this.$checkout_form.on("click",'input[name="payment_method"]',this.payment_method_selected),a(document.body).hasClass("woocommerce-order-pay")&&this.$order_review.on("click",'input[name="payment_method"]',this.payment_method_selected),this.$checkout_form.on("submit",this.submit),this.$checkout_form.on("blur change",".input-text, select, input:checkbox",this.validate_field),this.$checkout_form.on("update",this.trigger_update_checkout),this.$checkout_form.on("change",'select.shipping_method, input[name^="shipping_method"], #ship-to-different-address input, .update_totals_on_change select, .update_totals_on_change input[type="radio"]',this.trigger_update_checkout),this.$checkout_form.on("change",".address-field select",this.input_changed),this.$checkout_form.on("change",".address-field input.input-text, .update_totals_on_change input.input-text",this.maybe_input_changed),this.$checkout_form.on("change keydown",".address-field input.input-text, .update_totals_on_change input.input-text",this.queue_update_checkout),this.$checkout_form.on("change","#ship-to-different-address input",this.ship_to_different_address),this.$checkout_form.find("#ship-to-different-address input").change(),this.init_payment_methods(),"1"===wc_checkout_params.is_checkout&&a(document.body).trigger("init_checkout"),"yes"===wc_checkout_params.option_guest_checkout&&a("input#createaccount").change(this.toggle_create_account).change()},init_payment_methods:function(b){var c=a(".woocommerce-checkout").find('input[name="payment_method"]');1===c.length&&c.eq(0).hide(),b&&a("#"+b).prop("checked",!0),0===c.filter(":checked").length&&c.eq(0).prop("checked",!0),c.filter(":checked").eq(0).trigger("click")},get_payment_method:function(){return b.$order_review.find('input[name="payment_method"]:checked').val()},payment_method_selected:function(){if(a(".payment_methods input.input-radio").length>1){var b=a("div.payment_box."+a(this).attr("ID"));a(this).is(":checked")&&!b.is(":visible")&&(a("div.payment_box").filter(":visible").slideUp(250),a(this).is(":checked")&&a("div.payment_box."+a(this).attr("ID")).slideDown(250))}else a("div.payment_box").show();a(this).data("order_button_text")?a("#place_order").val(a(this).data("order_button_text")):a("#place_order").val(a("#place_order").data("value"))},toggle_create_account:function(){a("div.create-account").hide(),a(this).is(":checked")&&a("div.create-account").slideDown()},init_checkout:function(){a("#billing_country, #shipping_country, .country_to_state").change(),a(document.body).trigger("update_checkout")},maybe_input_changed:function(a){b.dirtyInput&&b.input_changed(a)},input_changed:function(a){b.dirtyInput=a.target,b.maybe_update_checkout()},queue_update_checkout:function(a){var c=a.keyCode||a.which||0;return 9===c||(b.dirtyInput=this,b.reset_update_checkout_timer(),void(b.updateTimer=setTimeout(b.maybe_update_checkout,"1000")))},trigger_update_checkout:function(){b.reset_update_checkout_timer(),b.dirtyInput=!1,a(document.body).trigger("update_checkout")},maybe_update_checkout:function(){var c=!0;if(a(b.dirtyInput).length){var d=a(b.dirtyInput).closest("div").find(".address-field.validate-required");d.length&&d.each(function(){""===a(this).find("input.input-text").val()&&(c=!1)})}c&&b.trigger_update_checkout()},ship_to_different_address:function(){a("div.shipping_address").hide(),a(this).is(":checked")&&a("div.shipping_address").slideDown()},reset_update_checkout_timer:function(){clearTimeout(b.updateTimer)},validate_field:function(){var b=a(this),c=b.closest(".form-row"),d=!0;if(c.is(".validate-required")&&("checkbox"!==b.attr("type")||b.is(":checked")?""===b.val()&&(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-required-field"),d=!1):(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-required-field"),d=!1)),c.is(".validate-email")&&b.val()){var e=new RegExp(/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i);e.test(b.val())||(c.removeClass("woocommerce-validated").addClass("woocommerce-invalid woocommerce-invalid-email"),d=!1)}d&&c.removeClass("woocommerce-invalid woocommerce-invalid-required-field").addClass("woocommerce-validated")},update_checkout:function(a,c){b.reset_update_checkout_timer(),b.updateTimer=setTimeout(b.update_checkout_action,"5",c)},update_checkout_action:function(c){if(b.xhr&&b.xhr.abort(),0!==a("form.checkout").length){c="undefined"!=typeof c?c:{update_shipping_method:!0};var d=a("#billing_country").val(),e=a("#billing_state").val(),f=a("input#billing_postcode").val(),g=a("#billing_city").val(),h=a("input#billing_address_1").val(),i=a("input#billing_address_2").val(),j=d,k=e,l=f,m=g,n=h,o=i;a("#ship-to-different-address").find("input").is(":checked")&&(j=a("#shipping_country").val(),k=a("#shipping_state").val(),l=a("input#shipping_postcode").val(),m=a("#shipping_city").val(),n=a("input#shipping_address_1").val(),o=a("input#shipping_address_2").val());var p={security:wc_checkout_params.update_order_review_nonce,payment_method:b.get_payment_method(),country:d,state:e,postcode:f,city:g,address:h,address_2:i,s_country:j,s_state:k,s_postcode:l,s_city:m,s_address:n,s_address_2:o,post_data:a("form.checkout").serialize()};if(!1!==c.update_shipping_method){var q={};a('select.shipping_method, input[name^="shipping_method"][type="radio"]:checked, input[name^="shipping_method"][type="hidden"]').each(function(){q[a(this).data("index")]=a(this).val()}),p.shipping_method=q}a(".woocommerce-checkout-payment, .woocommerce-checkout-review-order-table").block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),b.xhr=a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","update_order_review"),data:p,success:function(c){var d=a('.woocommerce-checkout input[name="payment_method"]:checked').attr("id");if("true"===c.reload)return void window.location.reload();a(".woocommerce-NoticeGroup-updateOrderReview").remove();var e=a("#terms").prop("checked");if(c&&c.fragments&&a.each(c.fragments,function(b,c){a(b).replaceWith(c),a(b).unblock()}),e&&a("#terms").prop("checked",!0),"failure"===c.result){var f=a("form.checkout");a(".woocommerce-error, .woocommerce-message").remove(),c.messages?f.prepend('
    '+c.messages+"
    "):f.prepend(c),f.find(".input-text, select, input:checkbox").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3)}b.init_payment_methods(d),a(document.body).trigger("updated_checkout")}})}},submit:function(){b.reset_update_checkout_timer();var c=a(this);if(c.is(".processing"))return!1;if(c.triggerHandler("checkout_place_order")!==!1&&c.triggerHandler("checkout_place_order_"+b.get_payment_method())!==!1){c.addClass("processing");var d=c.data();1!==d["blockUI.isBlocked"]&&c.block({message:null,overlayCSS:{background:"#fff",opacity:.6}}),a.ajaxSetup({dataFilter:function(b,c){if("json"!==c)return b;try{var d=a.parseJSON(b);if(d&&"object"==typeof d)return b}catch(e){var f=b.match(/{"result.*"}/);null===f?console.log("Unable to fix malformed JSON"):(console.log("Fixed malformed JSON. Original:"),console.log(b),b=f[0])}return b}}),a.ajax({type:"POST",url:wc_checkout_params.checkout_url,data:c.serialize(),dataType:"json",success:function(c){try{if("success"!==c.result)throw"failure"===c.result?"Result failure":"Invalid response";-1===c.redirect.indexOf("https://")||-1===c.redirect.indexOf("http://")?window.location=c.redirect:window.location=decodeURI(c.redirect)}catch(d){if("true"===c.reload)return void window.location.reload();"true"===c.refresh&&a(document.body).trigger("update_checkout"),c.messages?b.submit_error(c.messages):b.submit_error('
    '+wc_checkout_params.i18n_checkout_error+"
    ")}},error:function(a,c,d){b.submit_error('
    '+d+"
    ")}})}return!1},submit_error:function(c){a(".woocommerce-error, .woocommerce-message").remove(),b.$checkout_form.prepend(c),b.$checkout_form.removeClass("processing").unblock(),b.$checkout_form.find(".input-text, select, input:checkbox").blur(),a("html, body").animate({scrollTop:a("form.checkout").offset().top-100},1e3),a(document.body).trigger("checkout_error")}},c={init:function(){a(document.body).on("click","a.showcoupon",this.show_coupon_form),a(document.body).on("click",".woocommerce-remove-coupon",this.remove_coupon),a("form.checkout_coupon").hide().submit(this.submit)},show_coupon_form:function(){return a(".checkout_coupon").slideToggle(400,function(){a(".checkout_coupon").find(":input:eq(0)").focus()}),!1},submit:function(){var b=a(this);if(b.is(".processing"))return!1;b.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var c={security:wc_checkout_params.apply_coupon_nonce,coupon_code:b.find('input[name="coupon_code"]').val()};return a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","apply_coupon"),data:c,success:function(c){a(".woocommerce-error, .woocommerce-message").remove(),b.removeClass("processing").unblock(),c&&(b.before(c),b.slideUp(),a(document.body).trigger("update_checkout",{update_shipping_method:!1}))},dataType:"html"}),!1},remove_coupon:function(b){b.preventDefault();var c=a(this).parents(".woocommerce-checkout-review-order"),d=a(this).data("coupon");c.addClass("processing").block({message:null,overlayCSS:{background:"#fff",opacity:.6}});var e={security:wc_checkout_params.remove_coupon_nonce,coupon:d};a.ajax({type:"POST",url:wc_checkout_params.wc_ajax_url.toString().replace("%%endpoint%%","remove_coupon"),data:e,success:function(b){a(".woocommerce-error, .woocommerce-message").remove(),c.removeClass("processing").unblock(),b&&(a("form.woocommerce-checkout").before(b),a(document.body).trigger("update_checkout",{update_shipping_method:!1}),a("form.checkout_coupon").find('input[name="coupon_code"]').val(""))},error:function(a){wc_checkout_params.debug_mode&&console.log(a.responseText)},dataType:"html"})}},d={init:function(){a(document.body).on("click","a.showlogin",this.show_login_form)},show_login_form:function(){return a("form.login").slideToggle(),!1}};b.init(),c.init(),d.init()}); \ No newline at end of file From 267e5cba9aac8f0738c55ba018ecdcbdb500bc35 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 09:14:03 -0600 Subject: [PATCH 215/298] Add initial Shipping Zones REST API controller, with zone schema definition method. --- ...lass-wc-rest-shipping-zones-controller.php | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 includes/api/class-wc-rest-shipping-zones-controller.php diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php new file mode 100644 index 00000000000..baa8e88254a --- /dev/null +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -0,0 +1,79 @@ + 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone', + 'type' => 'object', + 'properties' => array( + 'id' => array( + 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'readonly' => true, + ), + 'name' => array( + 'description' => __( 'Shipping zone name.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'required' => true, + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'order' => array( + 'description' => __( 'Shipping zone order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'required' => false, + 'arg_options' => array( + 'sanitize_callback' => 'absint', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } +} From 0de6f42b51613210ffe395a15b9cccd850ac61c4 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 10:33:25 -0600 Subject: [PATCH 216/298] Create GET route for shipping zones, handling case where shipping calculations are disabled. --- ...lass-wc-rest-shipping-zones-controller.php | 32 +++++++++++++++++++ includes/class-wc-api.php | 1 + 2 files changed, 33 insertions(+) diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index baa8e88254a..9bccef8eead 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -36,6 +36,38 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Controller { */ protected $rest_base = 'shipping/zones'; + /** + * Register the routes for Shipping Zones. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base, array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Check whether a given request has permission to read Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function get_items_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + /** * Get the Shipping Zones schema, conforming to JSON Schema * diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index c7557a4d376..cc76cf7dbf4 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -197,6 +197,7 @@ class WC_API extends WC_Legacy_API { 'WC_REST_Reports_Controller', 'WC_REST_Settings_Controller', 'WC_REST_Settings_Options_Controller', + 'WC_REST_Shipping_Zones_Controller', 'WC_REST_Tax_Classes_Controller', 'WC_REST_Taxes_Controller', 'WC_REST_Webhook_Deliveries_Controller', From fd042b88cf7089af9454781ffe9cbd3eaa539cf6 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 11:21:23 -0600 Subject: [PATCH 217/298] Implement get_items() for Shipping Zones endpoint. --- ...lass-wc-rest-shipping-zones-controller.php | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index 9bccef8eead..99c9baedd36 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -50,6 +50,71 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Controller { ) ); } + /** + * Get all Shipping Zones. + * + * @param WP_REST_Request $request + * @return WP_REST_Response + */ + public function get_items( $request ) { + $zones = WC_Shipping_Zones::get_zones(); + $data = array(); + + foreach ( $zones as $zone_obj ) { + $zone = $this->prepare_item_for_response( $zone_obj, $request ); + $zone = $this->prepare_response_for_collection( $zone ); + $data[] = $zone; + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare the Shipping Zone for the REST response. + * + * @param array $item Shipping Zone. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $data = array( + 'id' => $item['zone_id'], + 'name' => $item['zone_name'], + 'order' => $item['zone_order'], + ); + + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $data, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $data['id'] ) ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param int $zone_id Given Shipping Zone ID. + * @return array Links for the given Shipping Zone. + */ + protected function prepare_links( $zone_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base; + $links = array( + 'self' => array( + 'href' => rest_url( trailingslashit( $base ) . $zone_id ), + ), + 'collection' => array( + 'href' => rest_url( $base ), + ), + ); + + return $links; + } + /** * Check whether a given request has permission to read Shipping Zones. * From 039f5d2300059057c746d8754a902478ad7ab5ae Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 11:43:54 -0600 Subject: [PATCH 218/298] Add route and handler for retrieving single Shipping Zones. --- ...lass-wc-rest-shipping-zones-controller.php | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index 99c9baedd36..9512c24630c 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -48,6 +48,35 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Controller { ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Get a single Shipping Zone. + * + * @param WP_REST_Request $request + * @return WP_REST_Response + */ + public function get_item( $request ) { + $zone = WC_Shipping_Zones::get_zone_by( 'zone_id', $request['id'] ); + + if ( false === $zone ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_invalid', __( "Resource doesn't exist.", 'woocommerce' ), array( 'status' => 404 ) ); + } + + $data = $zone->get_data(); + $data = $this->prepare_item_for_response( $data, $request ); + $data = $this->prepare_response_for_collection( $data ); + + return rest_ensure_response( $data ); } /** From 69a40b06480bdff3a92ad37f06e4c45a607e4d36 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 14:15:14 -0600 Subject: [PATCH 219/298] Refactor Shipping Zone retrieval into a reusable method. --- ...lass-wc-rest-shipping-zones-controller.php | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index 9512c24630c..3d56a7ff7b5 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -59,6 +59,22 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Controller { ) ); } + /** + * Retrieve a Shipping Zone by it's ID. + * + * @param int $zone_id Shipping Zone ID. + * @return WC_Shipping_Zone|WP_Error + */ + protected function get_zone( $zone_id ) { + $zone = WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id ); + + if ( false === $zone ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_invalid', __( "Resource doesn't exist.", 'woocommerce' ), array( 'status' => 404 ) ); + } + + return $zone; + } + /** * Get a single Shipping Zone. * @@ -66,10 +82,10 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Controller { * @return WP_REST_Response */ public function get_item( $request ) { - $zone = WC_Shipping_Zones::get_zone_by( 'zone_id', $request['id'] ); + $zone = $this->get_zone( $request->get_param( 'id' ) ); - if ( false === $zone ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_invalid', __( "Resource doesn't exist.", 'woocommerce' ), array( 'status' => 404 ) ); + if ( is_wp_error( $zone ) ) { + return $zone; } $data = $zone->get_data(); From 14807419980ba20a851bc6236022c503c0a081ad Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 14:15:56 -0600 Subject: [PATCH 220/298] Cast returned zone ID and order as integers. --- includes/api/class-wc-rest-shipping-zones-controller.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index 3d56a7ff7b5..d30765967b7 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -123,9 +123,9 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Controller { */ public function prepare_item_for_response( $item, $request ) { $data = array( - 'id' => $item['zone_id'], + 'id' => (int) $item['zone_id'], 'name' => $item['zone_name'], - 'order' => $item['zone_order'], + 'order' => (int) $item['zone_order'], ); $context = empty( $request['context'] ) ? 'view' : $request['context']; From 29e150612f1ad1bbe51c2377ccef7f999ffe0c30 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 14:16:14 -0600 Subject: [PATCH 221/298] Add update shipping zone endpoint and handler. --- ...lass-wc-rest-shipping-zones-controller.php | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index d30765967b7..df31f671a1a 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -55,6 +55,12 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Controller { 'callback' => array( $this, 'get_item' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } @@ -114,6 +120,38 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Controller { return rest_ensure_response( $data ); } + /** + * Update a single Shipping Zone. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function update_item( $request ) { + $zone = $this->get_zone( $request->get_param( 'id' ) ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $zone_changed = false; + + if ( ! is_null( $request->get_param( 'name' ) ) ) { + $zone->set_zone_name( $request->get_param( 'name' ) ); + $zone_changed = true; + } + + if ( ! is_null( $request->get_param( 'order' ) ) ) { + $zone->set_zone_order( $request->get_param( 'order' ) ); + $zone_changed = true; + } + + if ( $zone_changed ) { + $zone->save(); + } + + return $this->get_item( $request ); + } + /** * Prepare the Shipping Zone for the REST response. * From 5718e66b2c064d02f8befffc04f242a9259a781e Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 15:01:49 -0600 Subject: [PATCH 222/298] Add create shipping zone endpoint and handler. --- ...lass-wc-rest-shipping-zones-controller.php | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index df31f671a1a..8760415ad0c 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -46,6 +46,12 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Controller { 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), + ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); @@ -120,6 +126,29 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Controller { return rest_ensure_response( $data ); } + /** + * Create a single Shipping Zone. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_REST_Request|WP_Error + */ + public function create_item( $request ) { + $zone = new WC_Shipping_Zone( null ); + + if ( ! is_null( $request->get_param( 'name' ) ) ) { + $zone->set_zone_name( $request->get_param( 'name' ) ); + } + + if ( ! is_null( $request->get_param( 'order' ) ) ) { + $zone->set_zone_order( $request->get_param( 'order' ) ); + } + + $zone->create(); + $request->set_param( 'id', $zone->get_id() ); + + return $this->get_item( $request ); + } + /** * Update a single Shipping Zone. * From 2267e62fe041302602ef68ffb2cad1edc5f9fdc8 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 15:53:22 -0600 Subject: [PATCH 223/298] Add REST API testing bootstrap. --- tests/bootstrap.php | 6 +++ .../class-wp-test-spy-rest-server.php | 38 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 tests/framework/class-wp-test-spy-rest-server.php diff --git a/tests/bootstrap.php b/tests/bootstrap.php index d0dede09717..1669508e84f 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -115,6 +115,12 @@ class WC_Unit_Tests_Bootstrap { require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-shipping-zones.php' ); require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-payment-token.php' ); require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-settings.php' ); + + /** + * WP-API + * @todo to be removed when the wp-api branch is merged. + */ + require_once( $this->tests_dir . '/framework/class-wp-test-spy-rest-server.php' ); } /** diff --git a/tests/framework/class-wp-test-spy-rest-server.php b/tests/framework/class-wp-test-spy-rest-server.php new file mode 100644 index 00000000000..76694902b83 --- /dev/null +++ b/tests/framework/class-wp-test-spy-rest-server.php @@ -0,0 +1,38 @@ +endpoints; + } + + /** + * Allow calling protected methods from tests + * + * @param string $method Method to call + * @param array $args Arguments to pass to the method + * @return mixed + */ + public function __call( $method, $args ) { + return call_user_func_array( array( $this, $method ), $args ); + } + + /** + * Call dispatch() with the rest_post_dispatch filter + */ + public function dispatch( $request ) { + $result = parent::dispatch( $request ); + $result = rest_ensure_response( $result ); + if ( is_wp_error( $result ) ) { + $result = $this->error_to_response( $result ); + } + return apply_filters( 'rest_post_dispatch', rest_ensure_response( $result ), $this, $request ); + } +} \ No newline at end of file From 2a7e81a80934b3fa53efda939e1468ea808ded2d Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 16:36:25 -0600 Subject: [PATCH 224/298] Initial Shipping Zones unit test coverage, testing route registration. --- tests/unit-tests/api/shipping-zones.php | 54 +++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 tests/unit-tests/api/shipping-zones.php diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php new file mode 100644 index 00000000000..e9e328083f8 --- /dev/null +++ b/tests/unit-tests/api/shipping-zones.php @@ -0,0 +1,54 @@ +server = $wp_rest_server = new WP_Test_Spy_REST_Server; + do_action( 'rest_api_init' ); + $this->endpoint = new WC_REST_Shipping_Zones_Controller(); + $this->user = $this->factory->user->create( array( + 'role' => 'administrator', + ) ); + $this->zones = array(); + } + + /** + * Unset the server. + */ + public function tearDown() { + parent::tearDown(); + global $wp_rest_server; + $wp_rest_server = null; + foreach( $this->zones as $zone ) { + $zone->delete(); + } + } + + /** + * Test route registration. + * @since 2.7.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v1/shipping/zones', $routes ); + $this->assertArrayHasKey( '/wc/v1/shipping/zones/(?P[\d-]+)', $routes ); + } +} \ No newline at end of file From bbe5ffc295ede8a5a817ce85bb662508027b4dba Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 16:43:17 -0600 Subject: [PATCH 225/298] Add helper method to create shipping zones during testing. --- tests/unit-tests/api/shipping-zones.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index e9e328083f8..b1625e0bd68 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -42,6 +42,24 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { } } + /** + * Helper method to create a Shipping Zone. + * + * @param string $name Zone name. + * @param int $order Optional. Zone sort order. + * @return WC_Shipping_Zone + */ + protected function create_shipping_zone( $name, $order = 0 ) { + $zone = new WC_Shipping_Zone( null ); + $zone->set_zone_name( $name ); + $zone->set_zone_order( $order ); + $zone->save(); + + $this->zones[] = $zone; + + return $zone; + } + /** * Test route registration. * @since 2.7.0 From e4ccede35fa2ef5cf64ae905cef0beb3efd92b2f Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 16:44:10 -0600 Subject: [PATCH 226/298] Test coverage for /shipping/zones. Covers success, shipping disabled, and insufficient permissions cases. --- tests/unit-tests/api/shipping-zones.php | 67 +++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index b1625e0bd68..4f0432c9855 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -69,4 +69,71 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { $this->assertArrayHasKey( '/wc/v1/shipping/zones', $routes ); $this->assertArrayHasKey( '/wc/v1/shipping/zones/(?P[\d-]+)', $routes ); } + + /** + * Test getting all Shipping Zones. + * @since 2.7.0 + */ + public function test_get_zones() { + wp_set_current_user( $this->user ); + + // No zones by default + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 0 ); + + // Create a zone and make sure it's in the response + $this->create_shipping_zone( 'Zone 1' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 1 ); + $this->assertEquals( array( + 'id' => 1, + 'name' => 'Zone 1', + 'order' => 0, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/1' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones' ), + ), + ), + ), + ), $data[0] ); + } + + /** + * Test /shipping/zones without valid permissions/creds. + * @since 2.7.0 + */ + public function test_get_shipping_zones_without_permission() { + wp_set_current_user( 0 ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test /shipping/zones while Shipping is disabled in WooCommerce. + * @since 2.7.0 + */ + public function test_get_shipping_zones_disabled_shipping() { + wp_set_current_user( $this->user ); + + add_filter( 'wc_shipping_enabled', '__return_false' ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones' ) ); + $this->assertEquals( 404, $response->get_status() ); + + remove_filter( 'wc_shipping_enabled', '__return_false' ); + } } \ No newline at end of file From 3492f397d46785386f011d88423708d1ce4e4f67 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 16:57:35 -0600 Subject: [PATCH 227/298] Add test coverage for shipping zone schema endpoint. --- tests/unit-tests/api/shipping-zones.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index 4f0432c9855..b44795b9e3c 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -136,4 +136,22 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { remove_filter( 'wc_shipping_enabled', '__return_false' ); } + + /** + * Test Shipping Zone schema. + * @since 2.7.0 + */ + public function test_get_shipping_zone_schema() { + $request = new WP_REST_Request( 'OPTIONS', '/wc/v1/shipping/zones' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + $this->assertEquals( 3, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertTrue( $properties['id']['readonly'] ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertTrue( $properties['name']['required'] ); + $this->assertArrayHasKey( 'order', $properties ); + $this->assertFalse( $properties['order']['required'] ); + } } \ No newline at end of file From e037cf661ecb36ad9792086f685519fb0ee426d7 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 17:06:47 -0600 Subject: [PATCH 228/298] Add test coverage to shipping zone creation endpoint. --- tests/unit-tests/api/shipping-zones.php | 35 +++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index b44795b9e3c..0b340c32171 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -154,4 +154,39 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { $this->assertArrayHasKey( 'order', $properties ); $this->assertFalse( $properties['order']['required'] ); } + + /** + * Test Shipping Zone create endpoint. + * @since 2.7.0 + */ + public function test_create_shipping_zone() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'POST', '/wc/v1/shipping/zones' ); + $request->set_body_params( array( + 'name' => 'Test Zone', + 'order' => 1, + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( array( + 'id' => $data['id'], + 'name' => 'Test Zone', + 'order' => 1, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $data['id'] ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones' ), + ), + ), + ), + ), $data ); + } } \ No newline at end of file From 6a9ba5b9f3afdeb05347c550327b784c5cce6275 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 17:15:16 -0600 Subject: [PATCH 229/298] Add test coverage for shipping zone update endpoint. --- tests/unit-tests/api/shipping-zones.php | 54 +++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index 0b340c32171..82f7797f17e 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -189,4 +189,58 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { ), ), $data ); } + + /** + * Test Shipping Zone update endpoint. + * @since 2.7.0 + */ + public function test_update_shipping_zone() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Test Zone' ); + + $request = new WP_REST_Request( 'PUT', '/wc/v1/shipping/zones/' . $zone->get_id() ); + $request->set_body_params( array( + 'name' => 'Zone Test', + 'order' => 2, + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( array( + 'id' => $zone->get_id(), + 'name' => 'Zone Test', + 'order' => 2, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $zone->get_id() ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones' ), + ), + ), + ), + ), $data ); + } + + /** + * Test Shipping Zone update endpoint with a bad zone ID. + * @since 2.7.0 + */ + public function test_update_shipping_zone_invalid_id() { + wp_set_current_user( $this->user ); + + $request = new WP_REST_Request( 'PUT', '/wc/v1/shipping/zones/1' ); + $request->set_body_params( array( + 'name' => 'Zone Test', + 'order' => 2, + ) ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 404, $response->get_status() ); + } } \ No newline at end of file From 9b564b87b162e55b5dcd3d25b044dd7d74a58616 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Tue, 14 Jun 2016 17:25:12 -0600 Subject: [PATCH 230/298] Add test coverage to single shipping zone retrieval endpoint. --- tests/unit-tests/api/shipping-zones.php | 43 +++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index 82f7797f17e..9c49f70da61 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -243,4 +243,47 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { $this->assertEquals( 404, $response->get_status() ); } + + /** + * Test getting a single Shipping Zone. + * @since 2.7.0 + */ + public function test_get_single_shipping_zone() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Test Zone' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones/' . $zone->get_id() ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( array( + 'id' => $zone->get_id(), + 'name' => 'Test Zone', + 'order' => 0, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $zone->get_id() ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones' ), + ), + ), + ), + ), $data ); + } + + /** + * Test getting a single Shipping Zone with a bad zone ID. + * @since 2.7.0 + */ + public function test_get_single_shipping_zone_invalid_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones/1' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } } \ No newline at end of file From 7a142af215f326e46d205899fe51c47fd340bea5 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 15 Jun 2016 09:38:26 -0600 Subject: [PATCH 231/298] Initial Shipping Zone Locations endpoint controller, with schema. --- ...est-shipping-zone-locations-controller.php | 80 +++++++++++++++++++ includes/class-wc-api.php | 3 + 2 files changed, 83 insertions(+) create mode 100644 includes/api/class-wc-rest-shipping-zone-locations-controller.php diff --git a/includes/api/class-wc-rest-shipping-zone-locations-controller.php b/includes/api/class-wc-rest-shipping-zone-locations-controller.php new file mode 100644 index 00000000000..7ec9e86c75f --- /dev/null +++ b/includes/api/class-wc-rest-shipping-zone-locations-controller.php @@ -0,0 +1,80 @@ +/locations endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce/API + * @since 2.7.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Shipping Zone Locations class. + * + * @package WooCommerce/API + * @extends WC_REST_Controller + */ +class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Controller { + + /** + * Endpoint namespace. + * + * @var string + */ + protected $namespace = 'wc/v1'; + + /** + * Route base. + * + * @var string + */ + protected $rest_base = 'shipping/zones'; + + /** + * Get the Shipping Zone Locations schema, conforming to JSON Schema + * + * @return array + */ + public function get_item_schema() { + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone_location', + 'type' => 'object', + 'properties' => array( + 'code' => array( + 'description' => __( 'Shipping zone location code.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'required' => true, + 'arg_options' => array( + 'sanitize_callback' => 'sanitize_text_field', + ), + ), + 'type' => array( + 'description' => __( 'Shipping zone location type.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + 'required' => true, + 'arg_options' => array( + 'sanitize_callback' => 'absint', + ), + 'enum' => array( + 'postcode', + 'state', + 'country', + 'continent', + ), + ), + ), + ); + + return $this->add_additional_fields_schema( $schema ); + } + +} \ No newline at end of file diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index cc76cf7dbf4..e37d0caca1a 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -163,6 +163,8 @@ class WC_API extends WC_Legacy_API { include_once( dirname( __FILE__ ) . '/api/class-wc-rest-reports-controller.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-settings-controller.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-settings-options-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-shipping-zones-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-shipping-zone-locations-controller.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-tax-classes-controller.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-taxes-controller.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-webhook-deliveries.php' ); @@ -198,6 +200,7 @@ class WC_API extends WC_Legacy_API { 'WC_REST_Settings_Controller', 'WC_REST_Settings_Options_Controller', 'WC_REST_Shipping_Zones_Controller', + 'WC_REST_Shipping_Zone_Locations_Controller', 'WC_REST_Tax_Classes_Controller', 'WC_REST_Taxes_Controller', 'WC_REST_Webhook_Deliveries_Controller', From 56ef4426240c0b18c254163758e30fa55b68fa2e Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 15 Jun 2016 10:14:06 -0600 Subject: [PATCH 232/298] Move common methods to an abstract base shipping zones controller class. --- ...ract-wc-rest-shipping-zones-controller.php | 72 +++++++++++++++++++ ...est-shipping-zone-locations-controller.php | 2 +- ...lass-wc-rest-shipping-zones-controller.php | 58 ++------------- includes/class-wc-api.php | 1 + 4 files changed, 79 insertions(+), 54 deletions(-) create mode 100644 includes/abstracts/abstract-wc-rest-shipping-zones-controller.php diff --git a/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php b/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php new file mode 100644 index 00000000000..141493818a1 --- /dev/null +++ b/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php @@ -0,0 +1,72 @@ + 404 ) ); + } + + return $zone; + } + + /** + * Check whether a given request has permission to access Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } +} \ No newline at end of file diff --git a/includes/api/class-wc-rest-shipping-zone-locations-controller.php b/includes/api/class-wc-rest-shipping-zone-locations-controller.php index 7ec9e86c75f..279df514fdd 100644 --- a/includes/api/class-wc-rest-shipping-zone-locations-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-locations-controller.php @@ -20,7 +20,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @package WooCommerce/API * @extends WC_REST_Controller */ -class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Controller { +class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_Controller_Base { /** * Endpoint namespace. diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index 8760415ad0c..ba1b2deecc5 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -20,21 +20,7 @@ if ( ! defined( 'ABSPATH' ) ) { * @package WooCommerce/API * @extends WC_REST_Controller */ -class WC_REST_Shipping_Zones_Controller extends WC_REST_Controller { - - /** - * Endpoint namespace. - * - * @var string - */ - protected $namespace = 'wc/v1'; - - /** - * Route base. - * - * @var string - */ - protected $rest_base = 'shipping/zones'; +class WC_REST_Shipping_Zones_Controller extends WC_REST_Shipping_Zones_Controller_Base { /** * Register the routes for Shipping Zones. @@ -44,12 +30,12 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Controller { array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'permission_callback' => array( $this, 'permissions_check' ), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), @@ -59,34 +45,18 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Controller { array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'permission_callback' => array( $this, 'permissions_check' ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'get_items_permissions_check' ), + 'permission_callback' => array( $this, 'permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } - /** - * Retrieve a Shipping Zone by it's ID. - * - * @param int $zone_id Shipping Zone ID. - * @return WC_Shipping_Zone|WP_Error - */ - protected function get_zone( $zone_id ) { - $zone = WC_Shipping_Zones::get_zone_by( 'zone_id', $zone_id ); - - if ( false === $zone ) { - return new WP_Error( 'woocommerce_rest_shipping_zone_invalid', __( "Resource doesn't exist.", 'woocommerce' ), array( 'status' => 404 ) ); - } - - return $zone; - } - /** * Get a single Shipping Zone. * @@ -227,24 +197,6 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Controller { return $links; } - /** - * Check whether a given request has permission to read Shipping Zones. - * - * @param WP_REST_Request $request Full details about the request. - * @return WP_Error|boolean - */ - public function get_items_permissions_check( $request ) { - if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.' ), array( 'status' => 404 ) ); - } - - if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot list resources.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); - } - - return true; - } - /** * Get the Shipping Zones schema, conforming to JSON Schema * diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index e37d0caca1a..cd395ac2793 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -144,6 +144,7 @@ class WC_API extends WC_Legacy_API { include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-terms-controller.php' ); include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-settings-api.php' ); + // REST API controllers. include_once( dirname( __FILE__ ) . '/api/class-wc-rest-coupons-controller.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-customer-downloads-controller.php' ); From 96c18abb8dde90cd9428baecc6616ac47c8bdfc1 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 15 Jun 2016 12:51:16 -0600 Subject: [PATCH 233/298] Add shipping zone locations retrieval endpoint. --- ...est-shipping-zone-locations-controller.php | 79 +++++++++++++++++-- 1 file changed, 72 insertions(+), 7 deletions(-) diff --git a/includes/api/class-wc-rest-shipping-zone-locations-controller.php b/includes/api/class-wc-rest-shipping-zone-locations-controller.php index 279df514fdd..b152445f516 100644 --- a/includes/api/class-wc-rest-shipping-zone-locations-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-locations-controller.php @@ -23,18 +23,83 @@ if ( ! defined( 'ABSPATH' ) ) { class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_Controller_Base { /** - * Endpoint namespace. - * - * @var string + * Register the routes for Shipping Zone Locations. */ - protected $namespace = 'wc/v1'; + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d-]+)/locations', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } /** - * Route base. + * Get all Shipping Zones. * - * @var string + * @param WP_REST_Request $request + * @return WP_REST_Response */ - protected $rest_base = 'shipping/zones'; + public function get_items( $request ) { + $zone = $this->get_zone( $request['id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $locations = $zone->get_zone_locations(); + $data = array(); + + foreach ( $locations as $location_obj ) { + $location = $this->prepare_item_for_response( $location_obj, $request ); + $location = $this->prepare_response_for_collection( $location ); + $data[] = $location; + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare the Shipping Zone Location for the REST response. + * + * @param array $item Shipping Zone Location. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $item, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + $response->add_links( $this->prepare_links( $request['id'] ) ); + + return $response; + } + + /** + * Prepare links for the request. + * + * @param int $zone_id Given Shipping Zone ID. + * @return array Links for the given Shipping Zone Location. + */ + protected function prepare_links( $zone_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id; + $links = array( + 'collection' => array( + 'href' => rest_url( $base . '/locations' ), + ), + 'describes' => array( + 'href' => rest_url( $base ), + ), + ); + + return $links; + } /** * Get the Shipping Zone Locations schema, conforming to JSON Schema From 9946d028f2053d51882723fb7f88fb53d09ca83a Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 15 Jun 2016 12:51:48 -0600 Subject: [PATCH 234/298] =?UTF-8?q?Add=20=E2=80=9Cdescribed=20by=E2=80=9D?= =?UTF-8?q?=20link=20to=20shipping=20zones=20endpoint=20response.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...lass-wc-rest-shipping-zones-controller.php | 3 +++ tests/unit-tests/api/shipping-zones.php | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index ba1b2deecc5..d9748543053 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -192,6 +192,9 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Shipping_Zones_Controlle 'collection' => array( 'href' => rest_url( $base ), ), + 'describedby' => array( + 'href' => rest_url( trailingslashit( $base ) . $zone_id . '/locations' ), + ), ); return $links; diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index 9c49f70da61..29cb5692d3d 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -107,6 +107,11 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { 'href' => rest_url( '/wc/v1/shipping/zones' ), ), ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/1/locations' ), + ), + ), ), ), $data[0] ); } @@ -186,6 +191,11 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { 'href' => rest_url( '/wc/v1/shipping/zones' ), ), ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $data['id'] . '/locations' ), + ), + ), ), ), $data ); } @@ -223,6 +233,11 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { 'href' => rest_url( '/wc/v1/shipping/zones' ), ), ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), ), ), $data ); } @@ -271,6 +286,11 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { 'href' => rest_url( '/wc/v1/shipping/zones' ), ), ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), ), ), $data ); } From c041e69e86667b2c10db7e477451bfd67e508a2c Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 15 Jun 2016 14:18:16 -0600 Subject: [PATCH 235/298] Correct locations schema, should be an array of location objects. --- ...ss-wc-rest-shipping-zone-locations-controller.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/includes/api/class-wc-rest-shipping-zone-locations-controller.php b/includes/api/class-wc-rest-shipping-zone-locations-controller.php index b152445f516..aa2c3ed3522 100644 --- a/includes/api/class-wc-rest-shipping-zone-locations-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-locations-controller.php @@ -107,9 +107,7 @@ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_ * @return array */ public function get_item_schema() { - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'shipping_zone_location', + $single_location_schema = array( 'type' => 'object', 'properties' => array( 'code' => array( @@ -138,8 +136,14 @@ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_ ), ), ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone_locations', + 'type' => 'array', + 'items' => $this->add_additional_fields_schema( $single_location_schema ) + ); - return $this->add_additional_fields_schema( $schema ); + return $schema; } } \ No newline at end of file From 626819f9b855834d2d29138b79abf098dfa490a8 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 15 Jun 2016 14:18:35 -0600 Subject: [PATCH 236/298] Add shipping zone locations update endpoint and handler. --- ...est-shipping-zone-locations-controller.php | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/includes/api/class-wc-rest-shipping-zone-locations-controller.php b/includes/api/class-wc-rest-shipping-zone-locations-controller.php index aa2c3ed3522..c32ca281242 100644 --- a/includes/api/class-wc-rest-shipping-zone-locations-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-locations-controller.php @@ -32,15 +32,21 @@ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_ 'callback' => array( $this, 'get_items' ), 'permission_callback' => array( $this, 'permissions_check' ), ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_items' ), + 'permission_callback' => array( $this, 'permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } /** - * Get all Shipping Zones. + * Get all Shipping Zone Locations. * * @param WP_REST_Request $request - * @return WP_REST_Response + * @return WP_REST_Response|WP_Error */ public function get_items( $request ) { $zone = $this->get_zone( $request['id'] ); @@ -61,6 +67,35 @@ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_ return rest_ensure_response( $data ); } + /** + * Update all Shipping Zone Locations. + * + * @param WP_REST_Request $request + * @return WP_REST_Response|WP_Error + */ + public function update_items( $request ) { + $zone = $this->get_zone( $request['id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $raw_locations = $request->get_json_params(); + $locations = array(); + + foreach ( $raw_locations as $raw_location ) { + if ( empty( $raw_location['code'] ) || empty( $raw_location['type'] ) ) { + continue; + } + $locations[] = $raw_location; + } + + $zone->set_locations( $locations ); + $zone->save(); + + return $this->get_items( $request ); + } + /** * Prepare the Shipping Zone Location for the REST response. * From 0db15c5328dc39238aa3dc611d9849dbefda5017 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 15 Jun 2016 15:24:56 -0600 Subject: [PATCH 237/298] Add test coverage for shipping zone locations retrieval endpoint. --- tests/unit-tests/api/shipping-zones.php | 44 ++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index 29cb5692d3d..65dd4d7428a 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -49,10 +49,11 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { * @param int $order Optional. Zone sort order. * @return WC_Shipping_Zone */ - protected function create_shipping_zone( $name, $order = 0 ) { + protected function create_shipping_zone( $name, $order = 0, $locations = array() ) { $zone = new WC_Shipping_Zone( null ); $zone->set_zone_name( $name ); $zone->set_zone_order( $order ); + $zone->set_locations( $locations ); $zone->save(); $this->zones[] = $zone; @@ -68,6 +69,7 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { $routes = $this->server->get_routes(); $this->assertArrayHasKey( '/wc/v1/shipping/zones', $routes ); $this->assertArrayHasKey( '/wc/v1/shipping/zones/(?P[\d-]+)', $routes ); + $this->assertArrayHasKey( '/wc/v1/shipping/zones/(?P[\d-]+)/locations', $routes ); } /** @@ -306,4 +308,44 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { $this->assertEquals( 404, $response->get_status() ); } + + /** + * Test getting Shipping Zone Locations. + * @since 2.7.0 + */ + public function test_get_locations() { + wp_set_current_user( $this->user ); + + // Create a zone + $zone = $this->create_shipping_zone( 'Zone 1', 0, array( + array( + 'code' => 'US', + 'type' => 'country', + ), + ) ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones/' . $zone->get_id() . '/locations' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 1 ); + $this->assertEquals( array( + array( + 'code' => 'US', + 'type' => 'country', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + ), $data ); + } } \ No newline at end of file From e5fac4911e54012f43579f21feec769dc587901e Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 15 Jun 2016 15:47:57 -0600 Subject: [PATCH 238/298] Test coverage for requesting shipping zone locations with an invalid ID. --- tests/unit-tests/api/shipping-zones.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index 65dd4d7428a..10057f76261 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -348,4 +348,16 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { ), ), $data ); } + + /** + * Test getting Shipping Zone Locations with a bad zone ID. + * @since 2.7.0 + */ + public function test_get_locations_invalid_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones/1/locations' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } } \ No newline at end of file From 6d891e1247edec2b16960ee756a4a8f68f90428d Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 15 Jun 2016 16:22:57 -0600 Subject: [PATCH 239/298] Handle case where no locations are sent in update request. --- .../api/class-wc-rest-shipping-zone-locations-controller.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/api/class-wc-rest-shipping-zone-locations-controller.php b/includes/api/class-wc-rest-shipping-zone-locations-controller.php index c32ca281242..8cd35fc1422 100644 --- a/includes/api/class-wc-rest-shipping-zone-locations-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-locations-controller.php @@ -83,7 +83,7 @@ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_ $raw_locations = $request->get_json_params(); $locations = array(); - foreach ( $raw_locations as $raw_location ) { + foreach ( (array) $raw_locations as $raw_location ) { if ( empty( $raw_location['code'] ) || empty( $raw_location['type'] ) ) { continue; } From b9a0367cfa1e4bf1890c05627f9c7deff464d17c Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Wed, 15 Jun 2016 16:23:10 -0600 Subject: [PATCH 240/298] Test coverage for update shipping zone locations endpoint. --- tests/unit-tests/api/shipping-zones.php | 79 +++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index 10057f76261..6e44ae550c0 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -360,4 +360,83 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { $this->assertEquals( 404, $response->get_status() ); } + + /** + * Test Shipping Zone Locations update endpoint. + * @since 2.7.0 + */ + public function test_update_locations() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Test Zone' ); + + $request = new WP_REST_Request( 'PUT', '/wc/v1/shipping/zones/' . $zone->get_id() . '/locations' ); + $request->add_header( 'Content-Type', 'application/json' ); + $request->set_body( json_encode( array( + array( + 'code' => 'UK', + 'type' => 'country', + ), + array( + 'code' => 'US', // test that locations missing "type" aren't saved + ), + array( + 'code' => 'SW1A0AA', + 'type' => 'postcode', + ), + array( + 'type' => 'continent', // test that locations missing "code" aren't saved + ), + ) ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( count( $data ), 2 ); + $this->assertEquals( array( + array( + 'code' => 'UK', + 'type' => 'country', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + array( + 'code' => 'SW1A0AA', + 'type' => 'postcode', + '_links' => array( + 'collection' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $zone->get_id() . '/locations' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), + ), $data ); + } + + /** + * Test updating Shipping Zone Locations with a bad zone ID. + * @since 2.7.0 + */ + public function test_update_locations_invalid_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'PUT', '/wc/v1/shipping/zones/1/locations' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } } \ No newline at end of file From 5d147ae287f4f0104293098e61881058a369206c Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 09:26:01 -0600 Subject: [PATCH 241/298] Fix @extends annotation in shipping zone controller classes. --- .../api/class-wc-rest-shipping-zone-locations-controller.php | 2 +- includes/api/class-wc-rest-shipping-zones-controller.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/api/class-wc-rest-shipping-zone-locations-controller.php b/includes/api/class-wc-rest-shipping-zone-locations-controller.php index 8cd35fc1422..e16b792395b 100644 --- a/includes/api/class-wc-rest-shipping-zone-locations-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-locations-controller.php @@ -18,7 +18,7 @@ if ( ! defined( 'ABSPATH' ) ) { * REST API Shipping Zone Locations class. * * @package WooCommerce/API - * @extends WC_REST_Controller + * @extends WC_REST_Shipping_Zones_Controller_Base */ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_Controller_Base { diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index d9748543053..a706ad2d9ba 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -18,7 +18,7 @@ if ( ! defined( 'ABSPATH' ) ) { * REST API Shipping Zones class. * * @package WooCommerce/API - * @extends WC_REST_Controller + * @extends WC_REST_Shipping_Zones_Controller_Base */ class WC_REST_Shipping_Zones_Controller extends WC_REST_Shipping_Zones_Controller_Base { From 5400f94f86404cfd1f3b08dd7348197ac99e843e Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 09:26:45 -0600 Subject: [PATCH 242/298] =?UTF-8?q?Shipping=20zone=20location=20=E2=80=9Ct?= =?UTF-8?q?ype=E2=80=9D=20field=20sanitization=20callback=20should=20be=20?= =?UTF-8?q?for=20text=20values.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/class-wc-rest-shipping-zone-locations-controller.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/includes/api/class-wc-rest-shipping-zone-locations-controller.php b/includes/api/class-wc-rest-shipping-zone-locations-controller.php index e16b792395b..ff46875b353 100644 --- a/includes/api/class-wc-rest-shipping-zone-locations-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-locations-controller.php @@ -160,7 +160,7 @@ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_ 'context' => array( 'view', 'edit' ), 'required' => true, 'arg_options' => array( - 'sanitize_callback' => 'absint', + 'sanitize_callback' => 'sanitize_text_field', ), 'enum' => array( 'postcode', @@ -180,5 +180,4 @@ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_ return $schema; } - } \ No newline at end of file From 510229e13d14cf613d825f7c5a9b208499dd756b Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 09:27:32 -0600 Subject: [PATCH 243/298] Add initial controller for Shipping Zone Methods endpoint, with schema definition. --- ...-rest-shipping-zone-methods-controller.php | 84 +++++++++++++++++++ includes/class-wc-api.php | 2 + 2 files changed, 86 insertions(+) create mode 100644 includes/api/class-wc-rest-shipping-zone-methods-controller.php diff --git a/includes/api/class-wc-rest-shipping-zone-methods-controller.php b/includes/api/class-wc-rest-shipping-zone-methods-controller.php new file mode 100644 index 00000000000..4fe7bbe004a --- /dev/null +++ b/includes/api/class-wc-rest-shipping-zone-methods-controller.php @@ -0,0 +1,84 @@ +/methods endpoint. + * + * @author WooThemes + * @category API + * @package WooCommerce/API + * @since 2.7.0 + */ + +if ( ! defined( 'ABSPATH' ) ) { + exit; +} + +/** + * REST API Shipping Zone Methods class. + * + * @package WooCommerce/API + * @extends WC_REST_Shipping_Zones_Controller_Base + */ +class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zones_Controller_Base { + /** + * Get the Shipping Zone Methods schema, conforming to JSON Schema + * + * @return array + */ + public function get_item_schema() { + $single_method_schema = array( + 'type' => 'object', + 'properties' => array( + 'instance_id' => array( + 'description' => __( 'Shipping method instance ID.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view' ), + ), + 'title' => array( + 'description' => __( 'Shipping method customer facing title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + ), + 'order' => array( + 'description' => __( 'Shipping method sort order.', 'woocommerce' ), + 'type' => 'integer', + 'context' => array( 'view', 'edit' ), + 'required' => false, + 'arg_options' => array( + 'sanitize_callback' => 'absint', + ), + ), + 'enabled' => array( + 'description' => __( 'Shipping method enabled status.', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + 'required' => false, + ), + 'method_id' => array( + 'description' => __( 'Shipping method ID.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + ), + 'method_title' => array( + 'description' => __( 'Shipping method title.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + ), + 'method_description' => array( + 'description' => __( 'Shipping method description.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view' ), + ), + ), + ); + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone_methods', + 'type' => 'array', + 'items' => $this->add_additional_fields_schema( $single_method_schema ) + ); + + return $schema; + } +} \ No newline at end of file diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index cd395ac2793..324495d6f45 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -166,6 +166,7 @@ class WC_API extends WC_Legacy_API { include_once( dirname( __FILE__ ) . '/api/class-wc-rest-settings-options-controller.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-shipping-zones-controller.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-shipping-zone-locations-controller.php' ); + include_once( dirname( __FILE__ ) . '/api/class-wc-rest-shipping-zone-methods-controller.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-tax-classes-controller.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-taxes-controller.php' ); include_once( dirname( __FILE__ ) . '/api/class-wc-rest-webhook-deliveries.php' ); @@ -202,6 +203,7 @@ class WC_API extends WC_Legacy_API { 'WC_REST_Settings_Options_Controller', 'WC_REST_Shipping_Zones_Controller', 'WC_REST_Shipping_Zone_Locations_Controller', + 'WC_REST_Shipping_Zone_Methods_Controller', 'WC_REST_Tax_Classes_Controller', 'WC_REST_Taxes_Controller', 'WC_REST_Webhook_Deliveries_Controller', From 92f0c2bd2c257b37d62940a058981a91a4a3ac5b Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 16:34:40 -0600 Subject: [PATCH 244/298] Add endpoint to retrieve all shipping zone methods. --- ...-rest-shipping-zone-methods-controller.php | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/includes/api/class-wc-rest-shipping-zone-methods-controller.php b/includes/api/class-wc-rest-shipping-zone-methods-controller.php index 4fe7bbe004a..6fce0ec38f3 100644 --- a/includes/api/class-wc-rest-shipping-zone-methods-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-methods-controller.php @@ -21,6 +21,74 @@ if ( ! defined( 'ABSPATH' ) ) { * @extends WC_REST_Shipping_Zones_Controller_Base */ class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zones_Controller_Base { + + /** + * Register the routes for Shipping Zone Methods. + */ + public function register_routes() { + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d-]+)/methods', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_items' ), + 'permission_callback' => array( $this, 'permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Get all Shipping Zone Methods. + * + * @param WP_REST_Request $request + * @return WP_REST_Response|WP_Error + */ + public function get_items( $request ) { + $zone = $this->get_zone( $request['zone_id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $methods = $zone->get_shipping_methods(); + $data = array(); + + foreach ( $methods as $method_obj ) { + $method = $this->prepare_item_for_response( $method_obj, $request ); + $method = $this->prepare_response_for_collection( $method ); + $data[] = $method; + } + + return rest_ensure_response( $data ); + } + + /** + * Prepare the Shipping Zone Method for the REST response. + * + * @param array $item Shipping Zone Method. + * @param WP_REST_Request $request Request object. + * @return WP_REST_Response $response + */ + public function prepare_item_for_response( $item, $request ) { + $method = array( + 'instance_id' => $item->instance_id, + 'title' => $item->instance_settings['title'], + 'order' => $item->method_order, + 'enabled' => ( 'yes' === $item->enabled ), + 'method_id' => $item->id, + 'method_title' => $item->method_title, + 'method_description' => $item->method_description, + ); + + $context = empty( $request['context'] ) ? 'view' : $request['context']; + $data = $this->add_additional_fields_to_object( $method, $request ); + $data = $this->filter_response_by_context( $data, $context ); + + // Wrap the data in a response object. + $response = rest_ensure_response( $data ); + + return $response; + } + /** * Get the Shipping Zone Methods schema, conforming to JSON Schema * From f2bb438e987e57b4f886ec48dd43a007568671b1 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Thu, 16 Jun 2016 16:53:33 -0600 Subject: [PATCH 245/298] Add _links to each shipping zone method. --- ...-rest-shipping-zone-methods-controller.php | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/includes/api/class-wc-rest-shipping-zone-methods-controller.php b/includes/api/class-wc-rest-shipping-zone-methods-controller.php index 6fce0ec38f3..bbccff9b8f9 100644 --- a/includes/api/class-wc-rest-shipping-zone-methods-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-methods-controller.php @@ -86,9 +86,32 @@ class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zones_Co // Wrap the data in a response object. $response = rest_ensure_response( $data ); + $response->add_links( $this->prepare_links( $request['zone_id'], $item->instance_id ) ); + return $response; } + /** + * Prepare links for the request. + * + * @param int $zone_id Given Shipping Zone ID. + * @param int $instance_id Given Shipping Zone Method Instance ID. + * @return array Links for the given Shipping Zone Method. + */ + protected function prepare_links( $zone_id, $instance_id ) { + $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id; + $links = array( + 'collection' => array( + 'href' => rest_url( $base . '/methods' ), + ), + 'describes' => array( + 'href' => rest_url( $base ), + ), + ); + + return $links; + } + /** * Get the Shipping Zone Methods schema, conforming to JSON Schema * From 7ebb466287b5fda9ac3921c918da566e4c992491 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Fri, 17 Jun 2016 14:59:36 -0600 Subject: [PATCH 246/298] REST API item schemas should be singular objects. Use single object schemas for Shipping Zone Locations and Methods. --- ...ss-wc-rest-shipping-zone-locations-controller.php | 12 ++++-------- ...lass-wc-rest-shipping-zone-methods-controller.php | 12 ++++-------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/includes/api/class-wc-rest-shipping-zone-locations-controller.php b/includes/api/class-wc-rest-shipping-zone-locations-controller.php index ff46875b353..e00de3b01cd 100644 --- a/includes/api/class-wc-rest-shipping-zone-locations-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-locations-controller.php @@ -142,7 +142,9 @@ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_ * @return array */ public function get_item_schema() { - $single_location_schema = array( + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone_location', 'type' => 'object', 'properties' => array( 'code' => array( @@ -171,13 +173,7 @@ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_ ), ), ); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'shipping_zone_locations', - 'type' => 'array', - 'items' => $this->add_additional_fields_schema( $single_location_schema ) - ); - return $schema; + return $this->add_additional_fields_schema( $schema ); } } \ No newline at end of file diff --git a/includes/api/class-wc-rest-shipping-zone-methods-controller.php b/includes/api/class-wc-rest-shipping-zone-methods-controller.php index bbccff9b8f9..c3b250fa5cc 100644 --- a/includes/api/class-wc-rest-shipping-zone-methods-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-methods-controller.php @@ -118,7 +118,9 @@ class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zones_Co * @return array */ public function get_item_schema() { - $single_method_schema = array( + $schema = array( + '$schema' => 'http://json-schema.org/draft-04/schema#', + 'title' => 'shipping_zone_method', 'type' => 'object', 'properties' => array( 'instance_id' => array( @@ -163,13 +165,7 @@ class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zones_Co ), ), ); - $schema = array( - '$schema' => 'http://json-schema.org/draft-04/schema#', - 'title' => 'shipping_zone_methods', - 'type' => 'array', - 'items' => $this->add_additional_fields_schema( $single_method_schema ) - ); - return $schema; + return $this->add_additional_fields_schema( $schema ); } } \ No newline at end of file From 288496b22b9d68e3e8032c03cc026d9301897e5e Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Fri, 17 Jun 2016 15:14:39 -0600 Subject: [PATCH 247/298] Separate shipping zone endpoint permissions check between read and write operations. --- ...ract-wc-rest-shipping-zones-controller.php | 22 +++++++++++++++++-- ...est-shipping-zone-locations-controller.php | 4 ++-- ...-rest-shipping-zone-methods-controller.php | 2 +- ...lass-wc-rest-shipping-zones-controller.php | 8 +++---- 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php b/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php index 141493818a1..91201d1dd3e 100644 --- a/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php +++ b/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php @@ -53,12 +53,12 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller } /** - * Check whether a given request has permission to access Shipping Zones. + * Check whether a given request has permission to read Shipping Zones. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean */ - public function permissions_check( $request ) { + public function get_items_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.' ), array( 'status' => 404 ) ); } @@ -69,4 +69,22 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller return true; } + + /** + * Check whether a given request has permission to edit Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_items_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot update resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } } \ No newline at end of file diff --git a/includes/api/class-wc-rest-shipping-zone-locations-controller.php b/includes/api/class-wc-rest-shipping-zone-locations-controller.php index e00de3b01cd..d724540a8a0 100644 --- a/includes/api/class-wc-rest-shipping-zone-locations-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-locations-controller.php @@ -30,12 +30,12 @@ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_ array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_items' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), diff --git a/includes/api/class-wc-rest-shipping-zone-methods-controller.php b/includes/api/class-wc-rest-shipping-zone-methods-controller.php index c3b250fa5cc..ceaf8e3c917 100644 --- a/includes/api/class-wc-rest-shipping-zone-methods-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-methods-controller.php @@ -30,7 +30,7 @@ class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zones_Co array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index a706ad2d9ba..ace340c0e49 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -30,12 +30,12 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Shipping_Zones_Controlle array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), @@ -45,12 +45,12 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Shipping_Zones_Controlle array( 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_item' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), ), array( 'methods' => WP_REST_Server::EDITABLE, 'callback' => array( $this, 'update_item' ), - 'permission_callback' => array( $this, 'permissions_check' ), + 'permission_callback' => array( $this, 'update_items_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), From 61a5bf8a682917097c697b71eabeafc2318b14f5 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Fri, 17 Jun 2016 15:31:40 -0600 Subject: [PATCH 248/298] Add single shipping zone method instance endpoint. --- ...-rest-shipping-zone-methods-controller.php | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/includes/api/class-wc-rest-shipping-zone-methods-controller.php b/includes/api/class-wc-rest-shipping-zone-methods-controller.php index ceaf8e3c917..6a47d2fc5d1 100644 --- a/includes/api/class-wc-rest-shipping-zone-methods-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-methods-controller.php @@ -34,6 +34,48 @@ class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zones_Co ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/(?P[\d-]+)/methods/(?P[\d-]+)', array( + array( + 'methods' => WP_REST_Server::READABLE, + 'callback' => array( $this, 'get_item' ), + 'permission_callback' => array( $this, 'get_items_permissions_check' ), + ), + 'schema' => array( $this, 'get_public_item_schema' ), + ) ); + } + + /** + * Get a single Shipping Zone Method. + * + * @param WP_REST_Request $request + * @return WP_REST_Response|WP_Error + */ + public function get_item( $request ) { + $zone = $this->get_zone( $request['zone_id'] ); + + if ( is_wp_error( $zone ) ) { + return $zone; + } + + $instance_id = (int) $request['instance_id']; + $methods = $zone->get_shipping_methods(); + $method = false; + + foreach ( $methods as $method_obj ) { + if ( $instance_id === $method_obj->instance_id ) { + $method = $method_obj; + break; + } + } + + if ( false === $method ) { + return new WP_Error( 'woocommerce_rest_shipping_zone_method_invalid', __( "Resource doesn't exist.", 'woocommerce' ), array( 'status' => 404 ) ); + } + + $data = $this->prepare_item_for_response( $method, $request ); + + return rest_ensure_response( $data ); } /** @@ -101,6 +143,9 @@ class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zones_Co protected function prepare_links( $zone_id, $instance_id ) { $base = '/' . $this->namespace . '/' . $this->rest_base . '/' . $zone_id; $links = array( + 'self' => array( + 'href' => rest_url( $base . '/methods/' . $instance_id ), + ), 'collection' => array( 'href' => rest_url( $base . '/methods' ), ), From cdc90f5633ffd9d506b168b761dcfcea2acf857c Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Fri, 17 Jun 2016 15:49:08 -0600 Subject: [PATCH 249/298] Test coverage for shipping zone method routes. --- tests/unit-tests/api/shipping-zones.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index 6e44ae550c0..aa062340c5b 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -70,6 +70,8 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { $this->assertArrayHasKey( '/wc/v1/shipping/zones', $routes ); $this->assertArrayHasKey( '/wc/v1/shipping/zones/(?P[\d-]+)', $routes ); $this->assertArrayHasKey( '/wc/v1/shipping/zones/(?P[\d-]+)/locations', $routes ); + $this->assertArrayHasKey( '/wc/v1/shipping/zones/(?P[\d-]+)/methods', $routes ); + $this->assertArrayHasKey( '/wc/v1/shipping/zones/(?P[\d-]+)/methods/(?P[\d-]+)', $routes ); } /** From 5e7c495e100c895b5b605ad8fbf93830b36522a1 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Fri, 17 Jun 2016 16:01:29 -0600 Subject: [PATCH 250/298] =?UTF-8?q?Add=20=E2=80=9Crest=20of=20the=20world?= =?UTF-8?q?=E2=80=9D=20zone=20to=20API=20response.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/api/class-wc-rest-shipping-zones-controller.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index ace340c0e49..0cb524b0cdd 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -84,7 +84,15 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Shipping_Zones_Controlle * @return WP_REST_Response */ public function get_items( $request ) { + $rest_of_the_world = $this->get_zone( 0 ); + + // "Rest of the World" should always exist, but handle the case where it doesn't. + if ( is_wp_error( $rest_of_the_world ) ) { + return $rest_of_the_world; + } + $zones = WC_Shipping_Zones::get_zones(); + array_unshift( $zones, $rest_of_the_world->get_data() ); $data = array(); foreach ( $zones as $zone_obj ) { From e007bc177830b6c6d1b54cdf0bd963eca96809b9 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Fri, 17 Jun 2016 17:03:59 -0600 Subject: [PATCH 251/298] Test coverage for all shipping zone methods endpoint. --- tests/unit-tests/api/shipping-zones.php | 90 +++++++++++++++++++++++-- 1 file changed, 85 insertions(+), 5 deletions(-) diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index aa062340c5b..5443437e2b7 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -81,12 +81,34 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { public function test_get_zones() { wp_set_current_user( $this->user ); - // No zones by default + // "Rest of the World" zone exists by default $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones' ) ); $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 0 ); + $this->assertEquals( count( $data ), 1 ); + $this->assertContains( array( + 'id' => 0, + 'name' => 'Rest of the World', + 'order' => 0, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/0' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones' ), + ), + ), + 'describedby' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/0/locations' ), + ), + ), + ), + ), $data ); // Create a zone and make sure it's in the response $this->create_shipping_zone( 'Zone 1' ); @@ -95,8 +117,8 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { $data = $response->get_data(); $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 1 ); - $this->assertEquals( array( + $this->assertEquals( count( $data ), 2 ); + $this->assertContains( array( 'id' => 1, 'name' => 'Zone 1', 'order' => 0, @@ -117,7 +139,7 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { ), ), ), - ), $data[0] ); + ), $data ); } /** @@ -441,4 +463,62 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { $this->assertEquals( 404, $response->get_status() ); } + + /** + * Test getting all Shipping Zone Methods. + * @since 2.7.0 + */ + public function test_get_methods() { + wp_set_current_user( $this->user ); + + // Create a shipping method and make sure it's in the response + $zone = $this->create_shipping_zone( 'Zone 1' ); + $instance_id = $zone->add_shipping_method( 'flat_rate' ); + $methods = $zone->get_shipping_methods(); + $method = $methods[ $instance_id ]; + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones/' . $zone->get_id() . '/methods' ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 1 ); + $this->assertContains( array( + 'instance_id' => $instance_id, + 'title' => $method->instance_settings['title'], + 'order' => $method->method_order, + 'enabled' => ( 'yes' === $method->enabled ), + 'method_id' => $method->id, + 'method_title' => $method->method_title, + 'method_description' => $method->method_description, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $zone->get_id() . '/methods' ), + ), + ), + 'describes' => array( + array( + 'href' => rest_url( '/wc/v1/shipping/zones/' . $zone->get_id() ), + ), + ), + ), + ), $data ); + } + + /** + * Test getting all Shipping Zone Methods with a bad zone ID. + * @since 2.7.0 + */ + public function test_get_methods_invalid_id() { + wp_set_current_user( $this->user ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones/1/methods' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } } \ No newline at end of file From bb23d2eaae1597136d7ebccac6d5c636b7133022 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Fri, 17 Jun 2016 17:40:58 -0600 Subject: [PATCH 252/298] Ensure _links are added to the single shipping zone method endpoint. --- .../api/class-wc-rest-shipping-zone-methods-controller.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/api/class-wc-rest-shipping-zone-methods-controller.php b/includes/api/class-wc-rest-shipping-zone-methods-controller.php index 6a47d2fc5d1..9a0e2008fab 100644 --- a/includes/api/class-wc-rest-shipping-zone-methods-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-methods-controller.php @@ -96,7 +96,6 @@ class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zones_Co foreach ( $methods as $method_obj ) { $method = $this->prepare_item_for_response( $method_obj, $request ); - $method = $this->prepare_response_for_collection( $method ); $data[] = $method; } @@ -130,6 +129,8 @@ class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zones_Co $response->add_links( $this->prepare_links( $request['zone_id'], $item->instance_id ) ); + $response = $this->prepare_response_for_collection( $response ); + return $response; } From 105064ad261a7f4dbd79ad35a26d67f60295d979 Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Fri, 17 Jun 2016 17:41:02 -0600 Subject: [PATCH 253/298] Test coverage for getting a single shipping zone method. --- tests/unit-tests/api/shipping-zones.php | 40 ++++++++++++++++++++----- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index 5443437e2b7..0f0fdf0c675 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -465,7 +465,7 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { } /** - * Test getting all Shipping Zone Methods. + * Test getting all Shipping Zone Methods and getting a single Shipping Zone Method. * @since 2.7.0 */ public function test_get_methods() { @@ -478,11 +478,8 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { $method = $methods[ $instance_id ]; $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones/' . $zone->get_id() . '/methods' ) ); - $data = $response->get_data(); - - $this->assertEquals( 200, $response->get_status() ); - $this->assertEquals( count( $data ), 1 ); - $this->assertContains( array( + $data = $response->get_data(); + $expected = array( 'instance_id' => $instance_id, 'title' => $method->instance_settings['title'], 'order' => $method->method_order, @@ -507,18 +504,45 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { ), ), ), - ), $data ); + ); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( count( $data ), 1 ); + $this->assertContains( $expected, $data ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones/' . $zone->get_id() . '/methods/' . $instance_id ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( $expected, $data ); } /** * Test getting all Shipping Zone Methods with a bad zone ID. * @since 2.7.0 */ - public function test_get_methods_invalid_id() { + public function test_get_methods_invalid_zone_id() { wp_set_current_user( $this->user ); $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones/1/methods' ) ); $this->assertEquals( 404, $response->get_status() ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones/1/methods/1' ) ); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test getting a single Shipping Zone Method with a bad ID. + * @since 2.7.0 + */ + public function test_get_methods_invalid_method_id() { + wp_set_current_user( $this->user ); + + $zone = $this->create_shipping_zone( 'Zone 1' ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/shipping/zones/' . $zone->get_id() . '/methods/1' ) ); + + $this->assertEquals( 404, $response->get_status() ); } } \ No newline at end of file From ea4285b1ecbbc40234fee228063626f20cc102ea Mon Sep 17 00:00:00 2001 From: Jeff Stieler Date: Fri, 17 Jun 2016 18:01:47 -0600 Subject: [PATCH 254/298] =?UTF-8?q?Ensure=20=E2=80=9Crest=20of=20the=20wor?= =?UTF-8?q?ld=E2=80=9D=20zone=20retrieval=20doesn=E2=80=99t=20fail=20by=20?= =?UTF-8?q?using=20the=20core=20method=20instead=20of=20the=20REST=20contr?= =?UTF-8?q?oller=20wrapper.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- includes/api/class-wc-rest-shipping-zones-controller.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index 0cb524b0cdd..9594abc9f1f 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -84,12 +84,7 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Shipping_Zones_Controlle * @return WP_REST_Response */ public function get_items( $request ) { - $rest_of_the_world = $this->get_zone( 0 ); - - // "Rest of the World" should always exist, but handle the case where it doesn't. - if ( is_wp_error( $rest_of_the_world ) ) { - return $rest_of_the_world; - } + $rest_of_the_world = WC_Shipping_Zones::get_zone_by( 'zone_id', 0 ); $zones = WC_Shipping_Zones::get_zones(); array_unshift( $zones, $rest_of_the_world->get_data() ); From 33e0b367acd5517666e9320003f0cebec43c8e5f Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 26 Jul 2016 11:42:57 -0700 Subject: [PATCH 255/298] Add new line at end of files. --- .../abstracts/abstract-wc-rest-shipping-zones-controller.php | 2 +- .../api/class-wc-rest-shipping-zone-locations-controller.php | 4 ++-- .../api/class-wc-rest-shipping-zone-methods-controller.php | 2 +- tests/unit-tests/api/shipping-zones.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php b/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php index 91201d1dd3e..4117a3b06bf 100644 --- a/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php +++ b/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php @@ -87,4 +87,4 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller return true; } -} \ No newline at end of file +} diff --git a/includes/api/class-wc-rest-shipping-zone-locations-controller.php b/includes/api/class-wc-rest-shipping-zone-locations-controller.php index d724540a8a0..26a854eb885 100644 --- a/includes/api/class-wc-rest-shipping-zone-locations-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-locations-controller.php @@ -54,7 +54,7 @@ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_ if ( is_wp_error( $zone ) ) { return $zone; } - + $locations = $zone->get_zone_locations(); $data = array(); @@ -176,4 +176,4 @@ class WC_REST_Shipping_Zone_Locations_Controller extends WC_REST_Shipping_Zones_ return $this->add_additional_fields_schema( $schema ); } -} \ No newline at end of file +} diff --git a/includes/api/class-wc-rest-shipping-zone-methods-controller.php b/includes/api/class-wc-rest-shipping-zone-methods-controller.php index 9a0e2008fab..2e729101a5a 100644 --- a/includes/api/class-wc-rest-shipping-zone-methods-controller.php +++ b/includes/api/class-wc-rest-shipping-zone-methods-controller.php @@ -214,4 +214,4 @@ class WC_REST_Shipping_Zone_Methods_Controller extends WC_REST_Shipping_Zones_Co return $this->add_additional_fields_schema( $schema ); } -} \ No newline at end of file +} diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index 0f0fdf0c675..2ab3dc696f2 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -545,4 +545,4 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { $this->assertEquals( 404, $response->get_status() ); } -} \ No newline at end of file +} From 069ee3b9acdeac1a14672e4ecc7986233c61a35d Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 26 Jul 2016 11:48:44 -0700 Subject: [PATCH 256/298] Add an error check when creating a new shipping zone via the API, incase create() fails. --- includes/api/class-wc-rest-shipping-zones-controller.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index 9594abc9f1f..2b6e1c22023 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -117,9 +117,13 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Shipping_Zones_Controlle } $zone->create(); - $request->set_param( 'id', $zone->get_id() ); - return $this->get_item( $request ); + if ( $zone->get_id() !== 0 ) { + $request->set_param( 'id', $zone->get_id() ); + return $this->get_item( $request ); + } else { + return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce' ), array( 'status' => 500 ) ); + } } /** From 1ba2c6e4d6b0a3aa7afe20c1097b5c7ed515dc45 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 26 Jul 2016 11:57:23 -0700 Subject: [PATCH 257/298] Line break on spy-server --- tests/framework/class-wp-test-spy-rest-server.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/framework/class-wp-test-spy-rest-server.php b/tests/framework/class-wp-test-spy-rest-server.php index 76694902b83..ba485b65a1a 100644 --- a/tests/framework/class-wp-test-spy-rest-server.php +++ b/tests/framework/class-wp-test-spy-rest-server.php @@ -35,4 +35,4 @@ class WP_Test_Spy_REST_Server extends WP_REST_Server { } return apply_filters( 'rest_post_dispatch', rest_ensure_response( $result ), $this, $request ); } -} \ No newline at end of file +} From 9a03eb44071017e716ce7001b1efa24992520e91 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 26 Jul 2016 14:30:02 -0700 Subject: [PATCH 258/298] Use the new API test base for shipping zone tests. --- tests/bootstrap.php | 6 --- .../class-wp-test-spy-rest-server.php | 38 ------------------- tests/unit-tests/api/shipping-zones.php | 9 +---- 3 files changed, 2 insertions(+), 51 deletions(-) delete mode 100644 tests/framework/class-wp-test-spy-rest-server.php diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 1669508e84f..d0dede09717 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -115,12 +115,6 @@ class WC_Unit_Tests_Bootstrap { require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-shipping-zones.php' ); require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-payment-token.php' ); require_once( $this->tests_dir . '/framework/helpers/class-wc-helper-settings.php' ); - - /** - * WP-API - * @todo to be removed when the wp-api branch is merged. - */ - require_once( $this->tests_dir . '/framework/class-wp-test-spy-rest-server.php' ); } /** diff --git a/tests/framework/class-wp-test-spy-rest-server.php b/tests/framework/class-wp-test-spy-rest-server.php deleted file mode 100644 index ba485b65a1a..00000000000 --- a/tests/framework/class-wp-test-spy-rest-server.php +++ /dev/null @@ -1,38 +0,0 @@ -endpoints; - } - - /** - * Allow calling protected methods from tests - * - * @param string $method Method to call - * @param array $args Arguments to pass to the method - * @return mixed - */ - public function __call( $method, $args ) { - return call_user_func_array( array( $this, $method ), $args ); - } - - /** - * Call dispatch() with the rest_post_dispatch filter - */ - public function dispatch( $request ) { - $result = parent::dispatch( $request ); - $result = rest_ensure_response( $result ); - if ( is_wp_error( $result ) ) { - $result = $this->error_to_response( $result ); - } - return apply_filters( 'rest_post_dispatch', rest_ensure_response( $result ), $this, $request ); - } -} diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index 2ab3dc696f2..809fec0486f 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -5,7 +5,7 @@ * @package WooCommerce\Tests\API * @since 2.7.0 */ -class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { +class WC_Tests_API_Shipping_Zones extends WC_REST_Unit_Test_Case { protected $server; @@ -20,9 +20,6 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { */ public function setUp() { parent::setUp(); - global $wp_rest_server; - $this->server = $wp_rest_server = new WP_Test_Spy_REST_Server; - do_action( 'rest_api_init' ); $this->endpoint = new WC_REST_Shipping_Zones_Controller(); $this->user = $this->factory->user->create( array( 'role' => 'administrator', @@ -31,12 +28,10 @@ class WC_Tests_API_Shipping_Zones extends WC_Unit_Test_Case { } /** - * Unset the server. + * Delete zones. */ public function tearDown() { parent::tearDown(); - global $wp_rest_server; - $wp_rest_server = null; foreach( $this->zones as $zone ) { $zone->delete(); } From e761edd8d9501e0070a676741b8d0a7da432cde6 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 27 Jul 2016 12:42:42 -0700 Subject: [PATCH 259/298] Make sure to load abstract-wc-rest-shipping-zones-controller.php --- includes/class-wc-api.php | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/class-wc-api.php b/includes/class-wc-api.php index 324495d6f45..6e3abec8f8d 100644 --- a/includes/class-wc-api.php +++ b/includes/class-wc-api.php @@ -141,6 +141,7 @@ class WC_API extends WC_Legacy_API { // Abstract controllers. include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-controller.php' ); include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-posts-controller.php' ); + include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-shipping-zones-controller.php' ); include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-rest-terms-controller.php' ); include_once( dirname( __FILE__ ) . '/abstracts/abstract-wc-settings-api.php' ); From 9396c5436b224ef2c65f0c3b78d089a168071bb4 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 2 Aug 2016 10:26:26 -0700 Subject: [PATCH 260/298] Make sure that the create shipping zone uses the correct permissions function. Also makes sure creating the shipping zone returns 201, with the location of the new entity, like other endpoints. --- ...tract-wc-rest-shipping-zones-controller.php | 18 ++++++++++++++++++ ...class-wc-rest-shipping-zones-controller.php | 7 +++++-- tests/unit-tests/api/shipping-zones.php | 18 +++++++++++++++++- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php b/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php index 4117a3b06bf..77c175fcde4 100644 --- a/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php +++ b/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php @@ -70,6 +70,24 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller return true; } + /** + * Check if a given request has access to create Shipping Zones. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + if ( ! wc_shipping_enabled() ) { + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.' ), array( 'status' => 404 ) ); + } + + if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you cannot create new resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + + return true; + } + /** * Check whether a given request has permission to edit Shipping Zones. * diff --git a/includes/api/class-wc-rest-shipping-zones-controller.php b/includes/api/class-wc-rest-shipping-zones-controller.php index 2b6e1c22023..5edaf4fa177 100644 --- a/includes/api/class-wc-rest-shipping-zones-controller.php +++ b/includes/api/class-wc-rest-shipping-zones-controller.php @@ -35,7 +35,7 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Shipping_Zones_Controlle array( 'methods' => WP_REST_Server::CREATABLE, 'callback' => array( $this, 'create_item' ), - 'permission_callback' => array( $this, 'update_items_permissions_check' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), ), 'schema' => array( $this, 'get_public_item_schema' ), @@ -120,7 +120,10 @@ class WC_REST_Shipping_Zones_Controller extends WC_REST_Shipping_Zones_Controlle if ( $zone->get_id() !== 0 ) { $request->set_param( 'id', $zone->get_id() ); - return $this->get_item( $request ); + $response = $this->get_item( $request ); + $response->set_status( 201 ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $zone->get_id() ) ) ); + return $response; } else { return new WP_Error( 'woocommerce_rest_shipping_zone_not_created', __( "Resource cannot be created. Check to make sure 'order' and 'name' are present.", 'woocommerce' ), array( 'status' => 500 ) ); } diff --git a/tests/unit-tests/api/shipping-zones.php b/tests/unit-tests/api/shipping-zones.php index 809fec0486f..714a5fd97c8 100644 --- a/tests/unit-tests/api/shipping-zones.php +++ b/tests/unit-tests/api/shipping-zones.php @@ -196,7 +196,7 @@ class WC_Tests_API_Shipping_Zones extends WC_REST_Unit_Test_Case { $response = $this->server->dispatch( $request ); $data = $response->get_data(); - $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 201, $response->get_status() ); $this->assertEquals( array( 'id' => $data['id'], 'name' => 'Test Zone', @@ -221,6 +221,22 @@ class WC_Tests_API_Shipping_Zones extends WC_REST_Unit_Test_Case { ), $data ); } + /** + * Test Shipping Zone create endpoint. + * @since 2.7.0 + */ + public function test_create_shipping_zone_without_permission() { + wp_set_current_user( 0 ); + + $request = new WP_REST_Request( 'POST', '/wc/v1/shipping/zones' ); + $request->set_body_params( array( + 'name' => 'Test Zone', + 'order' => 1, + ) ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 401, $response->get_status() ); + } + /** * Test Shipping Zone update endpoint. * @since 2.7.0 From ffb74a7b0918319778657b08b53c279a8aed8175 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 2 Aug 2016 18:28:31 +0100 Subject: [PATCH 261/298] Add user to site on login Closes #11409 --- includes/class-wc-form-handler.php | 22 ++++++++++++++++------ readme.txt | 1 + 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/includes/class-wc-form-handler.php b/includes/class-wc-form-handler.php index 7d8cc89bd74..b2aca304b2d 100644 --- a/includes/class-wc-form-handler.php +++ b/includes/class-wc-form-handler.php @@ -873,9 +873,12 @@ class WC_Form_Handler { if ( ! empty( $_POST['login'] ) && wp_verify_nonce( $nonce_value, 'woocommerce-login' ) ) { try { - $creds = array(); - $username = trim( $_POST['username'] ); + $creds = array( + 'user_password' => $_POST['password'], + 'remember' => isset( $_POST['rememberme'] ), + ); + $username = trim( $_POST['username'] ); $validation_error = new WP_Error(); $validation_error = apply_filters( 'woocommerce_process_login_errors', $validation_error, $_POST['username'], $_POST['password'] ); @@ -904,10 +907,17 @@ class WC_Form_Handler { $creds['user_login'] = $username; } - $creds['user_password'] = $_POST['password']; - $creds['remember'] = isset( $_POST['rememberme'] ); - $secure_cookie = is_ssl() ? true : false; - $user = wp_signon( apply_filters( 'woocommerce_login_credentials', $creds ), $secure_cookie ); + // On multisite, ensure user exists on current site, if not add them before allowing login. + if ( is_multisite() ) { + $user_data = get_user_by( 'login', $username ); + + if ( $user_data && ! is_user_member_of_blog( $user_data->ID, get_current_blog_id() ) ) { + add_user_to_blog( get_current_blog_id(), $user_data->ID, 'customer' ); + } + } + + // Perform the login + $user = wp_signon( apply_filters( 'woocommerce_login_credentials', $creds ), is_ssl() ); if ( is_wp_error( $user ) ) { $message = $user->get_error_message(); diff --git a/readme.txt b/readme.txt index 8f837af4cad..0afc8bc48be 100644 --- a/readme.txt +++ b/readme.txt @@ -164,6 +164,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc * Improved handling of shop page rewrite rules to allow subpages. * Redirect to login after password reset. * When using authorizations in PayPal standard, automatically capture funds when the order goes processing/completed. +* On multisite, when a user logs into a store with an account on a site, but not the current site, rather than error, add the user to the current site as a customer. [See changelog for all versions](https://raw.githubusercontent.com/woothemes/woocommerce/master/CHANGELOG.txt). From b8ec255ea847f3c2135203e60e80ff885c94b0a4 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Thu, 28 Jul 2016 15:12:49 -0700 Subject: [PATCH 262/298] First pass at a product reviews REST API that supports creating/updating/deleting product reviews. --- ...ass-wc-rest-product-reviews-controller.php | 248 +++++++++++- .../helpers/class-wc-helper-product.php | 23 ++ tests/unit-tests/api/product-reviews.php | 374 ++++++++++++++++++ 3 files changed, 635 insertions(+), 10 deletions(-) create mode 100644 tests/unit-tests/api/product-reviews.php diff --git a/includes/api/class-wc-rest-product-reviews-controller.php b/includes/api/class-wc-rest-product-reviews-controller.php index 5c7f900bd5e..24af89d1c05 100644 --- a/includes/api/class-wc-rest-product-reviews-controller.php +++ b/includes/api/class-wc-rest-product-reviews-controller.php @@ -47,6 +47,22 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { 'permission_callback' => array( $this, 'get_items_permissions_check' ), 'args' => $this->get_collection_params(), ), + array( + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => array( $this, 'create_item' ), + 'permission_callback' => array( $this, 'create_item_permissions_check' ), + 'args' => array_merge( $this->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ), array( + 'review' => array( + 'required' => true, + ), + 'name' => array( + 'required' => true, + ), + 'email' => array( + 'required' => true, + ), + ) ), + ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); @@ -59,6 +75,23 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { 'context' => $this->get_context_param( array( 'default' => 'view' ) ), ), ), + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'update_item' ), + 'permission_callback' => array( $this, 'update_item_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + array( + 'methods' => WP_REST_Server::DELETABLE, + 'callback' => array( $this, 'delete_item' ), + 'permission_callback' => array( $this, 'delete_item_permissions_check' ), + 'args' => array( + 'force' => array( + 'default' => false, + 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + ), + ), + ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); } @@ -78,7 +111,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { } /** - * Check if a given request has access to read a webhook develivery. + * Check if a given request has access to read a product review. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean @@ -93,6 +126,48 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { return true; } + /** + * Check if a given request has access to create a new product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function create_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + if ( $post && ! wc_rest_check_post_permissions( 'product', 'create', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_create', __( 'Sorry, you cannot create new resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to update a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function update_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + if ( $post && ! wc_rest_check_post_permissions( 'product', 'edit', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot edit resource.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + + /** + * Check if a given request has access to delete a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function delete_item_permissions_check( $request ) { + $post = get_post( (int) $request['product_id'] ); + if ( $post && ! wc_rest_check_post_permissions( 'product', 'delete', $post->ID ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot delete product reviews.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + /** * Get all reviews from a product. * @@ -143,6 +218,158 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { return $response; } + + /** + * Create a product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function create_item( $request ) { + $product = get_post( (int) $request['product_id'] ); + + if ( empty( $product->post_type ) || 'product' !== $product->post_type ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + if ( empty( $request['review'] ) ) { + return new WP_Error( 'woocommerce_rest_product_review_invalid_review', __( 'Product review content is required.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + if ( empty( $request['name'] ) ) { + return new WP_Error( 'woocommerce_rest_product_review_invalid_name', __( 'Product review author name is required.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + if ( empty( $request['email'] ) ) { + return new WP_Error( 'woocommerce_rest_product_review_invalid_email', __( 'Product review email is required.', 'woocommerce' ), array( 'status' => 400 ) ); + } + + + $data = array( + 'comment_post_ID' => $product->id, + 'comment_author' => $request['name'], + 'comment_author_email' => $request['email'], + 'comment_content' => $request['review'], + 'comment_approved' => 1, + 'comment_type' => 'review', + ); + $product_review_id = wp_insert_comment( $data ); + update_comment_meta( $product_review_id, 'rating', ( ! empty( $request['rating'] ) ? $request['rating'] : '0' ) ); + + $comment = get_comment( $product_review_id ); + $this->update_additional_fields_for_object( $comment, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Comment $comment Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_product_review", $comment, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $comment, $request ); + $response = rest_ensure_response( $response ); + $response->set_status( 201 ); + $base = str_replace( '(?P[\d]+)', $product->id, $this->rest_base ); + $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $product_review_id ) ) ); + + return $response; + } + + /** + * Update a single product review. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|WP_REST_Response + */ + public function update_item( $request ) { + $id = (int) $request['id']; + $product = get_post( (int) $request['product_id'] ); + + + if ( empty( $product->post_type ) || 'product' !== $product->post_type ) { + return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $review = get_comment( $id ); + + if ( empty( $id ) || empty( $review ) || intval( $review->comment_post_ID ) !== intval( $product->ID ) ) { + return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + // Update fields + $commentdata = array( 'comment_ID' => $id ); + + if ( ! empty( $request['name'] ) ) { + $commentdata['comment_author'] = $request['name' ]; + } + + if ( ! empty( $request['email'] ) ) { + $commentdata['comment_author_email'] = $request['email' ]; + } + + if ( ! empty( $request['review'] ) ) { + $commentdata['comment_content'] = $request['review' ]; + } + + + wp_update_comment( $commentdata ); + + if ( ! empty( $request['rating'] ) ) { + update_comment_meta( $id, 'rating', $request['rating'] ); + } + + $comment = get_comment( $id ); + $this->update_additional_fields_for_object( $comment, $request ); + + /** + * Fires after a single item is created or updated via the REST API. + * + * @param WP_Comment $comment Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. + */ + do_action( "woocommerce_rest_insert_product_review", $comment, $request, true ); + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $comment, $request ); + + return rest_ensure_response( $response ); + } + + /** + * Delete a product review. + * + * @param WP_REST_Request $request Full details about the request + * @return WP_Error|boolean + */ + public function delete_item( $request ) { + $force = isset( $request['force'] ) ? (bool) $request['force'] : false; + + // We don't support trashing for this type, error out. + if ( ! $force ) { + return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Product reviews do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); + } + + $result = wp_delete_comment( $request['id'], true ); + + /** + * Fires after a product review is deleted via the REST API. + * + * @param object $post The deleted item. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. + */ + do_action( 'rest_delete_product_revie', $result, $request ); + if ( $result ) { + return true; + } else { + return new WP_Error( 'rest_cannot_delete', __( 'The product review cannot be deleted.' ), array( 'status' => 500 ) ); + } + } + /** * Prepare a single product review output for response. * @@ -219,37 +446,38 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { 'id' => array( 'description' => __( 'Unique identifier for the resource.', 'woocommerce' ), 'type' => 'integer', - 'context' => array( 'view' ), + 'context' => array( 'view', 'edit' ), 'readonly' => true, ), + 'review' => array( + 'description' => __( 'The content of the review.', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), 'date_created' => array( 'description' => __( "The date the review was created, in the site's timezone.", 'woocommerce' ), 'type' => 'date-time', 'context' => array( 'view', 'edit' ), - 'readonly' => true, ), 'rating' => array( 'description' => __( 'Review rating (0 to 5).', 'woocommerce' ), 'type' => 'integer', - 'context' => array( 'view' ), - 'readonly' => true, + 'context' => array( 'view', 'edit' ), ), 'name' => array( 'description' => __( 'Reviewer name.', 'woocommerce' ), 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, + 'context' => array( 'view', 'edit' ), ), 'email' => array( 'description' => __( 'Reviewer email.', 'woocommerce' ), 'type' => 'string', - 'context' => array( 'view' ), - 'readonly' => true, + 'context' => array( 'view', 'edit' ), ), 'verified' => array( 'description' => __( 'Shows if the reviewer bought the product or not.', 'woocommerce' ), 'type' => 'boolean', - 'context' => array( 'view' ), + 'context' => array( 'view', 'edit' ), 'readonly' => true, ), ), diff --git a/tests/framework/helpers/class-wc-helper-product.php b/tests/framework/helpers/class-wc-helper-product.php index a3d5567f900..e2bf15c64d1 100644 --- a/tests/framework/helpers/class-wc-helper-product.php +++ b/tests/framework/helpers/class-wc-helper-product.php @@ -239,4 +239,27 @@ class WC_Helper_Product { $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_attribute_taxonomies WHERE attribute_id = $attribute_id" ); } + /** + * Creates a new product review on a specific product. + * + * @since 2.7 + * @param $product_id integer Product ID that the review is for + * @param $revieww_content string Content to use for the product review + * @return integer Product Review ID + */ + public static function create_product_review( $product_id, $review_content = 'Review content here' ) { + $data = array( + 'comment_post_ID' => $product_id, + 'comment_author' => 'admin', + 'comment_author_email' => 'woo@woo.local', + 'comment_author_url' => '', + 'comment_date' => '2016-01-01T11:11:11', + 'comment_content' => $review_content, + 'comment_approved' => 1, + 'comment_type' => 'review', + ); + + return wp_insert_comment( $data ); + } + } diff --git a/tests/unit-tests/api/product-reviews.php b/tests/unit-tests/api/product-reviews.php new file mode 100644 index 00000000000..ca68ce0b5c2 --- /dev/null +++ b/tests/unit-tests/api/product-reviews.php @@ -0,0 +1,374 @@ +endpoint = new WC_REST_Product_Reviews_Controller(); + $this->user = $this->factory->user->create( array( + 'role' => 'administrator', + ) ); + } + + /** + * Test route registration. + * + * @since 2.7.0 + */ + public function test_register_routes() { + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( '/wc/v1/products/(?P[\d]+)/reviews', $routes ); + $this->assertArrayHasKey( '/wc/v1/products/(?P[\d]+)/reviews/(?P[\d]+)', $routes ); + } + + /** + * + * + * @since 2.7.0 + */ + public function test_get_product_reviews() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + // Create 10 products reviews for the product + for ( $i = 0; $i < 10; $i++ ) { + WC_Helper_Product::create_product_review( $product->id ); + } + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/products/' . $product->id . '/reviews' ) ); + $product_reviews = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( 10, count( $product_reviews ) ); + $this->assertContains( array( + 'id' => 2, + 'date_created' => '2016-01-01T11:11:11', + 'review' => 'Review content here', + 'rating' => 0, + 'name' => 'admin', + 'email' => 'woo@woo.local', + 'verified' => false, + '_links' => array( + 'self' => array( + array( + 'href' => rest_url( '/wc/v1/products/' . $product->id . '/reviews/2' ), + ), + ), + 'collection' => array( + array( + 'href' => rest_url( '/wc/v1/products/' . $product->id . '/reviews' ), + ), + ), + 'up' => array( + array( + 'href' => rest_url( '/wc/v1/products/' . $product->id ), + ), + ), + ), + ), $product_reviews ); + + } + + /** + * Tests to make sure product reviews cannot be viewed without valid permissions. + * + * @since 2.7.0 + */ + public function test_get_product_reviews_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/products/' . $product->id . '/reviews' ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests to make sure an error is returned when an invalid product is loaded. + * + * @since 2.7.0 + */ + public function test_get_product_reviews_invalid_product() { + wp_set_current_user( $this->user ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/products/0/reviews' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Tests getting a single product review. + * + * @since 2.7.0 + */ + public function test_get_product_review() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->id ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/products/' . $product->id . '/reviews/' . $product_review_id ) ); + $data = $response->get_data(); + + $this->assertEquals( 200, $response->get_status() ); + $this->assertEquals( array( + 'id' => $product_review_id , + 'date_created' => '2016-01-01T11:11:11', + 'review' => 'Review content here', + 'rating' => 0, + 'name' => 'admin', + 'email' => 'woo@woo.local', + 'verified' => false, + ), $data ); + } + + /** + * Tests getting a single product review without the correct permissions. + * + * @since 2.7.0 + */ + public function test_get_product_review_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->id ); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/products/' . $product->id . '/reviews/' . $product_review_id ) ); + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests getting a product review with an invalid ID. + * + * @since 2.7.0 + */ + public function test_get_product_review_invalid_id() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/products/' . $product->id . '/reviews/0' ) ); + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Tests creating a product review. + * + * @since 2.7.0 + */ + public function test_create_product_review() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'POST', '/wc/v1/products/' . $product->id . '/reviews' ); + $request->set_body_params( array( + 'review' => 'Hello world.', + 'name' => 'Admin', + 'email' => 'woo@woo.local', + 'rating' => '5', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 201, $response->get_status() ); + $this->assertEquals( array( + 'id' => $data['id'], + 'date_created' => $data['date_created'], + 'review' => 'Hello world.', + 'rating' => 5, + 'name' => 'Admin', + 'email' => 'woo@woo.local', + 'verified' => false, + ), $data ); + } + + /** + * Tests creating a product review without required fields. + * + * @since 2.7.0 + */ + public function test_create_product_review_invalid_fields() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + // missing review + $request = new WP_REST_Request( 'POST', '/wc/v1/products/' . $product->id . '/reviews' ); + $request->set_body_params( array( + 'name' => 'Admin', + 'email' => 'woo@woo.local', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + + // missing name + $request = new WP_REST_Request( 'POST', '/wc/v1/products/' . $product->id . '/reviews' ); + $request->set_body_params( array( + 'review' => 'Hello world.', + 'email' => 'woo@woo.local', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + + // missing email + $request = new WP_REST_Request( 'POST', '/wc/v1/products/' . $product->id . '/reviews' ); + $request->set_body_params( array( + 'review' => 'Hello world.', + 'name' => 'Admin', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 400, $response->get_status() ); + } + + /** + * Tests updating a product review. + * + * @since 2.7.0 + */ + public function test_update_product_review() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->id ); + + $response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/products/' . $product->id . '/reviews/' . $product_review_id ) ); + $data = $response->get_data(); + $this->assertEquals( 'Review content here', $data['review'] ); + $this->assertEquals( 'admin', $data['name'] ); + $this->assertEquals( 'woo@woo.local', $data['email'] ); + $this->assertEquals( 0, $data['rating'] ); + + $request = new WP_REST_Request( 'PUT', '/wc/v1/products/' . $product->id . '/reviews/' . $product_review_id ); + $request->set_body_params( array( + 'review' => 'Hello world - updated.', + 'name' => 'Justin', + 'email' => 'woo2@woo.local', + 'rating' => 3, + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $this->assertEquals( 'Hello world - updated.', $data['review'] ); + $this->assertEquals( 'Justin', $data['name'] ); + $this->assertEquals( 'woo2@woo.local', $data['email'] ); + $this->assertEquals( 3, $data['rating'] ); + } + + /** + * Tests updating a product review without the correct permissions. + * + * @since 2.7.0 + */ + public function test_update_product_review_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->id ); + + $request = new WP_REST_Request( 'PUT', '/wc/v1/products/' . $product->id . '/reviews/' . $product_review_id ); + $request->set_body_params( array( + 'review' => 'Hello world.', + 'name' => 'Admin', + 'email' => 'woo@woo.dev', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Tests that updating a product review with an invalid id fails. + * + * @since 2.7.0 + */ + public function test_update_product_review_invalid_id() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + $request = new WP_REST_Request( 'PUT', '/wc/v1/products/' . $product->id . '/reviews/0' ); + $request->set_body_params( array( + 'review' => 'Hello world.', + 'name' => 'Admin', + 'email' => 'woo@woo.dev', + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 404, $response->get_status() ); + } + + /** + * Test deleting a product review. + * + * @since 2.7.0 + */ + public function test_delete_product_review() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->id ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v1/products/' . $product->id . '/reviews/' . $product_review_id ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 200, $response->get_status() ); + } + + /** + * Test deleting a product review without permission/creds. + * + * @since 2.7.0 + */ + public function test_delete_product_without_permission() { + wp_set_current_user( 0 ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->id ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v1/products/' . $product->id . '/reviews/' . $product_review_id ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 401, $response->get_status() ); + } + + /** + * Test deleting a product review with an invalid id. + * + * @since 2.7.0 + */ + public function test_delete_product_review_invalid_id() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $product_review_id = WC_Helper_Product::create_product_review( $product->id ); + + $request = new WP_REST_Request( 'DELETE', '/wc/v1/products/' . $product->id . '/reviews/0' ); + $request->set_param( 'force', true ); + $response = $this->server->dispatch( $request ); + + $this->assertEquals( 500, $response->get_status() ); + } + + /** + * Test the product review schema. + * + * @since 2.7.0 + */ + public function test_product_review_schema() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + $request = new WP_REST_Request( 'OPTIONS', '/wc/v1/products/' . $product->id . '/reviews' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + $properties = $data['schema']['properties']; + + $this->assertEquals( 7, count( $properties ) ); + $this->assertArrayHasKey( 'id', $properties ); + $this->assertArrayHasKey( 'review', $properties ); + $this->assertArrayHasKey( 'date_created', $properties ); + $this->assertArrayHasKey( 'rating', $properties ); + $this->assertArrayHasKey( 'name', $properties ); + $this->assertArrayHasKey( 'email', $properties ); + $this->assertArrayHasKey( 'verified', $properties ); + } + +} From a305da25ef1fcc4841e33ea281d2bfe77f5499e0 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Fri, 29 Jul 2016 12:37:29 -0700 Subject: [PATCH 263/298] Add batch support to the product reviews endpoint. --- ...ass-wc-rest-product-reviews-controller.php | 82 ++++++++++++++++--- tests/unit-tests/api/product-reviews.php | 54 +++++++++++- 2 files changed, 124 insertions(+), 12 deletions(-) diff --git a/includes/api/class-wc-rest-product-reviews-controller.php b/includes/api/class-wc-rest-product-reviews-controller.php index 24af89d1c05..562e007b292 100644 --- a/includes/api/class-wc-rest-product-reviews-controller.php +++ b/includes/api/class-wc-rest-product-reviews-controller.php @@ -94,6 +94,16 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { ), 'schema' => array( $this, 'get_public_item_schema' ), ) ); + + register_rest_route( $this->namespace, '/' . $this->rest_base . '/batch', array( + array( + 'methods' => WP_REST_Server::EDITABLE, + 'callback' => array( $this, 'batch_items' ), + 'permission_callback' => array( $this, 'batch_items_permissions_check' ), + 'args' => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ), + ), + 'schema' => array( $this, 'get_public_batch_schema' ), + ) ); } /** @@ -168,6 +178,19 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { return true; } + /** + * Check if a given request has access to batch manage product reviews. + * + * @param WP_REST_Request $request Full details about the request. + * @return WP_Error|boolean + */ + public function batch_items_permissions_check( $request ) { + if ( ! wc_rest_check_post_permissions( 'product', 'batch' ) ) { + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot manipulate product reviews.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + } + return true; + } + /** * Get all reviews from a product. * @@ -244,15 +267,15 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { return new WP_Error( 'woocommerce_rest_product_review_invalid_email', __( 'Product review email is required.', 'woocommerce' ), array( 'status' => 400 ) ); } - $data = array( - 'comment_post_ID' => $product->id, + 'comment_post_ID' => $product->ID, 'comment_author' => $request['name'], 'comment_author_email' => $request['email'], 'comment_content' => $request['review'], 'comment_approved' => 1, 'comment_type' => 'review', ); + $product_review_id = wp_insert_comment( $data ); update_comment_meta( $product_review_id, 'rating', ( ! empty( $request['rating'] ) ? $request['rating'] : '0' ) ); @@ -288,7 +311,6 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { $id = (int) $request['id']; $product = get_post( (int) $request['product_id'] ); - if ( empty( $product->post_type ) || 'product' !== $product->post_type ) { return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } @@ -346,6 +368,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { * @return WP_Error|boolean */ public function delete_item( $request ) { + $id = is_array( $request['id'] ) ? $request['id']['id'] : $request['id']; $force = isset( $request['force'] ) ? (bool) $request['force'] : false; // We don't support trashing for this type, error out. @@ -353,21 +376,60 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Product reviews do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } - $result = wp_delete_comment( $request['id'], true ); + $comment = get_comment( $id ); + + if ( empty( $id ) || empty( $comment->comment_ID ) || empty( $comment->comment_post_ID ) ) { + return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid product review ID.', 'woocommerce' ), array( 'status' => 404 ) ); + } + + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $comment, $request ); + + $result = wp_delete_comment( $id, true ); + + if ( ! $result ) { + return new WP_Error( 'rest_cannot_delete', __( 'The product review cannot be deleted.' ), array( 'status' => 500 ) ); + } /** * Fires after a product review is deleted via the REST API. * - * @param object $post The deleted item. + * @param object $comment The deleted item. * @param WP_REST_Response $response The response data. * @param WP_REST_Request $request The request sent to the API. */ - do_action( 'rest_delete_product_revie', $result, $request ); - if ( $result ) { - return true; - } else { - return new WP_Error( 'rest_cannot_delete', __( 'The product review cannot be deleted.' ), array( 'status' => 500 ) ); + do_action( 'rest_delete_product_review', $comment, $response, $request ); + + return $response; + } + + /** + * Bulk create, update and delete items. + * + * @since 2.7.0 + * @param WP_REST_Request $request Full details about the request. + * @return array Of WP_Error or WP_REST_Response. + */ + public function batch_items( $request ) { + $items = array_filter( $request->get_params() ); + $params = $request->get_url_params(); + $product_id = $params['product_id']; + $body_params = array(); + + foreach ( array( 'update', 'create', 'delete' ) as $batch_type ) { + if ( ! empty( $items[ $batch_type ] ) ) { + $injected_items = array(); + foreach ( $items[ $batch_type ] as $item ) { + $injected_items[] = array_merge( array( 'product_id' => $product_id ), $item ); + } + $body_params[ $batch_type ] = $injected_items; + } } + + $request = new WP_REST_Request( $request->get_method() ); + $request->set_body_params( $body_params ); + + return parent::batch_items( $request ); } /** diff --git a/tests/unit-tests/api/product-reviews.php b/tests/unit-tests/api/product-reviews.php index ca68ce0b5c2..89843b24c96 100644 --- a/tests/unit-tests/api/product-reviews.php +++ b/tests/unit-tests/api/product-reviews.php @@ -311,7 +311,6 @@ class Product_Reviews extends WC_REST_Unit_Test_Case { $request = new WP_REST_Request( 'DELETE', '/wc/v1/products/' . $product->id . '/reviews/' . $product_review_id ); $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); - $this->assertEquals( 200, $response->get_status() ); } @@ -345,9 +344,60 @@ class Product_Reviews extends WC_REST_Unit_Test_Case { $request->set_param( 'force', true ); $response = $this->server->dispatch( $request ); - $this->assertEquals( 500, $response->get_status() ); + $this->assertEquals( 404, $response->get_status() ); } + /** + * Test batch managing product reviews. + */ + public function test_product_reviews_batch() { + wp_set_current_user( $this->user ); + $product = WC_Helper_Product::create_simple_product(); + + $review_1_id = WC_Helper_Product::create_product_review( $product->id ); + $review_2_id = WC_Helper_Product::create_product_review( $product->id ); + $review_3_id = WC_Helper_Product::create_product_review( $product->id ); + $review_4_id = WC_Helper_Product::create_product_review( $product->id ); + + $request = new WP_REST_Request( 'POST', '/wc/v1/products/' . $product->id . '/reviews/batch' ); + $request->set_body_params( array( + 'update' => array( + array( + 'id' => $review_1_id, + 'review' => 'Updated review.', + ), + ), + 'delete' => array( + array( + 'id' => $review_2_id, + ), + array( + 'id' => $review_3_id, + ), + ), + 'create' => array( + array( + 'review' => 'New review.', + 'name' => 'Justin', + 'email' => 'woo3@woo.local', + ), + ), + ) ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 'Updated review.', $data['update'][0]['review'] ); + $this->assertEquals( 'New review.', $data['create'][0]['review'] ); + $this->assertEquals( $review_2_id, $data['delete'][0]['id'] ); + $this->assertEquals( $review_3_id, $data['delete'][1]['id'] ); + + $request = new WP_REST_Request( 'GET', '/wc/v1/products/' . $product->id . '/reviews' ); + $response = $this->server->dispatch( $request ); + $data = $response->get_data(); + + $this->assertEquals( 3, count( $data ) ); + } + /** * Test the product review schema. * From 7529b0b3e91e7b4eb64345aa43b3227c963a6559 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Fri, 29 Jul 2016 12:43:59 -0700 Subject: [PATCH 264/298] Code cleanup --- ...ass-wc-rest-product-reviews-controller.php | 21 +++++++------------ tests/unit-tests/api/product-reviews.php | 3 +-- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/includes/api/class-wc-rest-product-reviews-controller.php b/includes/api/class-wc-rest-product-reviews-controller.php index 562e007b292..e7f529ef227 100644 --- a/includes/api/class-wc-rest-product-reviews-controller.php +++ b/includes/api/class-wc-rest-product-reviews-controller.php @@ -1,8 +1,8 @@ /reviews endpoint. + * Handles requests to /products//reviews. * * @author WooThemes * @category API @@ -15,7 +15,7 @@ if ( ! defined( 'ABSPATH' ) ) { } /** - * REST API Products controller class. + * REST API Product Reviews Controller Class. * * @package WooCommerce/API * @extends WC_REST_Controller @@ -137,7 +137,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { } /** - * Check if a given request has access to create a new product review. + * Check if a given request has access to create a new product review. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean @@ -186,7 +186,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { */ public function batch_items_permissions_check( $request ) { if ( ! wc_rest_check_post_permissions( 'product', 'batch' ) ) { - return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot manipulate product reviews.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); + return new WP_Error( 'woocommerce_rest_cannot_edit', __( 'Sorry, you cannot batch manipulate product reviews.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) ); } return true; } @@ -264,7 +264,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { } if ( empty( $request['email'] ) ) { - return new WP_Error( 'woocommerce_rest_product_review_invalid_email', __( 'Product review email is required.', 'woocommerce' ), array( 'status' => 400 ) ); + return new WP_Error( 'woocommerce_rest_product_review_invalid_email', __( 'Product review author email is required.', 'woocommerce' ), array( 'status' => 400 ) ); } $data = array( @@ -275,7 +275,6 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { 'comment_approved' => 1, 'comment_type' => 'review', ); - $product_review_id = wp_insert_comment( $data ); update_comment_meta( $product_review_id, 'rating', ( ! empty( $request['rating'] ) ? $request['rating'] : '0' ) ); @@ -323,22 +322,17 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { // Update fields $commentdata = array( 'comment_ID' => $id ); - if ( ! empty( $request['name'] ) ) { $commentdata['comment_author'] = $request['name' ]; } - if ( ! empty( $request['email'] ) ) { $commentdata['comment_author_email'] = $request['email' ]; } - if ( ! empty( $request['review'] ) ) { $commentdata['comment_content'] = $request['review' ]; } - wp_update_comment( $commentdata ); - if ( ! empty( $request['rating'] ) ) { update_comment_meta( $id, 'rating', $request['rating'] ); } @@ -368,10 +362,9 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { * @return WP_Error|boolean */ public function delete_item( $request ) { - $id = is_array( $request['id'] ) ? $request['id']['id'] : $request['id']; + $id = is_array( $request['id'] ) ? $request['id']['id'] : $request['id']; $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - // We don't support trashing for this type, error out. if ( ! $force ) { return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Product reviews do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); } diff --git a/tests/unit-tests/api/product-reviews.php b/tests/unit-tests/api/product-reviews.php index 89843b24c96..88aa0e30a2e 100644 --- a/tests/unit-tests/api/product-reviews.php +++ b/tests/unit-tests/api/product-reviews.php @@ -31,7 +31,7 @@ class Product_Reviews extends WC_REST_Unit_Test_Case { } /** - * + * Test getting all product reviews. * * @since 2.7.0 */ @@ -74,7 +74,6 @@ class Product_Reviews extends WC_REST_Unit_Test_Case { ), ), ), $product_reviews ); - } /** From 5d521b0da5848021847a262f2ef1689384b8618e Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Tue, 2 Aug 2016 11:03:44 -0700 Subject: [PATCH 265/298] Fix product review endpoint based on PR feedback: Code cleanup, prepare_item_for_database like WP-API's comments does, better error handling on create, required arg simplification, trash support for reviews. --- ...ass-wc-rest-product-reviews-controller.php | 187 +++++++++++------- 1 file changed, 113 insertions(+), 74 deletions(-) diff --git a/includes/api/class-wc-rest-product-reviews-controller.php b/includes/api/class-wc-rest-product-reviews-controller.php index e7f529ef227..12df9399c36 100644 --- a/includes/api/class-wc-rest-product-reviews-controller.php +++ b/includes/api/class-wc-rest-product-reviews-controller.php @@ -88,7 +88,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { 'args' => array( 'force' => array( 'default' => false, - 'description' => __( 'Required to be true, as resource does not support trashing.', 'woocommerce' ), + 'description' => __( 'Whether to bypass trash and force deletion.', 'woocommerce' ), ), ), ), @@ -121,7 +121,7 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { } /** - * Check if a given request has access to read a product review. + * Check if a given request has access to read a product review. * * @param WP_REST_Request $request Full details about the request. * @return WP_Error|boolean @@ -198,13 +198,13 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { * @return array */ public function get_items( $request ) { - $product = get_post( (int) $request['product_id'] ); + $product_id = (int) $request['product_id']; - if ( empty( $product->post_type ) || 'product' !== $product->post_type ) { + if ( 'product' !== get_post_type( $product_id ) ) { return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } - $reviews = get_approved_comments( $product->ID ); + $reviews = get_approved_comments( $product_id ); $data = array(); foreach ( $reviews as $review_data ) { $review = $this->prepare_item_for_response( $review_data, $request ); @@ -222,16 +222,16 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { * @return WP_Error|WP_REST_Response */ public function get_item( $request ) { - $id = (int) $request['id']; - $product = get_post( (int) $request['product_id'] ); + $id = (int) $request['id']; + $product_id = (int) $request['product_id']; - if ( empty( $product->post_type ) || 'product' !== $product->post_type ) { + if ( 'product' !== get_post_type( $product_id ) ) { return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } $review = get_comment( $id ); - if ( empty( $id ) || empty( $review ) || intval( $review->comment_post_ID ) !== intval( $product->ID ) ) { + if ( empty( $id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { return new WP_Error( 'woocommerce_rest_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } @@ -249,52 +249,48 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { * @return WP_Error|WP_REST_Response */ public function create_item( $request ) { - $product = get_post( (int) $request['product_id'] ); + $product_id = (int) $request['product_id']; - if ( empty( $product->post_type ) || 'product' !== $product->post_type ) { + if ( 'product' !== get_post_type( $product_id ) ) { return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } - if ( empty( $request['review'] ) ) { - return new WP_Error( 'woocommerce_rest_product_review_invalid_review', __( 'Product review content is required.', 'woocommerce' ), array( 'status' => 400 ) ); + $prepared_review = $this->prepare_item_for_database( $request ); + + /** + * Filter a product review (comment) before it is inserted via the REST API. + * + * Allows modification of the comment right before it is inserted via `wp_insert_comment`. + * + * @param array $prepared_review The prepared comment data for `wp_insert_comment`. + * @param WP_REST_Request $request Request used to insert the comment. + */ + $prepared_review = apply_filters( 'rest_pre_insert_product_review', $prepared_review, $request ); + + $product_review_id = wp_insert_comment( $prepared_review ); + if ( ! $product_review_id ) { + return new WP_Error( 'rest_product_review_failed_create', __( 'Creating product review failed.' ), array( 'status' => 500 ) ); } - if ( empty( $request['name'] ) ) { - return new WP_Error( 'woocommerce_rest_product_review_invalid_name', __( 'Product review author name is required.', 'woocommerce' ), array( 'status' => 400 ) ); - } - - if ( empty( $request['email'] ) ) { - return new WP_Error( 'woocommerce_rest_product_review_invalid_email', __( 'Product review author email is required.', 'woocommerce' ), array( 'status' => 400 ) ); - } - - $data = array( - 'comment_post_ID' => $product->ID, - 'comment_author' => $request['name'], - 'comment_author_email' => $request['email'], - 'comment_content' => $request['review'], - 'comment_approved' => 1, - 'comment_type' => 'review', - ); - $product_review_id = wp_insert_comment( $data ); update_comment_meta( $product_review_id, 'rating', ( ! empty( $request['rating'] ) ? $request['rating'] : '0' ) ); - $comment = get_comment( $product_review_id ); - $this->update_additional_fields_for_object( $comment, $request ); + $product_review = get_comment( $product_review_id ); + $this->update_additional_fields_for_object( $product_review, $request ); /** * Fires after a single item is created or updated via the REST API. * - * @param WP_Comment $comment Inserted object. - * @param WP_REST_Request $request Request object. - * @param boolean $creating True when creating item, false when updating. + * @param WP_Comment $product_review Inserted object. + * @param WP_REST_Request $request Request object. + * @param boolean $creating True when creating item, false when updating. */ - do_action( "woocommerce_rest_insert_product_review", $comment, $request, true ); + do_action( "woocommerce_rest_insert_product_review", $product_review, $request, true ); $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $comment, $request ); + $response = $this->prepare_item_for_response( $product_review, $request ); $response = rest_ensure_response( $response ); $response->set_status( 201 ); - $base = str_replace( '(?P[\d]+)', $product->id, $this->rest_base ); + $base = str_replace( '(?P[\d]+)', $product_id, $this->rest_base ); $response->header( 'Location', rest_url( sprintf( '/%s/%s/%d', $this->namespace, $base, $product_review_id ) ) ); return $response; @@ -307,38 +303,32 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { * @return WP_Error|WP_REST_Response */ public function update_item( $request ) { - $id = (int) $request['id']; - $product = get_post( (int) $request['product_id'] ); + $product_review_id = (int) $request['id']; + $product_id = (int) $request['product_id']; - if ( empty( $product->post_type ) || 'product' !== $product->post_type ) { + if ( 'product' !== get_post_type( $product_id ) ) { return new WP_Error( 'woocommerce_rest_product_invalid_id', __( 'Invalid product ID.', 'woocommerce' ), array( 'status' => 404 ) ); } - $review = get_comment( $id ); + $review = get_comment( $product_review_id ); - if ( empty( $id ) || empty( $review ) || intval( $review->comment_post_ID ) !== intval( $product->ID ) ) { + if ( empty( $product_review_id ) || empty( $review ) || intval( $review->comment_post_ID ) !== $product_id ) { return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid resource ID.', 'woocommerce' ), array( 'status' => 404 ) ); } - // Update fields - $commentdata = array( 'comment_ID' => $id ); - if ( ! empty( $request['name'] ) ) { - $commentdata['comment_author'] = $request['name' ]; - } - if ( ! empty( $request['email'] ) ) { - $commentdata['comment_author_email'] = $request['email' ]; - } - if ( ! empty( $request['review'] ) ) { - $commentdata['comment_content'] = $request['review' ]; + $prepared_review = $this->prepare_item_for_database( $request ); + + $updated = wp_update_comment( $prepared_review ); + if ( 0 === $updated ) { + return new WP_Error( 'rest_product_review_failed_edit', __( 'Updating product review failed.' ), array( 'status' => 500 ) ); } - wp_update_comment( $commentdata ); if ( ! empty( $request['rating'] ) ) { - update_comment_meta( $id, 'rating', $request['rating'] ); + update_comment_meta( $product_review_id, 'rating', $request['rating'] ); } - $comment = get_comment( $id ); - $this->update_additional_fields_for_object( $comment, $request ); + $product_review = get_comment( $product_review_id ); + $this->update_additional_fields_for_object( $product_review, $request ); /** * Fires after a single item is created or updated via the REST API. @@ -347,10 +337,10 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { * @param WP_REST_Request $request Request object. * @param boolean $creating True when creating item, false when updating. */ - do_action( "woocommerce_rest_insert_product_review", $comment, $request, true ); + do_action( "woocommerce_rest_insert_product_review", $product_review, $request, true ); $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $comment, $request ); + $response = $this->prepare_item_for_response( $product_review, $request ); return rest_ensure_response( $response ); } @@ -362,23 +352,40 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { * @return WP_Error|boolean */ public function delete_item( $request ) { - $id = is_array( $request['id'] ) ? $request['id']['id'] : $request['id']; + $product_review_id = is_array( $request['id'] ) ? $request['id']['id'] : $request['id']; $force = isset( $request['force'] ) ? (bool) $request['force'] : false; - if ( ! $force ) { - return new WP_Error( 'woocommerce_rest_trash_not_supported', __( 'Product reviews do not support trashing.', 'woocommerce' ), array( 'status' => 501 ) ); - } - - $comment = get_comment( $id ); - - if ( empty( $id ) || empty( $comment->comment_ID ) || empty( $comment->comment_post_ID ) ) { + $product_review = get_comment( $product_review_id ); + if ( empty( $product_review_id ) || empty( $product_review->comment_ID ) || empty( $product_review->comment_post_ID ) ) { return new WP_Error( 'woocommerce_rest_product_review_invalid_id', __( 'Invalid product review ID.', 'woocommerce' ), array( 'status' => 404 ) ); } - $request->set_param( 'context', 'edit' ); - $response = $this->prepare_item_for_response( $comment, $request ); + /** + * Filter whether a product review is trashable. + * + * Return false to disable trash support for the product review. + * + * @param boolean $supports_trash Whether the object supports trashing. + * @param WP_Post $product_review The object being considered for trashing support. + */ + $supports_trash = apply_filters( 'rest_product_review_trashable', ( EMPTY_TRASH_DAYS > 0 ), $product_review ); - $result = wp_delete_comment( $id, true ); + $request->set_param( 'context', 'edit' ); + $response = $this->prepare_item_for_response( $product_review, $request ); + + if ( $force ) { + $result = wp_delete_comment( $product_review_id, true ); + } else { + if ( ! $supports_trash ) { + return new WP_Error( 'rest_trash_not_supported', __( 'The product review does not support trashing.' ), array( 'status' => 501 ) ); + } + + if ( 'trash' === $product_review->comment_approved ) { + return new WP_Error( 'rest_already_trashed', __( 'The comment has already been trashed.' ), array( 'status' => 410 ) ); + } + + $result = wp_trash_comment( $product_review->comment_ID ); + } if ( ! $result ) { return new WP_Error( 'rest_cannot_delete', __( 'The product review cannot be deleted.' ), array( 'status' => 500 ) ); @@ -387,11 +394,11 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { /** * Fires after a product review is deleted via the REST API. * - * @param object $comment The deleted item. - * @param WP_REST_Response $response The response data. - * @param WP_REST_Request $request The request sent to the API. + * @param object $product_review The deleted item. + * @param WP_REST_Response $response The response data. + * @param WP_REST_Request $request The request sent to the API. */ - do_action( 'rest_delete_product_review', $comment, $response, $request ); + do_action( 'rest_delete_product_review', $product_review, $response, $request ); return $response; } @@ -462,6 +469,38 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller { return apply_filters( 'woocommerce_rest_prepare_product_review', $response, $review, $request ); } + /** + * Prepare a single product review to be inserted into the database. + * + * @param WP_REST_Request $request Request object. + * @return array|WP_Error $prepared_review + */ + protected function prepare_item_for_database( $request ) { + $prepared_review = array( 'comment_approved' => 1, 'comment_type' => 'review' ); + + if ( isset( $request['id'] ) ) { + $prepared_review['comment_ID'] = (int) $request['id']; + } + + if ( isset( $request['review'] ) ) { + $prepared_review['comment_content'] = $request['review']; + } + + if ( isset( $request['product_id'] ) ) { + $prepared_review['comment_post_ID'] = (int) $request['product_id']; + } + + if ( isset( $request['name'] ) ) { + $prepared_review['comment_author'] = $request['name']; + } + + if ( isset( $request['email'] ) ) { + $prepared_review['comment_author_email'] = $request['email']; + } + + return apply_filters( 'rest_preprocess_product_review', $prepared_review, $request ); + } + /** * Prepare links for the request. * From 1310ff09b51e445c07b1052e70545fe0592f7b36 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 3 Aug 2016 12:52:45 +0100 Subject: [PATCH 266/298] Deprecated function replacements --- .../abstracts/abstract-wc-legacy-order.php | 36 +++---------------- includes/class-wc-order-item-product.php | 32 +++++++++++------ 2 files changed, 26 insertions(+), 42 deletions(-) diff --git a/includes/abstracts/abstract-wc-legacy-order.php b/includes/abstracts/abstract-wc-legacy-order.php index 3dba3345528..8fe96d3435a 100644 --- a/includes/abstracts/abstract-wc-legacy-order.php +++ b/includes/abstracts/abstract-wc-legacy-order.php @@ -375,6 +375,7 @@ abstract class WC_Abstract_Legacy_Order extends WC_Data { * @param array $item */ public function display_item_downloads( $item ) { + _deprecated_function( 'display_item_downloads', '2.7', 'wc_display_item_downloads' ); $product = $item->get_product(); if ( $product && $product->exists() && $product->is_downloadable() && $this->is_download_permitted() ) { @@ -400,6 +401,7 @@ abstract class WC_Abstract_Legacy_Order extends WC_Data { * @return string */ public function get_download_url( $product_id, $download_id ) { + _deprecated_function( 'get_download_url', '2.7', 'WC_Order_Item_Product::get_item_download_url' ); return add_query_arg( array( 'download_file' => $product_id, 'order' => $this->get_order_key(), @@ -415,37 +417,8 @@ abstract class WC_Abstract_Legacy_Order extends WC_Data { * @return array */ public function get_item_downloads( $item ) { - global $wpdb; - - $product = $item->get_product(); - - if ( ! $product ) { - /** - * $product can be `false`. Example: checking an old order, when a product or variation has been deleted. - * @see \WC_Product_Factory::get_product - */ - return array(); - } - $download_ids = $wpdb->get_col( $wpdb->prepare(" - SELECT download_id - FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions - WHERE user_email = %s - AND order_key = %s - AND product_id = %d - ORDER BY permission_id - ", $this->get_billing_email(), $this->get_order_key(), $product_id ) ); - - $files = array(); - - foreach ( $download_ids as $download_id ) { - - if ( $product->has_file( $download_id ) ) { - $files[ $download_id ] = $product->get_file( $download_id ); - $files[ $download_id ]['download_url'] = $this->get_download_url( $product_id, $download_id ); - } - } - - return apply_filters( 'woocommerce_get_item_downloads', $files, $item, $this ); + _deprecated_function( 'get_item_downloads', '2.7', 'WC_Order_Item_Product::get_item_downloads' ); + return $item->get_item_downloads(); } /** @@ -607,6 +580,7 @@ abstract class WC_Abstract_Legacy_Order extends WC_Data { * @return string */ public function email_order_items_table( $args = array() ) { + _deprecated_function( 'email_order_items_table', '2.7', 'wc_get_email_order_items' ); return wc_get_email_order_items( $this, $args ); } diff --git a/includes/class-wc-order-item-product.php b/includes/class-wc-order-item-product.php index a9dbd58f973..88772eedbbe 100644 --- a/includes/class-wc-order-item-product.php +++ b/includes/class-wc-order-item-product.php @@ -156,6 +156,22 @@ class WC_Order_Item_Product extends WC_Order_Item { return apply_filters( 'woocommerce_order_item_product', $product, $this ); } + /** + * Get the Download URL. + * @param int $download_id + * @return string + */ + public function get_item_download_url( $download_id ) { + $order = $this->get_order(); + + return $order ? add_query_arg( array( + 'download_file' => $this->get_variation_id() ? $this->get_variation_id() : $this->get_product_id(), + 'order' => $order->get_order_key(), + 'email' => urlencode( $order->get_billing_email() ), + 'key' => $download_id + ), trailingslashit( home_url() ) ) : ''; + } + /** * Get any associated downloadable files. * @return array @@ -165,28 +181,22 @@ class WC_Order_Item_Product extends WC_Order_Item { $files = array(); $product = $this->get_product(); - $order = wc_get_order( $this->get_order_id() ); + $order = $this->get_order(); if ( $product && $order && $product->is_downloadable() && $order->is_download_permitted() ) { - $download_file_id = $this->get_variation_id() ? $this->get_variation_id() : $this->get_product_id(); - $download_ids = $wpdb->get_col( + $download_ids = $wpdb->get_col( $wpdb->prepare( "SELECT download_id FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE user_email = %s AND order_key = %s AND product_id = %d ORDER BY permission_id", $order->get_billing_email(), $order->get_order_key(), - $download_file_id + $this->get_variation_id() ? $this->get_variation_id() : $this->get_product_id() ) ); foreach ( $download_ids as $download_id ) { if ( $product->has_file( $download_id ) ) { - $files[ $download_id ] = $product->get_file( $download_id ); - $files[ $download_id ]['download_url'] = add_query_arg( array( - 'download_file' => $download_file_id, - 'order' => $order->get_order_key(), - 'email' => urlencode( $order->get_billing_email() ), - 'key' => $download_id - ), trailingslashit( home_url() ) ); + $files[ $download_id ] = $product->get_file( $download_id ); + $files[ $download_id ]['download_url'] = $this->get_item_download_url( $download_id ); } } } From a053d234c9c77158229f473ad03a7b484360bb7f Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 3 Aug 2016 12:52:51 +0100 Subject: [PATCH 267/298] get_order() method --- includes/class-wc-order-item.php | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/includes/class-wc-order-item.php b/includes/class-wc-order-item.php index ac87dbd666d..204f1c20c3c 100644 --- a/includes/class-wc-order-item.php +++ b/includes/class-wc-order-item.php @@ -28,6 +28,12 @@ class WC_Order_Item extends WC_Data implements ArrayAccess { 'type' => '', ); + /** + * May store an order to prevent retriving it multiple times. + * @var object + */ + protected $_order; + /** * Stores meta in cache for future reads. * A group must be set to to enable caching. @@ -90,6 +96,17 @@ class WC_Order_Item extends WC_Data implements ArrayAccess { return 1; } + /** + * Get parent order object. + * @return int + */ + public function get_order() { + if ( ! $this->_order ) { + $this->_order = wc_get_order( $this->get_order_id() ); + } + return $this->_order; + } + /* |-------------------------------------------------------------------------- | Getters From b8db53c2c1882af2597856d219ac0bdae9c23963 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 3 Aug 2016 12:54:16 +0100 Subject: [PATCH 268/298] made set_type private --- includes/class-wc-order-item.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/includes/class-wc-order-item.php b/includes/class-wc-order-item.php index 204f1c20c3c..630b278bc1e 100644 --- a/includes/class-wc-order-item.php +++ b/includes/class-wc-order-item.php @@ -195,9 +195,8 @@ class WC_Order_Item extends WC_Data implements ArrayAccess { * Set order item type. * @param string $value */ - public function set_type( $value ) { + protected function set_type( $value ) { $this->_data['type'] = wc_clean( $value ); - } /* From f694f297e895fb381b1265f787a7c87062f168c6 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 3 Aug 2016 12:57:32 +0100 Subject: [PATCH 269/298] Use get_id() --- includes/abstracts/abstract-wc-order.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/abstracts/abstract-wc-order.php b/includes/abstracts/abstract-wc-order.php index 5dc22243602..e04b6b21468 100644 --- a/includes/abstracts/abstract-wc-order.php +++ b/includes/abstracts/abstract-wc-order.php @@ -1603,7 +1603,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { if ( apply_filters( 'woocommerce_get_order_item_totals_excl_free_fees', empty( $fee['line_total'] ) && empty( $fee['line_tax'] ), $id ) ) { continue; } - $total_rows[ 'fee_' . $fee->get_order_item_id() ] = array( + $total_rows[ 'fee_' . $fee->get_id() ] = array( 'label' => $fee->get_name() . ':', 'value' => wc_price( 'excl' === $tax_display ? $fee->get_total() : $fee->get_total() + $fee->get_total_tax(), array('currency' => $this->get_currency()) ) ); From 24235564d58541a343f7297ce1294c18c6d35a57 Mon Sep 17 00:00:00 2001 From: Maciej Swoboda Date: Wed, 3 Aug 2016 16:06:30 +0200 Subject: [PATCH 270/298] ZIP Code formatting for Poland In Poland we use ZIP code formatting: XX-XXX. So the "-" sign should not be removed. --- includes/wc-formatting-functions.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/includes/wc-formatting-functions.php b/includes/wc-formatting-functions.php index d6431432ab8..d1f50f0dd3d 100644 --- a/includes/wc-formatting-functions.php +++ b/includes/wc-formatting-functions.php @@ -668,6 +668,9 @@ function wc_format_postcode( $postcode, $country ) { case 'JP' : $postcode = trim( substr_replace( $postcode, '-', 3, 0 ) ); break; + case 'PL' : + $postcode = trim( substr_replace( $postcode, '-', -3, 0 ) ); + break; case 'PT' : $postcode = trim( substr_replace( $postcode, '-', 4, 0 ) ); break; From 5a9dacd59527427ea54d1eebd3bfc45638c5f247 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Wed, 3 Aug 2016 16:07:34 +0100 Subject: [PATCH 271/298] Show variable weights/dimensions even when parent values are not set. --- includes/abstracts/abstract-wc-product.php | 22 ++++++++- includes/class-wc-product-variable.php | 47 ++++++++++++++++++- includes/wc-template-functions.php | 2 +- readme.txt | 1 + .../single-product/product-attributes.php | 8 ++-- 5 files changed, 72 insertions(+), 8 deletions(-) diff --git a/includes/abstracts/abstract-wc-product.php b/includes/abstracts/abstract-wc-product.php index 2f2a478f324..ea0fa804b02 100644 --- a/includes/abstracts/abstract-wc-product.php +++ b/includes/abstracts/abstract-wc-product.php @@ -1429,7 +1429,7 @@ class WC_Product { * @return bool */ public function enable_dimensions_display() { - return apply_filters( 'wc_product_enable_dimensions_display', true ); + return apply_filters( 'wc_product_enable_dimensions_display', true ) && ( $this->has_dimensions() || $this->has_weight() ); } /** @@ -1441,6 +1441,15 @@ class WC_Product { return $this->get_dimensions() ? true : false; } + /** + * Does a child have dimensions set? + * @since 2.7.0 + * @return boolean + */ + public function child_has_dimensions() { + return false; + } + /** * Returns the product length. * @return string @@ -1483,6 +1492,15 @@ class WC_Product { return $this->get_weight() ? true : false; } + /** + * Does a child have a weight set? + * @since 2.7.0 + * @return boolean + */ + public function child_has_weight() { + return false; + } + /** * Returns formatted dimensions. * @return string @@ -1498,7 +1516,7 @@ class WC_Product { $dimensions .= ' ' . get_option( 'woocommerce_dimension_unit' ); } - return apply_filters( 'woocommerce_product_dimensions', $dimensions, $this ); + return apply_filters( 'woocommerce_product_dimensions', $dimensions, $this ); } /** diff --git a/includes/class-wc-product-variable.php b/includes/class-wc-product-variable.php index a44cfc42403..bce1de9c8cb 100644 --- a/includes/class-wc-product-variable.php +++ b/includes/class-wc-product-variable.php @@ -610,7 +610,7 @@ class WC_Product_Variable extends WC_Product { 'price_html' => apply_filters( 'woocommerce_show_variation_price', $variation->get_price() === "" || $this->get_variation_price( 'min' ) !== $this->get_variation_price( 'max' ), $this, $variation ) ? '' . $variation->get_price_html() . '' : '', 'availability_html' => $availability_html, 'sku' => $variation->get_sku(), - 'weight' => $variation->get_weight() . ' ' . esc_attr( get_option('woocommerce_weight_unit' ) ), + 'weight' => $variation->get_weight() ? $variation->get_weight() . ' ' . esc_attr( get_option('woocommerce_weight_unit' ) ) : '', 'dimensions' => $variation->get_dimensions(), 'min_qty' => 1, 'max_qty' => $variation->backorders_allowed() ? '' : $variation->get_stock_quantity(), @@ -723,6 +723,33 @@ class WC_Product_Variable extends WC_Product { } } + /** + * Does a child have a weight set? + * @since 2.7.0 + * @return boolean + */ + public function child_has_weight() { + return boolval( get_post_meta( $this->id, '_child_has_weight', true ) ); + } + + /** + * Does a child have dimensions set? + * @since 2.7.0 + * @return boolean + */ + public function child_has_dimensions() { + return boolval( get_post_meta( $this->id, '_child_has_dimensions', true ) ); + } + + /** + * Returns whether or not we are showing dimensions on the product page. + * + * @return bool + */ + public function enable_dimensions_display() { + return apply_filters( 'wc_product_enable_dimensions_display', true ) && ( $this->has_dimensions() || $this->has_weight() || $this->child_has_weight() || $this->child_has_dimensions() ); + } + /** * Sync the variable product with it's children. */ @@ -740,6 +767,8 @@ class WC_Product_Variable extends WC_Product { // No published variations - product won't be purchasable. if ( ! $children ) { update_post_meta( $product_id, '_price', '' ); + delete_post_meta( $product_id, '_child_has_weight' ); + delete_post_meta( $product_id, '_child_has_dimensions' ); delete_transient( 'wc_products_onsale' ); if ( is_admin() && 'publish' === get_post_status( $product_id ) ) { @@ -826,6 +855,22 @@ class WC_Product_Variable extends WC_Product { add_post_meta( $product_id, '_price', $max_price, false ); delete_transient( 'wc_products_onsale' ); + // Sync weights + foreach ( $children as $child_id ) { + if ( get_post_meta( $child_id, '_weight', true ) ) { + update_post_meta( $product_id, '_child_has_weight', true ); + break; + } + } + + // Sync dimensions + foreach ( $children as $child_id ) { + if ( get_post_meta( $child_id, '_height', true ) || get_post_meta( $child_id, '_width', true ) || get_post_meta( $child_id, '_length', true ) ) { + update_post_meta( $product_id, '_child_has_dimensions', true ); + break; + } + } + // Sync attributes self::sync_attributes( $product_id, $children ); diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 82156adfa7b..db0adf8c654 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -1141,7 +1141,7 @@ if ( ! function_exists( 'woocommerce_default_product_tabs' ) ) { } // Additional information tab - shows attributes - if ( $product && ( $product->has_attributes() || ( $product->enable_dimensions_display() && ( $product->has_dimensions() || $product->has_weight() ) ) ) ) { + if ( $product && ( $product->has_attributes() || $product->enable_dimensions_display() ) ) { $tabs['additional_information'] = array( 'title' => __( 'Additional Information', 'woocommerce' ), 'priority' => 20, diff --git a/readme.txt b/readme.txt index 0afc8bc48be..6f2aacdd3c9 100644 --- a/readme.txt +++ b/readme.txt @@ -165,6 +165,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc * Redirect to login after password reset. * When using authorizations in PayPal standard, automatically capture funds when the order goes processing/completed. * On multisite, when a user logs into a store with an account on a site, but not the current site, rather than error, add the user to the current site as a customer. +* Show variable weights/dimensions even when parent values are not set. [See changelog for all versions](https://raw.githubusercontent.com/woothemes/woocommerce/master/CHANGELOG.txt). diff --git a/templates/single-product/product-attributes.php b/templates/single-product/product-attributes.php index 9c548243674..bcf2e29380c 100644 --- a/templates/single-product/product-attributes.php +++ b/templates/single-product/product-attributes.php @@ -33,17 +33,17 @@ ob_start(); enable_dimensions_display() ) : ?> - has_weight() ) : $has_row = true; ?> + has_weight() || get_post_meta( $product->id, '_child_has_weight', true ) ) : $has_row = true; ?> - get_weight() ) . ' ' . esc_attr( get_option( 'woocommerce_weight_unit' ) ); ?> + get_weight() ? wc_format_localized_decimal( $product->get_weight() ) . ' ' . esc_attr( get_option( 'woocommerce_weight_unit' ) ) : __( 'N/A', 'woocommerce' ); ?> - has_dimensions() ) : $has_row = true; ?> + has_dimensions() || get_post_meta( $product->id, '_child_has_dimensions', true ) ) : $has_row = true; ?> - get_dimensions(); ?> + get_dimensions() ? $product->get_dimensions() : __( 'N/A', 'woocommerce' ); ?> From 8df6ff3c7b2e35176b9b2428b762715954f75a88 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 3 Aug 2016 10:44:20 -0700 Subject: [PATCH 272/298] Convert wp-admin's system status page to use the same backend code as the API. --- .../views/html-admin-page-status-report.php | 656 ++++++------------ ...class-wc-rest-system-status-controller.php | 100 ++- tests/unit-tests/api/system-status.php | 2 +- 3 files changed, 313 insertions(+), 445 deletions(-) diff --git a/includes/admin/views/html-admin-page-status-report.php b/includes/admin/views/html-admin-page-status-report.php index 7c5ad8471c6..ee651d4250e 100644 --- a/includes/admin/views/html-admin-page-status-report.php +++ b/includes/admin/views/html-admin-page-status-report.php @@ -6,8 +6,15 @@ if ( ! defined( 'ABSPATH' ) ) { exit; } -global $wpdb; +global $wpdb; +$system_status = new WC_REST_System_Status_Controller; +$environment = $system_status->get_environment_info(); +$database = $system_status->get_database_info(); +$active_plugins = $system_status->get_active_plugins(); +$theme = $system_status->get_theme_info(); +$settings = $system_status->get_settings(); +$pages = $system_status->get_pages(); ?>

    @@ -29,54 +36,47 @@ global $wpdb; : - + : - + : - version ); ?> + : ' . WC_LOG_DIR . ' '; + if ( $environment['log_directory_writable'] ) { + echo ' ' . esc_html( $environment['log_directory'] ) . ' '; } else { - printf( ' ' . __( 'To allow logging, make %s writable or define a custom WC_LOG_DIR.', 'woocommerce' ) . '', WC_LOG_DIR ); + printf( ' ' . __( 'To allow logging, make %s writable or define a custom WC_LOG_DIR.', 'woocommerce' ) . '', $environment['log_directory'] ); } ?> : - + : - '; else echo '–'; ?> + '; else echo '–'; ?> : ' . sprintf( __( '%s - We recommend setting memory to at least 64MB. See: %s', 'woocommerce' ), size_format( $memory ), '' . __( 'Increasing memory allocated to PHP', 'woocommerce' ) . '' ) . ''; + if ( $environment['wp_memory_limit'] < 67108864 ) { + echo ' ' . sprintf( __( '%s - We recommend setting memory to at least 64MB. See: %s', 'woocommerce' ), size_format( $environment['wp_memory_limit'] ), '' . __( 'Increasing memory allocated to PHP', 'woocommerce' ) . '' ) . ''; } else { - echo '' . size_format( $memory ) . ''; + echo '' . size_format( $environment['wp_memory_limit'] ) . ''; } ?> @@ -84,7 +84,7 @@ global $wpdb; : - + @@ -95,17 +95,17 @@ global $wpdb; : - - - + + + : - + @@ -119,23 +119,16 @@ global $wpdb; : - + : ' . sprintf( __( '%s - We recommend a minimum PHP version of 5.6. See: %s', 'woocommerce' ), esc_html( $php_version ), '' . __( 'How to update your PHP version', 'woocommerce' ) . '' ) . ''; - } else { - echo '' . esc_html( $php_version ) . ''; - } + if ( version_compare( $environment['php_version'], '5.6', '<' ) ) { + echo ' ' . sprintf( __( '%s - We recommend a minimum PHP version of 5.6. See: %s', 'woocommerce' ), esc_html( $environment['php_version'] ), '' . __( 'How to update your PHP version', 'woocommerce' ) . '' ) . ''; } else { - _e( "Couldn't determine PHP version because phpversion() doesn't exist.", 'woocommerce' ); + echo '' . esc_html( $environment['php_version'] ) . ''; } ?> @@ -143,55 +136,44 @@ global $wpdb; : - + : - + : - + : - + : - ' : '–'; ?> + ' : '–'; ?> use_mysqli ) { $ver = mysqli_get_server_info( $wpdb->dbh ); } else { $ver = mysql_get_server_info(); } - if ( ! empty( $wpdb->is_mysql ) && ! stristr( $ver, 'MariaDB' ) ) : ?> : db_version(); - - if ( version_compare( $mysql_version, '5.6', '<' ) ) { - echo ' ' . sprintf( __( '%s - We recommend a minimum MySQL version of 5.6. See: %s', 'woocommerce' ), esc_html( $mysql_version ), '' . __( 'WordPress Requirements', 'woocommerce' ) . '' ) . ''; + if ( version_compare( $environment['mysql_version'], '5.6', '<' ) ) { + echo ' ' . sprintf( __( '%s - We recommend a minimum MySQL version of 5.6. See: %s', 'woocommerce' ), esc_html( $environment['mysql_version'] ), '' . __( 'WordPress Requirements', 'woocommerce' ) . '' ) . ''; } else { - echo '' . esc_html( $mysql_version ) . ''; + echo '' . esc_html( $environment['mysql_version'] ) . ''; } ?> @@ -200,138 +182,96 @@ global $wpdb; : - + : ' . sprintf( __( 'Default timezone is %s - it should be UTC', 'woocommerce' ), $default_timezone ) . ''; + if ( 'UTC' !== $environment['default_timezone'] ) { + echo ' ' . sprintf( __( 'Default timezone is %s - it should be UTC', 'woocommerce' ), $environment['default_timezone'] ) . ''; } else { echo ''; } ?> - SoapClient' ); - } - - // DOMDocument. - $posting['dom_document']['name'] = 'DOMDocument'; - $posting['dom_document']['help'] = wc_help_tip( __( 'HTML/Multipart emails use DOMDocument to generate inline CSS in templates.', 'woocommerce' ) ); - - if ( class_exists( 'DOMDocument' ) ) { - $posting['dom_document']['success'] = true; - } else { - $posting['dom_document']['success'] = false; - $posting['dom_document']['note'] = sprintf( __( 'Your server does not have the %s class enabled - HTML/Multipart emails, and also some extensions, will not work without DOMDocument.', 'woocommerce' ), 'DOMDocument' ); - } - - // GZIP. - $posting['gzip']['name'] = 'GZip'; - $posting['gzip']['help'] = wc_help_tip( __( 'GZip (gzopen) is used to open the GEOIP database from MaxMind.', 'woocommerce' ) ); - - if ( is_callable( 'gzopen' ) ) { - $posting['gzip']['success'] = true; - } else { - $posting['gzip']['success'] = false; - $posting['gzip']['note'] = sprintf( __( 'Your server does not support the %s function - this is required to use the GeoIP database from MaxMind.', 'woocommerce' ), 'gzopen' ); - } - - // Multibyte String. - $posting['mbstring']['name'] = 'Multibyte String'; - $posting['mbstring']['help'] = wc_help_tip( __( 'Multibyte String (mbstring) is used to convert character encoding, like for emails or converting characters to lowercase.', 'woocommerce' ) ); - - if ( extension_loaded( 'mbstring' ) ) { - $posting['mbstring']['success'] = true; - } else { - $posting['mbstring']['success'] = false; - $posting['mbstring']['note'] = sprintf( __( 'Your server does not support the %s functions - this is required for better character encoding. Some fallbacks will be used instead for it.', 'woocommerce' ), 'mbstring' ); - } - - // WP Remote Post Check. - $posting['wp_remote_post']['name'] = __( 'Remote Post', 'woocommerce'); - $posting['wp_remote_post']['help'] = wc_help_tip( __( 'PayPal uses this method of communicating when sending back transaction information.', 'woocommerce' ) ); - - $response = wp_safe_remote_post( 'https://www.paypal.com/cgi-bin/webscr', array( - 'timeout' => 60, - 'user-agent' => 'WooCommerce/' . WC()->version, - 'httpversion' => '1.1', - 'body' => array( - 'cmd' => '_notify-validate' - ) - ) ); - - if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 ) { - $posting['wp_remote_post']['success'] = true; - } else { - $posting['wp_remote_post']['note'] = __( 'wp_remote_post() failed. PayPal IPN won\'t work with your server. Contact your hosting provider.', 'woocommerce' ); - if ( is_wp_error( $response ) ) { - $posting['wp_remote_post']['note'] .= ' ' . sprintf( __( 'Error: %s', 'woocommerce' ), wc_clean( $response->get_error_message() ) ); + + : + + '; } else { - $posting['wp_remote_post']['note'] .= ' ' . sprintf( __( 'Status code: %s', 'woocommerce' ), wc_clean( $response['response']['code'] ) ); - } - $posting['wp_remote_post']['success'] = false; - } - - // WP Remote Get Check. - $posting['wp_remote_get']['name'] = __( 'Remote Get', 'woocommerce'); - $posting['wp_remote_get']['help'] = wc_help_tip( __( 'WooCommerce plugins may use this method of communication when checking for plugin updates.', 'woocommerce' ) ); - - $response = wp_safe_remote_get( 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=' . ( is_multisite() ? '1' : '0' ) ); - - if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 ) { - $posting['wp_remote_get']['success'] = true; - } else { - $posting['wp_remote_get']['note'] = __( 'wp_remote_get() failed. The WooCommerce plugin updater won\'t work with your server. Contact your hosting provider.', 'woocommerce' ); - if ( is_wp_error( $response ) ) { - $posting['wp_remote_get']['note'] .= ' ' . sprintf( __( 'Error: %s', 'woocommerce' ), wc_clean( $response->get_error_message() ) ); + echo ' ' . __( 'Your server does not have fsockopen or cURL enabled - PayPal IPN and other scripts which communicate with other servers will not work. Contact your hosting provider.', 'woocommerce' ) . ''; + } ?> + + + + : + + '; } else { - $posting['wp_remote_get']['note'] .= ' ' . sprintf( __( 'Status code: %s', 'woocommerce' ), wc_clean( $response['response']['code'] ) ); - } - $posting['wp_remote_get']['success'] = false; - } - - $posting = apply_filters( 'woocommerce_debug_posting', $posting ); - - foreach ( $posting as $post ) { - $mark = ! empty( $post['success'] ) ? 'yes' : 'error'; - ?> - - : - - - - ' : ''; ?> - - - - + echo ' ' . sprintf( __( 'Your server does not have the %s class enabled - some gateway plugins which use SOAP may not work as expected.', 'woocommerce' ), 'SoapClient' ) . ''; + } ?> + + + + : + + '; + } else { + echo ' ' . sprintf( __( 'Your server does not have the %s class enabled - HTML/Multipart emails, and also some extensions, will not work without DOMDocument.', 'woocommerce' ), 'DOMDocument' ) . ''; + } ?> + + + + : + + '; + } else { + echo ' ' . sprintf( __( 'Your server does not support the %s function - this is required to use the GeoIP database from MaxMind.', 'woocommerce' ), 'gzopen' ) . ''; + } ?> + + + + : + + '; + } else { + echo ' ' . sprintf( __( 'Your server does not support the %s functions - this is required for better character encoding. Some fallbacks will be used instead for it.', 'woocommerce' ), 'mbstring' ) . ''; + } ?> + + + + : + + '; + } else { + echo ' ' . __( 'wp_remote_post() failed. Contact your hosting provider.', 'woocommerce' ) . ' ' . esc_html( $environment['remote_post_response'] ) . ''; + } ?> + + + + : + + '; + } else { + echo ' ' . __( 'wp_remote_get() failed. Contact your hosting provider.', 'woocommerce' ) . ' ' . esc_html( $environment['remote_get_response'] ) . ''; + } ?> + + @@ -344,137 +284,83 @@ global $wpdb; - + - - - - - - - - - - - - - - $table_exists ) { ?> - + + + + + + + + + + + +
    :
      prefix ) > 20 ) { - echo ' ' . sprintf( __( '%s - We recommend using a prefix with less than 20 characters. See: %s', 'woocommerce' ), esc_html( $wpdb->prefix ), '' . __( 'How to update your database table prefix', 'woocommerce' ) . '' ) . ''; + if ( strlen( $database['database_prefix'] ) > 20 ) { + echo ' ' . sprintf( __( '%s - We recommend using a prefix with less than 20 characters. See: %s', 'woocommerce' ), esc_html( $database['database_prefix'] ), '' . __( 'How to update your database table prefix', 'woocommerce' ) . '' ) . ''; } else { - echo '' . esc_html( $wpdb->prefix ) . ''; + echo '' . esc_html( $database['database_prefix'] ) . ''; } ?>
     get_var( $wpdb->prepare( "SHOW TABLES LIKE %s;", $wpdb->prefix . $table ) ) !== $wpdb->prefix . $table ? ' ' . __( 'Table does not exist', 'woocommerce' ) . '' : ''; ?>
    : ' . esc_html( WC_Geolocation::get_local_database_path() ) . ' '; - } else { - printf( ' ' . sprintf( __( 'The MaxMind GeoIP Database does not exist - Geolocation will not function. You can download and install it manually from %1$s to the path: %2$s. Scroll down to \"Downloads\" and download the \"Binary / gzip\" file next to \"GeoLite Country\". Please remember to uncompress GeoIP.dat.gz and upload the GeoIP.dat file only.', 'woocommerce' ), make_clickable( 'http://dev.maxmind.com/geoip/legacy/geolite/' ), '' . WC_Geolocation::get_local_database_path() . '' ) . '', WC_LOG_DIR ); - } - ?>
      ' . __( 'Table does not exist', 'woocommerce' ) . '' : ''; ?>
    : ' . esc_html( $database['maxmind_geoip_database'] ) . ' '; + } else { + printf( ' ' . sprintf( __( 'The MaxMind GeoIP Database does not exist - Geolocation will not function. You can download and install it manually from %1$s to the path: %2$s. Scroll down to \"Downloads\" and download the \"Binary / gzip\" file next to \"GeoLite Country\". Please remember to uncompress GeoIP.dat.gz and upload the GeoIP.dat file only.', 'woocommerce' ), make_clickable( 'http://dev.maxmind.com/geoip/legacy/geolite/' ), '' . $database['maxmind_geoip_database'] . '' ) . '', WC_LOG_DIR ); + } + ?>
    - + ' . $plugin_name . ''; + $plugin_name = esc_html( $plugin['name'] ); + if ( ! empty( $plugin['url'] ) ) { + $plugin_name = '' . $plugin_name . ''; } - if ( strstr( $dirname, 'woocommerce-' ) && strstr( $plugin_data['PluginURI'], 'woothemes.com' ) ) { - - if ( false === ( $version_data = get_transient( md5( $plugin ) . '_version_data' ) ) ) { - $changelog = wp_safe_remote_get( 'http://dzv365zjfbd8v.cloudfront.net/changelogs/' . $dirname . '/changelog.txt' ); - $cl_lines = explode( "\n", wp_remote_retrieve_body( $changelog ) ); - if ( ! empty( $cl_lines ) ) { - foreach ( $cl_lines as $line_num => $cl_line ) { - if ( preg_match( '/^[0-9]/', $cl_line ) ) { - - $date = str_replace( '.' , '-' , trim( substr( $cl_line , 0 , strpos( $cl_line , '-' ) ) ) ); - $version = preg_replace( '~[^0-9,.]~' , '' ,stristr( $cl_line , "version" ) ); - $update = trim( str_replace( "*" , "" , $cl_lines[ $line_num + 1 ] ) ); - $version_data = array( 'date' => $date , 'version' => $version , 'update' => $update , 'changelog' => $changelog ); - set_transient( md5( $plugin ) . '_version_data', $version_data, DAY_IN_SECONDS ); - break; - } - } - } + $version_string = ''; + $network_string = ''; + if ( strstr( $plugin['url'], 'woothemes.com' ) ) { + if ( ! empty( $plugin['version_latest'] ) && version_compare( $plugin['version_latest'], $plugin['version'], '>' ) ) { + $version_string = ' – ' . esc_html( sprintf( _x( '%s is available', 'Version info', 'woocommerce' ), $plugin['version_latest'] ) ) . ''; } - if ( ! empty( $version_data['version'] ) && version_compare( $version_data['version'], $plugin_data['Version'], '>' ) ) { - $version_string = ' – ' . esc_html( sprintf( _x( '%s is available', 'Version info', 'woocommerce' ), $version_data['version'] ) ) . ''; - } - - if ( $plugin_data['Network'] != false ) { + if ( $plugin['network_activated'] != false ) { $network_string = ' – ' . __( 'Network enabled', 'woocommerce' ) . ''; } } - ?> - + + + + + + - + - + - + - + - + - + - -

    ()

    ()

     
    :' : ''; ?>
    : ' : ''; ?>' : ''; ?>
    () ()
    - - - - - - - - - - + +

    :' : ''; ?> + $name ) { + $display_terms[] = strtolower( $name ) . ' (' . $slug . ')'; + } + echo implode( ', ', array_map( 'esc_html', $display_terms ) ); + ?>
    @@ -543,177 +431,109 @@ global $wpdb; array( - 'option' => 'woocommerce_shop_page_id', - 'shortcode' => '', - 'help' => __( 'The URL of your WooCommerce shop\'s homepage (along with the Page ID).', 'woocommerce' ), - ), - _x( 'Cart', 'Page setting', 'woocommerce' ) => array( - 'option' => 'woocommerce_cart_page_id', - 'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']', - 'help' => __( 'The URL of your WooCommerce shop\'s cart (along with the page ID).', 'woocommerce' ), - ), - _x( 'Checkout', 'Page setting', 'woocommerce' ) => array( - 'option' => 'woocommerce_checkout_page_id', - 'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']', - 'help' => __( 'The URL of your WooCommerce shop\'s checkout (along with the page ID).', 'woocommerce' ), - ), - _x( 'My Account', 'Page setting', 'woocommerce' ) => array( - 'option' => 'woocommerce_myaccount_page_id', - 'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']', - 'help' => __( 'The URL of your WooCommerce shop\'s “My Account” Page (along with the page ID).', 'woocommerce' ), - ) - ); - $alt = 1; - - foreach ( $check_pages as $page_name => $values ) { + foreach ( $pages as $page ) { $error = false; - $page_id = get_option( $values['option'] ); - if ( $page_id ) { - $page_name = '' . esc_html( $page_name ) . ''; + if ( $page['page_id'] ) { + $page_name = '' . esc_html( $page['page_name'] ) . ''; } else { - $page_name = esc_html( $page_name ); + $page_name = esc_html( $page['page_name'] ); } echo '' . $page_name . ':'; - echo '' . wc_help_tip( $values['help'] ) . ''; + echo '' . wc_help_tip( sprintf( __( 'The URL of your WooCommerce shop\'s %s (along with the Page ID).', 'woocommerce' ), $page_name ) ) . ''; // Page ID check. - if ( ! $page_id ) { + if ( ! $page['page_set'] ) { echo ' ' . __( 'Page not set', 'woocommerce' ) . ''; $error = true; - } else if ( ! get_post( $page_id ) ) { + } else if ( ! $page['page_exists'] ) { echo ' ' . __( 'Page ID is set, but the page does not exist', 'woocommerce' ) . ''; $error = true; - } else if ( get_post_status( $page_id ) !== 'publish' ) { + } else if ( ! $page['page_visible'] ) { echo ' ' . sprintf( __( 'Page visibility should be %spublic%s', 'woocommerce' ), '', '' ) . ''; $error = true; } else { - // Shortcode check - if ( $values['shortcode'] ) { - $page = get_post( $page_id ); - - if ( empty( $page ) ) { - - echo ' ' . sprintf( __( 'Page does not exist', 'woocommerce' ) ) . ''; + if ( $page['shortcode_required'] ) { + if ( ! $page['shortcode_present'] ) { + echo ' ' . sprintf( __( 'Page does not contain the shortcode.', 'woocommerce' ), $page['shortcode'] ) . ''; $error = true; - - } else if ( ! strstr( $page->post_content, $values['shortcode'] ) ) { - - echo ' ' . sprintf( __( 'Page does not contain the shortcode: %s', 'woocommerce' ), $values['shortcode'] ) . ''; - $error = true; - } } - } - if ( ! $error ) echo '#' . absint( $page_id ) . ' - ' . str_replace( home_url(), '', get_permalink( $page_id ) ) . ''; + if ( ! $error ) echo '#' . absint( $page['page_id'] ) . ' - ' . str_replace( home_url(), '', get_permalink( $page['page_id'] ) ) . ''; echo ''; } ?> - - - - - - - - - - - - - -

    :  0 ) ); - foreach ( $terms as $term ) { - $display_terms[] = strtolower( $term->name ) . ' (' . $term->slug . ')'; - } - echo implode( ', ', array_map( 'esc_html', $display_terms ) ); - ?>
    - Version; - $update_theme_version = WC_Admin_Status::get_latest_theme_version( $active_theme ); - ?> - + - + Template ); - $update_theme_version = WC_Admin_Status::get_latest_theme_version( $parent_theme ); + if( $theme['is_child_theme'] ) : ?> - + - + - + - + WC()->plugin_path() . '/templates/' ) ); - $scanned_files = array(); - $found_files = array(); - $outdated_templates = false; - - foreach ( $template_paths as $plugin_name => $template_path ) { - - $scanned_files = WC_Admin_Status::scan_template_files( $template_path ); - - foreach ( $scanned_files as $file ) { - if ( file_exists( get_stylesheet_directory() . '/' . $file ) ) { - $theme_file = get_stylesheet_directory() . '/' . $file; - } elseif ( file_exists( get_stylesheet_directory() . '/woocommerce/' . $file ) ) { - $theme_file = get_stylesheet_directory() . '/woocommerce/' . $file; - } elseif ( file_exists( get_template_directory() . '/' . $file ) ) { - $theme_file = get_template_directory() . '/' . $file; - } elseif( file_exists( get_template_directory() . '/woocommerce/' . $file ) ) { - $theme_file = get_template_directory() . '/woocommerce/' . $file; - } else { - $theme_file = false; - } - - if ( ! empty( $theme_file ) ) { - $core_version = WC_Admin_Status::get_file_version( $template_path . $file ); - $theme_version = WC_Admin_Status::get_file_version( $theme_file ); - - if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) { - if ( ! $outdated_templates ) { - $outdated_templates = true; - } - $found_files[ $plugin_name ][] = sprintf( __( '%s version %s is out of date. The core version is %s', 'woocommerce' ), str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ), $theme_version ? $theme_version : '-', $core_version ); - } else { - $found_files[ $plugin_name ][] = sprintf( '%s', str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ) ); - } - } - } - } - - if ( ! empty( $found_files ) ) { - foreach ( $found_files as $plugin_name => $found_plugin_files ) { - ?> + if ( ! empty( $theme['overrides'] ) ) { ?> - + - + @@ -795,12 +589,12 @@ global $wpdb; - + - + 'string', 'context' => array( 'view', 'edit' ), ), + 'version_latest' => array( + 'description' => __( 'Latest Version Of Theme', 'woocommerce' ), + 'type' => 'string', + 'context' => array( 'view', 'edit' ), + ), 'author_url' => array( 'description' => __( 'Theme Author URL', 'woocommerce' ), 'type' => 'string', @@ -319,6 +324,16 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { 'type' => 'boolean', 'context' => array( 'view', 'edit' ), ), + 'has_woocommerce_file' => array( + 'description' => __( 'Does the theme have a woocommerce.php file?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), + 'has_outdated_templates' => array( + 'description' => __( 'Does this theme have outdated templates?', 'woocommerce' ), + 'type' => 'boolean', + 'context' => array( 'view', 'edit' ), + ), 'overrides' => array( 'description' => __( 'Template Overrides', 'woocommerce' ), 'type' => 'array', @@ -563,14 +578,56 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { $active_plugins_data = array(); foreach ( $active_plugins as $plugin ) { - $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); + $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); + $dirname = dirname( $plugin ); + $theme_version_latest = ''; + if ( strstr( $data['PluginURI'], 'woothemes.com' ) ) { + if ( false === ( $version_data = get_transient( md5( $plugin ) . '_version_data' ) ) ) { + $changelog = wp_safe_remote_get( 'http://dzv365zjfbd8v.cloudfront.net/changelogs/' . $dirname . '/changelog.txt' ); + $cl_lines = explode( "\n", wp_remote_retrieve_body( $changelog ) ); + if ( ! empty( $cl_lines ) ) { + foreach ( $cl_lines as $line_num => $cl_line ) { + if ( preg_match( '/^[0-9]/', $cl_line ) ) { + $date = str_replace( '.' , '-' , trim( substr( $cl_line , 0 , strpos( $cl_line , '-' ) ) ) ); + $version = preg_replace( '~[^0-9,.]~' , '' ,stristr( $cl_line , "version" ) ); + $update = trim( str_replace( "*" , "" , $cl_lines[ $line_num + 1 ] ) ); + $version_data = array( 'date' => $date , 'version' => $version , 'update' => $update , 'changelog' => $changelog ); + set_transient( md5( $plugin ) . '_version_data', $version_data, DAY_IN_SECONDS ); + break; + } + } + } + } + $theme_version_latest = $version_data['version']; + } else { + include_once( ABSPATH . 'wp-admin/includes/plugin-install.php' ); + $slug = explode( '/', $plugin ); + $slug = explode( '.', end( $slug ) ); + $slug = $slug[0]; + + $api = plugins_api( 'plugin_information', array( + 'slug' => $slug, + 'fields' => array( + 'sections' => false, + 'tags' => false, + ) + ) ); + + if ( is_object( $api ) && ! is_wp_error( $api ) ) { + $theme_version_latest = $api->version; + } + } + // convert plugin data to json response format. $active_plugins_data[] = array( - 'name' => $data['Name'], - 'version' => $data['Version'], - 'url' => $data['PluginURI'], - 'author_name' => $data['AuthorName'], - 'author_url' => esc_url_raw( $data['AuthorURI'] ), + 'plugin' => $plugin, + 'name' => $data['Name'], + 'version' => $data['Version'], + 'version_latest' => $theme_version_latest, + 'url' => $data['PluginURI'], + 'author_name' => $data['AuthorName'], + 'author_url' => esc_url_raw( $data['AuthorURI'] ), + 'network_activated' => $data['Network'], ); } @@ -591,20 +648,22 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { if ( is_child_theme() ) { $parent_theme = wp_get_theme( $active_theme->Template ); $parent_theme_info = array( - 'parent_name' => $parent_theme->Name, - 'parentversion' => $parent_theme->Version, - 'parent_author_url' => $parent_theme->{'Author URI'}, + 'parent_name' => $parent_theme->Name, + 'parent_version' => $parent_theme->Version, + 'parent_version_latest' => WC_Admin_Status::get_latest_theme_version( $parent_theme ), + 'parent_author_url' => $parent_theme->{'Author URI'}, ); } else { - $parent_theme_info = array( 'parent_theme_name' => '', 'parent_theme_version' => '', 'parent_theme_author_url' => '' ); + $parent_theme_info = array( 'parent_name' => '', 'parent_version' => '', 'parent_version_latest' => '', 'parent_author_url' => '' ); } /** * Scan the theme directory for all WC templates to see if our theme * overrides any of them. */ - $override_files = array(); - $scan_files = WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' ); + $override_files = array(); + $outdated_templates = false; + $scan_files = WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' ); foreach ( $scan_files as $file ) { if ( file_exists( get_stylesheet_directory() . '/' . $file ) ) { $theme_file = get_stylesheet_directory() . '/' . $file; @@ -619,16 +678,30 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { } if ( ! empty( $theme_file ) ) { - $override_files[] = str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ); + $core_version = WC_Admin_Status::get_file_version( WC()->plugin_path() . '/templates/' . $file ); + $theme_version = WC_Admin_Status::get_file_version( $theme_file ); + if ( $core_version && ( empty( $theme_version ) || version_compare( $theme_version, $core_version, '<' ) ) ) { + if ( ! $outdated_templates ) { + $outdated_templates = true; + } + } + $override_files[] = array( + 'file' => str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file ), + 'version' => $theme_version, + 'core_version' => $core_version, + ); } } $active_theme_info = array( 'name' => $active_theme->Name, 'version' => $active_theme->Version, + 'version_latest' => WC_Admin_Status::get_latest_theme_version( $active_theme ), 'author_url' => esc_url_raw( $active_theme->{'Author URI'} ), 'is_child_theme' => is_child_theme(), 'has_woocommerce_support' => ( current_theme_supports( 'woocommerce' ) || in_array( $active_theme->template, wc_get_core_supported_themes() ) ), + 'has_woocommerce_file' => ( file_exists( get_stylesheet_directory() . '/woocommerce.php' ) || file_exists( get_template_directory() . '/woocommerce.php' ) ), + 'has_outdated_templates' => $outdated_templates, 'overrides' => $override_files, ); @@ -725,6 +798,7 @@ class WC_REST_System_Status_Controller extends WC_REST_Controller { 'page_set' => $page_set, 'page_exists' => $page_exists, 'page_visible' => $page_visible, + 'shortcode' => $values['shortcode'], 'shortcode_required' => $shortcode_required, 'shortcode_present' => $shortcode_present, ); diff --git a/tests/unit-tests/api/system-status.php b/tests/unit-tests/api/system-status.php index f35ebf458e0..3ef0e0d0d19 100644 --- a/tests/unit-tests/api/system-status.php +++ b/tests/unit-tests/api/system-status.php @@ -126,7 +126,7 @@ class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case { $data = $response->get_data(); $theme = $data['theme']; - $this->assertEquals( 9, count( $theme ) ); + $this->assertEquals( 13, count( $theme ) ); $this->assertEquals( $active_theme->Name, $theme['name'] ); } From cad08747b96ec6005bcadb82640fd96f1b8ff804 Mon Sep 17 00:00:00 2001 From: Justin Shreve Date: Wed, 3 Aug 2016 13:32:02 -0700 Subject: [PATCH 273/298] Add bulk edit and quick edit to the list of hooks for the product.updated webhook. --- includes/class-wc-install.php | 3 +++ includes/class-wc-webhook.php | 6 ++++++ includes/wc-update-functions.php | 17 +++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/includes/class-wc-install.php b/includes/class-wc-install.php index 57bfc7942fe..5bea84ac6bc 100644 --- a/includes/class-wc-install.php +++ b/includes/class-wc-install.php @@ -72,6 +72,9 @@ class WC_Install { 'wc_update_260_refunds', 'wc_update_260_db_version', ), + '2.7.0' => array( + 'wc_update_270_webhooks', + ), ); /** @var object Background update class */ diff --git a/includes/class-wc-webhook.php b/includes/class-wc-webhook.php index bd716a23c90..4d9891dac9b 100644 --- a/includes/class-wc-webhook.php +++ b/includes/class-wc-webhook.php @@ -270,6 +270,10 @@ class WC_Webhook { break; case 'product': + // bulk and quick edit action hooks return a product object instead of an ID + if ( 'updated' === $event && is_a( $resource_id, 'WC_Product' ) ) { + $resource_id = $resource_id->get_id(); + } $payload = WC()->api->WC_API_Products->get_product( $resource_id ); break; @@ -581,6 +585,8 @@ class WC_Webhook { 'product.updated' => array( 'woocommerce_process_product_meta', 'woocommerce_api_edit_product', + 'woocommerce_product_quick_edit_save', + 'woocommerce_product_bulk_edit_save', ), 'product.deleted' => array( 'wp_trash_post', diff --git a/includes/wc-update-functions.php b/includes/wc-update-functions.php index 423538394d1..456ff7dc085 100644 --- a/includes/wc-update-functions.php +++ b/includes/wc-update-functions.php @@ -970,3 +970,20 @@ function wc_update_260_refunds() { function wc_update_260_db_version() { WC_Install::update_db_version( '2.6.0' ); } + +function wc_update_270_webhooks() { + /** + * Make sure product.update webhooks get the woocommerce_product_quick_edit_save + * and woocommerce_product_bulk_edit_save hooks. + */ + $product_update_webhooks = get_posts( array( + 'posts_per_page' => -1, + 'post_type' => 'shop_webhook', + 'meta_key' => '_topic', + 'meta_value' => 'product.updated' + ) ); + foreach ( $product_update_webhooks as $product_update_webhook ) { + $webhook = new WC_Webhook( $product_update_webhook->ID ); + $webhook->set_topic( 'product.updated' ); + } +} From abc954dc83cb01a231a3f6f1fcbaf4036f2e9002 Mon Sep 17 00:00:00 2001 From: Caleb Burks <19caleb95@gmail.com> Date: Thu, 4 Aug 2016 03:16:58 -0400 Subject: [PATCH 274/298] Add responsive image markup to category thumbnails --- includes/wc-template-functions.php | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 82156adfa7b..6393a503db7 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -1748,10 +1748,13 @@ if ( ! function_exists( 'woocommerce_subcategory_thumbnail' ) ) { $thumbnail_id = get_woocommerce_term_meta( $category->term_id, 'thumbnail_id', true ); if ( $thumbnail_id ) { - $image = wp_get_attachment_image_src( $thumbnail_id, $small_thumbnail_size ); - $image = $image[0]; + $image = wp_get_attachment_image_src( $thumbnail_id, $small_thumbnail_size ); + $image = $image[0]; + $image_srcset = function_exists( 'wp_get_attachment_image_srcset' ) ? wp_get_attachment_image_srcset( $thumbnail_id, $small_thumbnail_size ) : false; + $image_sizes = function_exists( 'wp_get_attachment_image_sizes' ) ? wp_get_attachment_image_sizes( $thumbnail_id, $small_thumbnail_size ) : false; } else { $image = wc_placeholder_img_src(); + $image_srcset = $image_sizes = false; } if ( $image ) { @@ -1759,7 +1762,12 @@ if ( ! function_exists( 'woocommerce_subcategory_thumbnail' ) ) { // Ref: https://core.trac.wordpress.org/ticket/23605 $image = str_replace( ' ', '%20', $image ); - echo '' . esc_attr( $category->name ) . ''; + // Add responsive image markup if available + if ( $image_srcset && $image_sizes ) { + echo '' . esc_attr( $category->name ) . ''; + } else { + echo '' . esc_attr( $category->name ) . ''; + } } } } From a32f65df609b454165d3d790fe2f9d8e2528ba1a Mon Sep 17 00:00:00 2001 From: Caleb Burks <19caleb95@gmail.com> Date: Thu, 4 Aug 2016 03:28:03 -0400 Subject: [PATCH 275/298] Formatting fix --- includes/wc-template-functions.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 6393a503db7..b5ea3152439 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -1751,9 +1751,9 @@ if ( ! function_exists( 'woocommerce_subcategory_thumbnail' ) ) { $image = wp_get_attachment_image_src( $thumbnail_id, $small_thumbnail_size ); $image = $image[0]; $image_srcset = function_exists( 'wp_get_attachment_image_srcset' ) ? wp_get_attachment_image_srcset( $thumbnail_id, $small_thumbnail_size ) : false; - $image_sizes = function_exists( 'wp_get_attachment_image_sizes' ) ? wp_get_attachment_image_sizes( $thumbnail_id, $small_thumbnail_size ) : false; + $image_sizes = function_exists( 'wp_get_attachment_image_sizes' ) ? wp_get_attachment_image_sizes( $thumbnail_id, $small_thumbnail_size ) : false; } else { - $image = wc_placeholder_img_src(); + $image = wc_placeholder_img_src(); $image_srcset = $image_sizes = false; } From e02d4b91ff3d40882de22cf97d9571b03fd43dca Mon Sep 17 00:00:00 2001 From: Caleb Burks <19caleb95@gmail.com> Date: Thu, 4 Aug 2016 03:33:43 -0400 Subject: [PATCH 276/298] Readme update For forum support stuffs --- readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.txt b/readme.txt index 0afc8bc48be..1d35833b27f 100644 --- a/readme.txt +++ b/readme.txt @@ -1,5 +1,5 @@ === WooCommerce === -Contributors: automattic, mikejolley, jameskoster, claudiosanches, jshreve, coderkevin, woothemes, BFTrick +Contributors: automattic, mikejolley, jameskoster, claudiosanches, jshreve, coderkevin, woothemes, BFTrick, iCaleb Tags: ecommerce, e-commerce, store, sales, sell, shop, cart, checkout, downloadable, downloads, paypal, storefront Requires at least: 4.4 Tested up to: 4.5 From b0064bddf64168b4dea857c5f3f6b62f8efeae90 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 4 Aug 2016 11:12:14 +0100 Subject: [PATCH 277/298] Remove boolval --- includes/class-wc-product-variable.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/class-wc-product-variable.php b/includes/class-wc-product-variable.php index bce1de9c8cb..b14dbb733e8 100644 --- a/includes/class-wc-product-variable.php +++ b/includes/class-wc-product-variable.php @@ -729,7 +729,7 @@ class WC_Product_Variable extends WC_Product { * @return boolean */ public function child_has_weight() { - return boolval( get_post_meta( $this->id, '_child_has_weight', true ) ); + return (bool) get_post_meta( $this->id, '_child_has_weight', true ); } /** @@ -738,7 +738,7 @@ class WC_Product_Variable extends WC_Product { * @return boolean */ public function child_has_dimensions() { - return boolval( get_post_meta( $this->id, '_child_has_dimensions', true ) ); + return (bool) get_post_meta( $this->id, '_child_has_dimensions', true ); } /** From 475d8fc5ed65d6a9d6d650aa5bc654d250d01787 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 4 Aug 2016 11:27:38 +0100 Subject: [PATCH 278/298] [2.6] More password check to else block Closes #11623 --- includes/class-wc-form-handler.php | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/includes/class-wc-form-handler.php b/includes/class-wc-form-handler.php index b2aca304b2d..4b11ab44fbb 100644 --- a/includes/class-wc-form-handler.php +++ b/includes/class-wc-form-handler.php @@ -211,11 +211,6 @@ class WC_Form_Handler { $user->user_email = $account_email; } - if ( ! empty( $pass1 ) && ! wp_check_password( $pass_cur, $current_user->user_pass, $current_user->ID ) ) { - wc_add_notice( __( 'Your current password is incorrect.', 'woocommerce' ), 'error' ); - $save_pass = false; - } - if ( ! empty( $pass_cur ) && empty( $pass1 ) && empty( $pass2 ) ) { wc_add_notice( __( 'Please fill out all password fields.', 'woocommerce' ), 'error' ); $save_pass = false; @@ -228,6 +223,9 @@ class WC_Form_Handler { } elseif ( ( ! empty( $pass1 ) || ! empty( $pass2 ) ) && $pass1 !== $pass2 ) { wc_add_notice( __( 'New passwords do not match.', 'woocommerce' ), 'error' ); $save_pass = false; + } elseif ( ! empty( $pass1 ) && ! wp_check_password( $pass_cur, $current_user->user_pass, $current_user->ID ) ) { + wc_add_notice( __( 'Your current password is incorrect.', 'woocommerce' ), 'error' ); + $save_pass = false; } if ( $pass1 && $save_pass ) { From 75895f71f935e847962f023e1b64d6428020dcda Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 4 Aug 2016 13:09:21 +0100 Subject: [PATCH 279/298] made comparison strict #11326 --- includes/wc-template-functions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 96dc98cf561..e1600e8f887 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -349,7 +349,7 @@ function wc_query_string_form_fields( $values = null, $exclude = array(), $curre $values = $_GET; } foreach ( $values as $key => $value ) { - if ( in_array( $key, $exclude ) ) { + if ( in_array( $key, $exclude, true ) ) { continue; } if ( $current_key ) { From 644cf798668e8b400aa0cffaeaf02c72cf611883 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 4 Aug 2016 13:37:39 +0100 Subject: [PATCH 280/298] Move all query string vars to form in price widget using wc_query_string_form_fields Closes #11593 @claudiosmweb @justinshreve look fine to you? --- includes/wc-template-functions.php | 14 +++++-- .../widgets/class-wc-widget-price-filter.php | 41 +------------------ 2 files changed, 12 insertions(+), 43 deletions(-) diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index e1600e8f887..dc62f534dab 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -344,10 +344,12 @@ function wc_product_post_class( $classes, $class = '', $post_id = '' ) { * @param array $exclude Keys to exclude. * @param string $current_key Current key we are outputting. */ -function wc_query_string_form_fields( $values = null, $exclude = array(), $current_key = '' ) { +function wc_query_string_form_fields( $values = null, $exclude = array(), $current_key = '', $return = false ) { if ( is_null( $values ) ) { $values = $_GET; } + $html = ''; + foreach ( $values as $key => $value ) { if ( in_array( $key, $exclude, true ) ) { continue; @@ -356,11 +358,17 @@ function wc_query_string_form_fields( $values = null, $exclude = array(), $curre $key = $current_key . '[' . $key . ']'; } if ( is_array( $value ) ) { - wc_query_string_form_fields( $value, $exclude, $key ); + $html .= wc_query_string_form_fields( $value, $exclude, $key, true ); } else { - echo ''; + $html .= ''; } } + + if ( $return ) { + return $html; + } else { + echo $html; + } } /** Template pages ********************************************************/ diff --git a/includes/widgets/class-wc-widget-price-filter.php b/includes/widgets/class-wc-widget-price-filter.php index fb70ebdf3dd..a9010ffb288 100644 --- a/includes/widgets/class-wc-widget-price-filter.php +++ b/includes/widgets/class-wc-widget-price-filter.php @@ -68,45 +68,6 @@ class WC_Widget_Price_Filter extends WC_Widget { wp_enqueue_script( 'wc-price-slider' ); - // Remember current filters/search - $fields = ''; - - if ( get_search_query() ) { - $fields .= ''; - } - - if ( ! empty( $_GET['post_type'] ) ) { - $fields .= ''; - } - - if ( ! empty ( $_GET['product_cat'] ) ) { - $fields .= ''; - } - - if ( ! empty( $_GET['product_tag'] ) ) { - $fields .= ''; - } - - if ( ! empty( $_GET['orderby'] ) ) { - $fields .= ''; - } - - if ( ! empty( $_GET['min_rating'] ) ) { - $fields .= ''; - } - - if ( $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes() ) { - foreach ( $_chosen_attributes as $attribute => $data ) { - $taxonomy_filter = 'filter_' . str_replace( 'pa_', '', $attribute ); - - $fields .= ''; - - if ( 'or' == $data['query_type'] ) { - $fields .= ''; - } - } - } - // Find min and max price in current result set $prices = $this->get_filtered_price(); $min = floor( $prices->min_price ); @@ -152,7 +113,7 @@ class WC_Widget_Price_Filter extends WC_Widget { - ' . $fields . ' + ' . wc_query_string_form_fields( null, array( 'min_price', 'max_price' ), '', true ) . '
    From 387cd745c218835fbc37da93d1f4de758d606937 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 4 Aug 2016 14:43:34 +0100 Subject: [PATCH 281/298] Add missing textdomains --- .../abstract-wc-rest-shipping-zones-controller.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php b/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php index 77c175fcde4..ea9f0d45f3c 100644 --- a/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php +++ b/includes/abstracts/abstract-wc-rest-shipping-zones-controller.php @@ -60,7 +60,7 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller */ public function get_items_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'read' ) ) { @@ -78,7 +78,7 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller */ public function create_item_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { @@ -96,7 +96,7 @@ abstract class WC_REST_Shipping_Zones_Controller_Base extends WC_REST_Controller */ public function update_items_permissions_check( $request ) { if ( ! wc_shipping_enabled() ) { - return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.' ), array( 'status' => 404 ) ); + return new WP_Error( 'rest_no_route', __( 'Shipping is disabled.', 'woocommerce' ), array( 'status' => 404 ) ); } if ( ! wc_rest_check_manager_permissions( 'settings', 'edit' ) ) { From a3ae757106154c4d558ef944d820d3164e1fcef4 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 4 Aug 2016 17:05:05 +0100 Subject: [PATCH 282/298] Make set/get_order_id methods private --- includes/class-wc-order-item.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/class-wc-order-item.php b/includes/class-wc-order-item.php index 630b278bc1e..c728ba84942 100644 --- a/includes/class-wc-order-item.php +++ b/includes/class-wc-order-item.php @@ -133,7 +133,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess { * Get order item ID this meta belongs to. * @return int */ - public function get_order_item_id() { + protected function get_order_item_id() { return absint( $this->_data['order_item_id'] ); } @@ -179,7 +179,7 @@ class WC_Order_Item extends WC_Data implements ArrayAccess { * Set order item ID. * @param int $value */ - public function set_order_item_id( $value ) { + protected function set_order_item_id( $value ) { $this->_data['order_item_id'] = absint( $value ); } From 8867368b971d54fdd78068f5c1452531ed8460d2 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Thu, 4 Aug 2016 17:24:23 +0100 Subject: [PATCH 283/298] Fix unit tests --- tests/unit-tests/crud/orders.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unit-tests/crud/orders.php b/tests/unit-tests/crud/orders.php index 06ec2e91cb5..76b1e493d64 100644 --- a/tests/unit-tests/crud/orders.php +++ b/tests/unit-tests/crud/orders.php @@ -1129,7 +1129,7 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case { function test_get_checkout_payment_url() { $object = new WC_Order(); $id = $object->save(); - $this->assertEquals( '?order-pay=' . $id . '&pay_for_order=true&key=' . $object->get_order_key(), $object->get_checkout_payment_url() ); + $this->assertEquals( 'http://example.org?order-pay=' . $id . '&pay_for_order=true&key=' . $object->get_order_key(), $object->get_checkout_payment_url() ); } /** @@ -1139,7 +1139,7 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case { $object = new WC_Order(); $object->set_order_key( 'xxx' ); $id = $object->save(); - $this->assertEquals( '?order-received=' . $id . '&key=' . $object->get_order_key(), $object->get_checkout_order_received_url() ); + $this->assertEquals( 'http://example.org?order-received=' . $id . '&key=' . $object->get_order_key(), $object->get_checkout_order_received_url() ); } /** @@ -1172,7 +1172,7 @@ class WC_Tests_CRUD_Orders extends WC_Unit_Test_Case { function test_get_view_order_url() { $object = new WC_Order(); $id = $object->save(); - $this->assertEquals( '?view-order=' . $id, $object->get_view_order_url() ); + $this->assertEquals( 'http://example.org?view-order=' . $id, $object->get_view_order_url() ); } /** From 152134ed5e48f0aca4e715b995bde4e67c212b13 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 5 Aug 2016 12:11:35 +0100 Subject: [PATCH 284/298] Add unit test for #11626 --- tests/unit-tests/cart/cart.php | 55 +++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 4 deletions(-) diff --git a/tests/unit-tests/cart/cart.php b/tests/unit-tests/cart/cart.php index c58dd4685cb..e70f1942807 100644 --- a/tests/unit-tests/cart/cart.php +++ b/tests/unit-tests/cart/cart.php @@ -88,14 +88,59 @@ class WC_Tests_Cart extends WC_Unit_Test_Case { $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations" ); WC()->cart->empty_cart(); WC()->cart->remove_coupons(); + WC_Helper_Product::delete_product( $product->id ); + + + # Test case 3 #11626 + update_post_meta( $coupon->id, 'discount_type', 'percent' ); + update_post_meta( $coupon->id, 'coupon_amount', '50' ); + update_option( 'woocommerce_prices_include_tax', 'yes' ); + update_option( 'woocommerce_calc_taxes', 'yes' ); + + $tax_rate = array( + 'tax_rate_country' => '', + 'tax_rate_state' => '', + 'tax_rate' => '19.0000', + 'tax_rate_name' => 'TAX', + 'tax_rate_priority' => '1', + 'tax_rate_compound' => '0', + 'tax_rate_shipping' => '1', + 'tax_rate_order' => '1', + 'tax_rate_class' => '' + ); + WC_Tax::_insert_tax_rate( $tax_rate ); + + $product_ids = array(); + $products_data = array( + '5.17', '3.32', '1.25', '3.50', '5.01', '3.34', '5.99', '5.51' + ); + foreach ( $products_data as $price ) { + $loop_product = WC_Helper_Product::create_simple_product(); + $product_ids[] = $loop_product->id; + update_post_meta( $loop_product->id, '_regular_price', $price ); + update_post_meta( $loop_product->id, '_price', $price ); + WC()->cart->add_to_cart( $loop_product->id, 1 ); + } + + WC()->cart->add_discount( $coupon->code ); + WC()->cart->calculate_totals(); + $cart_item = current( WC()->cart->get_cart() ); + $this->assertEquals( '16.55', WC()->cart->total ); + + // Cleanup + WC()->cart->empty_cart(); + WC()->cart->remove_coupons(); + + foreach ( $product_ids as $product_id ) { + WC_Helper_Product::delete_product( $product_id ); + } + + $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rates" ); + $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations" ); update_option( 'woocommerce_prices_include_tax', 'no' ); update_option( 'woocommerce_calc_taxes', 'no' ); - // Delete coupon WC_Helper_Coupon::delete_coupon( $coupon->id ); - - // Clean up product - WC_Helper_Product::delete_product( $product->id ); } /** @@ -124,6 +169,8 @@ class WC_Tests_Cart extends WC_Unit_Test_Case { // Create dummy product $product = WC_Helper_Product::create_simple_product(); + WC()->cart->empty_cart(); + // Add the product to the cart. Methods returns boolean on failure, string on success. $this->assertNotFalse( WC()->cart->add_to_cart( $product->id, 1 ) ); From 052a277400160fdbd80dce3dd0feb9dfef6421b9 Mon Sep 17 00:00:00 2001 From: Jeroen Sormani Date: Fri, 5 Aug 2016 14:15:38 +0200 Subject: [PATCH 285/298] Focus on modal, enable esc-close + init tooltips When opening the modal it doesn't allow you to close it with the ESC key unless you click on the modal first. Focussing on the modal when its loaded resolves that. Also adding tooltip initialisation so tooltips will show if they are present. I don't believe core is using tooltips in there right now, but I guess its useful for the future / 3rd party devs that may have a use for it (like me) --- assets/js/admin/backbone-modal.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/js/admin/backbone-modal.js b/assets/js/admin/backbone-modal.js index 013a40cb787..72cc8971480 100644 --- a/assets/js/admin/backbone-modal.js +++ b/assets/js/admin/backbone-modal.js @@ -88,6 +88,8 @@ }).append( this.$el ); this.resizeContent(); + this.$el.focus(); + $( document.body ).trigger( 'init_tooltips' ); $( document.body ).trigger( 'wc_backbone_modal_loaded', this._target ); }, From 54256c4123b5aa948f181c9ecf1d2b98d7974060 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 5 Aug 2016 14:06:51 +0100 Subject: [PATCH 286/298] Round prices being saved to DB --- includes/class-wc-cart.php | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/includes/class-wc-cart.php b/includes/class-wc-cart.php index 83a785d6a66..4ad64013e66 100644 --- a/includes/class-wc-cart.php +++ b/includes/class-wc-cart.php @@ -1289,8 +1289,8 @@ class WC_Cart { // Apply discounts and get the discounted price FOR A SINGLE ITEM $discounted_price = $this->get_discounted_price( $values, $adjusted_price, true ); - // Convert back to line price and round nicely - $discounted_line_price = round( $discounted_price * $values['quantity'], $this->dp ); + // Convert back to line price + $discounted_line_price = $discounted_price * $values['quantity']; // Now use rounded line price to get taxes. $discounted_taxes = WC_Tax::calc_tax( $discounted_line_price, $item_tax_rates, true ); @@ -1312,8 +1312,8 @@ class WC_Cart { // Calc prices and tax (discounted) $discounted_price = $this->get_discounted_price( $values, $base_price, true ); - // Convert back to line price and round nicely - $discounted_line_price = round( $discounted_price * $values['quantity'], $this->dp ); + // Convert back to line price + $discounted_line_price = $discounted_price * $values['quantity']; // Now use rounded line price to get taxes. $discounted_taxes = WC_Tax::calc_tax( $discounted_line_price, $item_tax_rates, true ); @@ -1356,14 +1356,26 @@ class WC_Cart { // Cart contents total is based on discounted prices and is used for the final total calculation $this->cart_contents_total += $line_total; - // Store costs + taxes for lines - $this->cart_contents[ $cart_item_key ]['line_total'] = $line_total; - $this->cart_contents[ $cart_item_key ]['line_tax'] = $line_tax; - $this->cart_contents[ $cart_item_key ]['line_subtotal'] = $line_subtotal; - $this->cart_contents[ $cart_item_key ]['line_subtotal_tax'] = $line_subtotal_tax; - - // Store rates ID and costs - Since 2.2 - $this->cart_contents[ $cart_item_key ]['line_tax_data'] = array( 'total' => $discounted_taxes, 'subtotal' => $taxes ); + /** + * Store costs + taxes for lines. For tax inclusive prices, we do some extra rounding logic so the stored + * values "add up" when viewing the order in admin. This does have the disadvatage of not being able to + * recalculate the tax total/subtotal accurately in the future, but it does ensure the data looks correct. + * + * Tax exclusive prices are not affected. + */ + if ( ! $_product->is_taxable() || $this->prices_include_tax ) { + $this->cart_contents[ $cart_item_key ]['line_total'] = round( $line_total + $line_tax - wc_round_tax_total( $line_tax ), $this->dp ); + $this->cart_contents[ $cart_item_key ]['line_subtotal'] = round( $line_subtotal + $line_subtotal_tax - wc_round_tax_total( $line_subtotal_tax ), $this->dp ); + $this->cart_contents[ $cart_item_key ]['line_tax'] = wc_round_tax_total( $line_tax ); + $this->cart_contents[ $cart_item_key ]['line_subtotal_tax'] = wc_round_tax_total( $line_subtotal_tax ); + $this->cart_contents[ $cart_item_key ]['line_tax_data'] = array( 'total' => array_map( 'wc_round_tax_total', $discounted_taxes ), 'subtotal' => array_map( 'wc_round_tax_total', $taxes ) ); + } else { + $this->cart_contents[ $cart_item_key ]['line_total'] = $line_total; + $this->cart_contents[ $cart_item_key ]['line_subtotal'] = $line_subtotal; + $this->cart_contents[ $cart_item_key ]['line_tax'] = $line_tax; + $this->cart_contents[ $cart_item_key ]['line_subtotal_tax'] = $line_subtotal_tax; + $this->cart_contents[ $cart_item_key ]['line_tax_data'] = array( 'total' => $discounted_taxes, 'subtotal' => $taxes ); + } } // Only calculate the grand total + shipping if on the cart/checkout From 559e379faf280d6dd8a3ba6b6a5326a12c06da16 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 5 Aug 2016 14:23:01 +0100 Subject: [PATCH 287/298] Issues after audit --- .gitignore | 2 + assets/css/admin.scss | 2 +- assets/js/admin/wc-enhanced-select.js | 16 +- vendor/autoload.php | 7 - vendor/composer/ClassLoader.php | 413 ------------------------ vendor/composer/LICENSE | 21 -- vendor/composer/autoload_classmap.php | 9 - vendor/composer/autoload_namespaces.php | 9 - vendor/composer/autoload_psr4.php | 9 - vendor/composer/autoload_real.php | 45 --- 10 files changed, 11 insertions(+), 522 deletions(-) delete mode 100644 vendor/autoload.php delete mode 100644 vendor/composer/ClassLoader.php delete mode 100644 vendor/composer/LICENSE delete mode 100644 vendor/composer/autoload_classmap.php delete mode 100644 vendor/composer/autoload_namespaces.php delete mode 100644 vendor/composer/autoload_psr4.php delete mode 100644 vendor/composer/autoload_real.php diff --git a/.gitignore b/.gitignore index 2ba87075ebf..dc90fddabe1 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ Thumbs.db # Logs /logs + +/vendor/ diff --git a/assets/css/admin.scss b/assets/css/admin.scss index e21e5a99890..902893d4fd3 100644 --- a/assets/css/admin.scss +++ b/assets/css/admin.scss @@ -2053,7 +2053,7 @@ table.wc_input_table { border-bottom: 1px solid #DFDFDF; border-top: 0; background: #fff; - cursor: default;; + cursor: default; input[type="text"], input[type="number"] { diff --git a/assets/js/admin/wc-enhanced-select.js b/assets/js/admin/wc-enhanced-select.js index 15defaeca5f..4163f0532bf 100644 --- a/assets/js/admin/wc-enhanced-select.js +++ b/assets/js/admin/wc-enhanced-select.js @@ -147,11 +147,11 @@ jQuery( function( $ ) { $( this ).select2( select2_args ).addClass( 'enhanced' ); - if( $( this ).data( 'sortable' ) === true ){ + if ( $( this ).data( 'sortable' ) ) { $( this ).select2( 'container' ).find( 'ul.select2-choices' ).sortable({ - containment: 'parent', - start: function() { $( this ).select2( 'onSortStart' ); }, - update: function() { $( this ).select2( 'onSortEnd' ); } + containment: 'parent', + start: function() { $( this ).select2( 'onSortStart' ); }, + update: function() { $( this ).select2( 'onSortEnd' ); } }); } @@ -227,11 +227,11 @@ jQuery( function( $ ) { $( this ).select2( select2_args ).addClass( 'enhanced' ); - if( $( this ).data( 'sortable' ) === true ){ + if ( $( this ).data( 'sortable' ) ) { $( this ).select2( 'container' ).find( 'ul.select2-choices' ).sortable({ - containment: 'parent', - start: function() { $( this ).select2( 'onSortStart' ); }, - update: function() { $( this ).select2( 'onSortEnd' ); } + containment: 'parent', + start: function() { $( this ).select2( 'onSortStart' ); }, + update: function() { $( this ).select2( 'onSortEnd' ); } }); } diff --git a/vendor/autoload.php b/vendor/autoload.php deleted file mode 100644 index 96f29177d7f..00000000000 --- a/vendor/autoload.php +++ /dev/null @@ -1,7 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer\Autoload; - -/** - * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. - * - * $loader = new \Composer\Autoload\ClassLoader(); - * - * // register classes with namespaces - * $loader->add('Symfony\Component', __DIR__.'/component'); - * $loader->add('Symfony', __DIR__.'/framework'); - * - * // activate the autoloader - * $loader->register(); - * - * // to enable searching the include path (eg. for PEAR packages) - * $loader->setUseIncludePath(true); - * - * In this example, if you try to use a class in the Symfony\Component - * namespace or one of its children (Symfony\Component\Console for instance), - * the autoloader will first look for the class under the component/ - * directory, and it will then fallback to the framework/ directory if not - * found before giving up. - * - * This class is loosely based on the Symfony UniversalClassLoader. - * - * @author Fabien Potencier - * @author Jordi Boggiano - * @see http://www.php-fig.org/psr/psr-0/ - * @see http://www.php-fig.org/psr/psr-4/ - */ -class ClassLoader -{ - // PSR-4 - private $prefixLengthsPsr4 = array(); - private $prefixDirsPsr4 = array(); - private $fallbackDirsPsr4 = array(); - - // PSR-0 - private $prefixesPsr0 = array(); - private $fallbackDirsPsr0 = array(); - - private $useIncludePath = false; - private $classMap = array(); - - private $classMapAuthoritative = false; - - public function getPrefixes() - { - if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', $this->prefixesPsr0); - } - - return array(); - } - - public function getPrefixesPsr4() - { - return $this->prefixDirsPsr4; - } - - public function getFallbackDirs() - { - return $this->fallbackDirsPsr0; - } - - public function getFallbackDirsPsr4() - { - return $this->fallbackDirsPsr4; - } - - public function getClassMap() - { - return $this->classMap; - } - - /** - * @param array $classMap Class to filename map - */ - public function addClassMap(array $classMap) - { - if ($this->classMap) { - $this->classMap = array_merge($this->classMap, $classMap); - } else { - $this->classMap = $classMap; - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, either - * appending or prepending to the ones previously set for this prefix. - * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories - */ - public function add($prefix, $paths, $prepend = false) - { - if (!$prefix) { - if ($prepend) { - $this->fallbackDirsPsr0 = array_merge( - (array) $paths, - $this->fallbackDirsPsr0 - ); - } else { - $this->fallbackDirsPsr0 = array_merge( - $this->fallbackDirsPsr0, - (array) $paths - ); - } - - return; - } - - $first = $prefix[0]; - if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; - - return; - } - if ($prepend) { - $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, - $this->prefixesPsr0[$first][$prefix] - ); - } else { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $this->prefixesPsr0[$first][$prefix], - (array) $paths - ); - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, either - * appending or prepending to the ones previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories - * - * @throws \InvalidArgumentException - */ - public function addPsr4($prefix, $paths, $prepend = false) - { - if (!$prefix) { - // Register directories for the root namespace. - if ($prepend) { - $this->fallbackDirsPsr4 = array_merge( - (array) $paths, - $this->fallbackDirsPsr4 - ); - } else { - $this->fallbackDirsPsr4 = array_merge( - $this->fallbackDirsPsr4, - (array) $paths - ); - } - } elseif (!isset($this->prefixDirsPsr4[$prefix])) { - // Register directories for a new namespace. - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } elseif ($prepend) { - // Prepend directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, - $this->prefixDirsPsr4[$prefix] - ); - } else { - // Append directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $this->prefixDirsPsr4[$prefix], - (array) $paths - ); - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, - * replacing any others previously set for this prefix. - * - * @param string $prefix The prefix - * @param array|string $paths The PSR-0 base directories - */ - public function set($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr0 = (array) $paths; - } else { - $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, - * replacing any others previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param array|string $paths The PSR-4 base directories - * - * @throws \InvalidArgumentException - */ - public function setPsr4($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr4 = (array) $paths; - } else { - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } - } - - /** - * Turns on searching the include path for class files. - * - * @param bool $useIncludePath - */ - public function setUseIncludePath($useIncludePath) - { - $this->useIncludePath = $useIncludePath; - } - - /** - * Can be used to check if the autoloader uses the include path to check - * for classes. - * - * @return bool - */ - public function getUseIncludePath() - { - return $this->useIncludePath; - } - - /** - * Turns off searching the prefix and fallback directories for classes - * that have not been registered with the class map. - * - * @param bool $classMapAuthoritative - */ - public function setClassMapAuthoritative($classMapAuthoritative) - { - $this->classMapAuthoritative = $classMapAuthoritative; - } - - /** - * Should class lookup fail if not found in the current class map? - * - * @return bool - */ - public function isClassMapAuthoritative() - { - return $this->classMapAuthoritative; - } - - /** - * Registers this instance as an autoloader. - * - * @param bool $prepend Whether to prepend the autoloader or not - */ - public function register($prepend = false) - { - spl_autoload_register(array($this, 'loadClass'), true, $prepend); - } - - /** - * Unregisters this instance as an autoloader. - */ - public function unregister() - { - spl_autoload_unregister(array($this, 'loadClass')); - } - - /** - * Loads the given class or interface. - * - * @param string $class The name of the class - * @return bool|null True if loaded, null otherwise - */ - public function loadClass($class) - { - if ($file = $this->findFile($class)) { - includeFile($file); - - return true; - } - } - - /** - * Finds the path to the file where the class is defined. - * - * @param string $class The name of the class - * - * @return string|false The path if found, false otherwise - */ - public function findFile($class) - { - // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731 - if ('\\' == $class[0]) { - $class = substr($class, 1); - } - - // class map lookup - if (isset($this->classMap[$class])) { - return $this->classMap[$class]; - } - if ($this->classMapAuthoritative) { - return false; - } - - $file = $this->findFileWithExtension($class, '.php'); - - // Search for Hack files if we are running on HHVM - if ($file === null && defined('HHVM_VERSION')) { - $file = $this->findFileWithExtension($class, '.hh'); - } - - if ($file === null) { - // Remember that this class does not exist. - return $this->classMap[$class] = false; - } - - return $file; - } - - private function findFileWithExtension($class, $ext) - { - // PSR-4 lookup - $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; - - $first = $class[0]; - if (isset($this->prefixLengthsPsr4[$first])) { - foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) { - if (0 === strpos($class, $prefix)) { - foreach ($this->prefixDirsPsr4[$prefix] as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) { - return $file; - } - } - } - } - } - - // PSR-4 fallback dirs - foreach ($this->fallbackDirsPsr4 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { - return $file; - } - } - - // PSR-0 lookup - if (false !== $pos = strrpos($class, '\\')) { - // namespaced class name - $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) - . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); - } else { - // PEAR-like class name - $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; - } - - if (isset($this->prefixesPsr0[$first])) { - foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { - if (0 === strpos($class, $prefix)) { - foreach ($dirs as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - } - } - } - - // PSR-0 fallback dirs - foreach ($this->fallbackDirsPsr0 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - - // PSR-0 include paths. - if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { - return $file; - } - } -} - -/** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - */ -function includeFile($file) -{ - include $file; -} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE deleted file mode 100644 index c8d57af8b27..00000000000 --- a/vendor/composer/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - -Copyright (c) 2015 Nils Adermann, Jordi Boggiano - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php deleted file mode 100644 index 7a91153b0d8..00000000000 --- a/vendor/composer/autoload_classmap.php +++ /dev/null @@ -1,9 +0,0 @@ - $path) { - $loader->set($namespace, $path); - } - - $map = require __DIR__ . '/autoload_psr4.php'; - foreach ($map as $namespace => $path) { - $loader->setPsr4($namespace, $path); - } - - $classMap = require __DIR__ . '/autoload_classmap.php'; - if ($classMap) { - $loader->addClassMap($classMap); - } - - $loader->register(true); - - return $loader; - } -} From 87082734019686a6f33e7ca834665d964157563b Mon Sep 17 00:00:00 2001 From: James Koster Date: Fri, 5 Aug 2016 14:41:02 +0100 Subject: [PATCH 288/298] review meta template tidy up. closes #11417 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adds class for ‘comment awaiting approval’ message * Replaces ‘comment’ for ‘review’ in aforementioned message * Adds class for author * Adds class for review date * Adds new-style class for verification notice * Wraps dash in a span with new-style class * Removes unnecessary colon --- templates/single-product/review-meta.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/single-product/review-meta.php b/templates/single-product/review-meta.php index 71b68ea29af..77d8f62614b 100644 --- a/templates/single-product/review-meta.php +++ b/templates/single-product/review-meta.php @@ -13,11 +13,11 @@ * @see https://docs.woocommerce.com/document/template-structure/ * @author WooThemes * @package WooCommerce/Templates - * @version 2.6.0 + * @version 2.7.0 */ if ( ! defined( 'ABSPATH' ) ) { - exit; // Exit if accessed directly + exit; // Exit if accessed directly. } global $comment; @@ -25,18 +25,18 @@ $verified = wc_review_is_from_verified_owner( $comment->comment_ID ); if ( '0' === $comment->comment_approved ) { ?> -

    +

    - (' . esc_attr__( 'verified owner', 'woocommerce' ) . ') '; + echo '(' . esc_attr__( 'verified owner', 'woocommerce' ) . ') '; } - ?>– : + ?>

    Date: Fri, 5 Aug 2016 15:07:14 +0100 Subject: [PATCH 289/298] Readme --- readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.txt b/readme.txt index f7866f54642..39d85ff8e6b 100644 --- a/readme.txt +++ b/readme.txt @@ -166,6 +166,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc * When using authorizations in PayPal standard, automatically capture funds when the order goes processing/completed. * On multisite, when a user logs into a store with an account on a site, but not the current site, rather than error, add the user to the current site as a customer. * Show variable weights/dimensions even when parent values are not set. +* Automatically sort tax rates rather than allow clunky manual sorting. [See changelog for all versions](https://raw.githubusercontent.com/woothemes/woocommerce/master/CHANGELOG.txt). From 0b04ee195c1d117e7ac63b57674653fe582e53c0 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Fri, 5 Aug 2016 15:43:12 +0100 Subject: [PATCH 290/298] Over sanitization --- includes/abstracts/abstract-wc-order.php | 35 ++++++++++++------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/includes/abstracts/abstract-wc-order.php b/includes/abstracts/abstract-wc-order.php index e04b6b21468..fee786a16ad 100644 --- a/includes/abstracts/abstract-wc-order.php +++ b/includes/abstracts/abstract-wc-order.php @@ -171,27 +171,26 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { if ( empty( $id ) || ! ( $post_object = get_post( $id ) ) ) { return; } - $order_id = absint( $post_object->ID ); // Map standard post data - $this->set_id( $order_id ); + $this->set_id( $post_object->ID ); $this->set_parent_id( $post_object->post_parent ); $this->set_date_created( $post_object->post_date ); $this->set_date_modified( $post_object->post_modified ); $this->set_status( $post_object->post_status ); $this->set_order_type( $post_object->post_type ); - $this->set_customer_id( get_post_meta( $order_id, '_customer_user', true ) ); - $this->set_order_key( get_post_meta( $order_id, '_order_key', true ) ); - $this->set_currency( get_post_meta( $order_id, '_order_currency', true ) ); - $this->set_discount_total( get_post_meta( $order_id, '_cart_discount', true ) ); - $this->set_discount_tax( get_post_meta( $order_id, '_cart_discount_tax', true ) ); - $this->set_shipping_total( get_post_meta( $order_id, '_order_shipping', true ) ); - $this->set_shipping_tax( get_post_meta( $order_id, '_order_shipping_tax', true ) ); - $this->set_cart_tax( get_post_meta( $order_id, '_order_tax', true ) ); - $this->set_total( get_post_meta( $order_id, '_order_total', true ) ); + $this->set_customer_id( get_post_meta( $this->get_id(), '_customer_user', true ) ); + $this->set_order_key( get_post_meta( $this->get_id(), '_order_key', true ) ); + $this->set_currency( get_post_meta( $this->get_id(), '_order_currency', true ) ); + $this->set_discount_total( get_post_meta( $this->get_id(), '_cart_discount', true ) ); + $this->set_discount_tax( get_post_meta( $this->get_id(), '_cart_discount_tax', true ) ); + $this->set_shipping_total( get_post_meta( $this->get_id(), '_order_shipping', true ) ); + $this->set_shipping_tax( get_post_meta( $this->get_id(), '_order_shipping_tax', true ) ); + $this->set_cart_tax( get_post_meta( $this->get_id(), '_order_tax', true ) ); + $this->set_total( get_post_meta( $this->get_id(), '_order_total', true ) ); // Orders store the state of prices including tax when created. - $this->set_prices_include_tax( metadata_exists( 'post', $order_id, '_prices_include_tax' ) ? 'yes' === get_post_meta( $order_id, '_prices_include_tax', true ) : 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); + $this->set_prices_include_tax( metadata_exists( 'post', $this->get_id(), '_prices_include_tax' ) ? 'yes' === get_post_meta( $this->get_id(), '_prices_include_tax', true ) : 'yes' === get_option( 'woocommerce_prices_include_tax' ) ); // Load meta data $this->read_meta_data(); @@ -308,7 +307,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { * @return integer */ public function get_id() { - return absint( $this->_data['id'] ); + return $this->_data['id']; } /** @@ -317,7 +316,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { * @return integer */ public function get_parent_id() { - return absint( $this->_data['parent_id'] ); + return $this->_data['parent_id']; } /** @@ -361,7 +360,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { * @return bool */ public function get_prices_include_tax() { - return (bool) $this->_data['prices_include_tax']; + return $this->_data['prices_include_tax']; } /** @@ -377,7 +376,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { * @return int */ public function get_date_created() { - return absint( $this->_data['date_created'] ); + return $this->_data['date_created']; } /** @@ -385,7 +384,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { * @return int */ public function get_date_modified() { - return absint( $this->_data['date_modified'] ); + return $this->_data['date_modified']; } /** @@ -393,7 +392,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { * @return int */ public function get_customer_id() { - return absint( $this->_data['customer_id'] ); + return $this->_data['customer_id']; } /** From 122bcd5f9abb5ddc38709263de0e5a719b252314 Mon Sep 17 00:00:00 2001 From: James Koster Date: Fri, 5 Aug 2016 15:47:54 +0100 Subject: [PATCH 291/298] Remove unnecessary `!important`s in css and explain ones that are necessary. closes #11415 --- assets/css/woocommerce-smallscreen.scss | 4 ++-- assets/css/woocommerce.scss | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/assets/css/woocommerce-smallscreen.scss b/assets/css/woocommerce-smallscreen.scss index 0309d868849..9c7cf8cd6f3 100644 --- a/assets/css/woocommerce-smallscreen.scss +++ b/assets/css/woocommerce-smallscreen.scss @@ -41,7 +41,7 @@ text-align: right !important; // Important to overwrite order status inline styling &.order-actions { - text-align: left !important; + text-align: left !important; // This must always align left on handheld } &:before { @@ -109,7 +109,7 @@ &:nth-child(2n) { float: right; - clear: none !important; + clear: none !important; // This should never clear. } } } diff --git a/assets/css/woocommerce.scss b/assets/css/woocommerce.scss index 296f391165b..53daff01c87 100644 --- a/assets/css/woocommerce.scss +++ b/assets/css/woocommerce.scss @@ -69,13 +69,13 @@ p.demo_store { text-align: center; line-height: 1; border-radius: 100%; - color: red !important; + color: red !important; // Required for default theme compatibility text-decoration: none; font-weight: 700; border: 0; &:hover { - color: #fff !important; + color: #fff !important; // Required for default theme compatibility background: red; } } @@ -1496,13 +1496,13 @@ p.demo_store { .woocommerce-message, .woocommerce-error, .woocommerce-info { - padding: 1em 2em 1em 3.5em !important; - margin: 0 0 2em !important; + padding: 1em 2em 1em 3.5em; + margin: 0 0 2em; position: relative; background-color: lighten($secondary,5%); color: $secondarytext; border-top: 3px solid $primary; - list-style: none outside !important; + list-style: none outside; @include clearfix(); width: auto; word-wrap: break-word; @@ -1521,9 +1521,9 @@ p.demo_store { } li { - list-style: none outside !important; - padding-left: 0 !important; - margin-left: 0 !important; + list-style: none outside !important; // Required for default theme compatibility + padding-left: 0 !important; // Required for default theme compatibility + margin-left: 0 !important; // Required for default theme compatibility } } From 92b28baeb4b9e605e9fb2e419a956004f4ad625c Mon Sep 17 00:00:00 2001 From: Nathaniel Date: Sat, 6 Aug 2016 11:54:44 -0700 Subject: [PATCH 292/298] Update class-wc-form-handler.php As a user, I would expect to be returned to the Edit Address page as opposed to the My Account page. --- includes/class-wc-form-handler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/class-wc-form-handler.php b/includes/class-wc-form-handler.php index 4b11ab44fbb..7f5cc236aee 100644 --- a/includes/class-wc-form-handler.php +++ b/includes/class-wc-form-handler.php @@ -146,7 +146,7 @@ class WC_Form_Handler { do_action( 'woocommerce_customer_save_address', $user_id, $load_address ); - wp_safe_redirect( wc_get_page_permalink( 'myaccount' ) ); + wp_safe_redirect( wc_get_endpoint_url( 'edit-address', '', wc_get_page_permalink( 'myaccount' ) ) ); exit; } } From 4484877481101baeea377cdea1e4427c2c40f4b2 Mon Sep 17 00:00:00 2001 From: Paul Kilmurray Date: Mon, 8 Aug 2016 10:36:04 +0700 Subject: [PATCH 293/298] initialize $tax_rates variable There are situations where the $tax_rates may not be initialized in the conditional, which in turn throws an error later in the function. --- includes/abstracts/abstract-wc-order.php | 1 + 1 file changed, 1 insertion(+) diff --git a/includes/abstracts/abstract-wc-order.php b/includes/abstracts/abstract-wc-order.php index fee786a16ad..9b1e0da6675 100644 --- a/includes/abstracts/abstract-wc-order.php +++ b/includes/abstracts/abstract-wc-order.php @@ -1197,6 +1197,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order { // Inherit tax class from items if ( '' === $shipping_tax_class ) { + $tax_rates = array(); $tax_classes = WC_Tax::get_tax_classes(); $found_tax_classes = $this->get_items_tax_classes(); From 61e2969b8309e55428241618bc5c2a29234620a3 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 8 Aug 2016 11:27:07 +0100 Subject: [PATCH 294/298] [2.6][API] Fix coupon description field fixes #11633 --- includes/api/class-wc-rest-coupons-controller.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/includes/api/class-wc-rest-coupons-controller.php b/includes/api/class-wc-rest-coupons-controller.php index c42cfb5c11c..cd8badb979e 100644 --- a/includes/api/class-wc-rest-coupons-controller.php +++ b/includes/api/class-wc-rest-coupons-controller.php @@ -246,8 +246,8 @@ class WC_REST_Coupons_Controller extends WC_REST_Posts_Controller { // Content. $data->post_content = ''; - // Excerpt. - if ( ! empty( $schema['properties']['excerpt'] ) && isset( $request['description'] ) ) { + // Coupon description (excerpt). + if ( ! empty( $schema['properties']['description'] ) && isset( $request['description'] ) ) { $data->post_excerpt = wp_filter_post_kses( $request['description'] ); } From 4a8db96c916266c964ccaf15fe5070a24782cd22 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 8 Aug 2016 12:10:29 +0100 Subject: [PATCH 295/298] [2.6][api] ID needs to be capitalized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sorting won’t work with lowercase id Fixes #11635 @claudiosmweb --- includes/abstracts/abstract-wc-rest-posts-controller.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/includes/abstracts/abstract-wc-rest-posts-controller.php b/includes/abstracts/abstract-wc-rest-posts-controller.php index 6b634c0bf49..bea36577bcf 100644 --- a/includes/abstracts/abstract-wc-rest-posts-controller.php +++ b/includes/abstracts/abstract-wc-rest-posts-controller.php @@ -521,6 +521,8 @@ abstract class WC_REST_Posts_Controller extends WC_REST_Controller { if ( 'include' === $query_args['orderby'] ) { $query_args['orderby'] = 'post__in'; + } elseif ( 'id' === $query_args['orderby'] ) { + $query_args['orderby'] = 'ID'; // ID must be capitalized } return $query_args; From 5eaee825f148ad6d271f6f2753ae21352122b004 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 8 Aug 2016 12:14:41 +0100 Subject: [PATCH 296/298] Ensure page_object is valid Closes #11641 --- includes/admin/wc-admin-functions.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/includes/admin/wc-admin-functions.php b/includes/admin/wc-admin-functions.php index 3f0fdbad604..45805de5405 100644 --- a/includes/admin/wc-admin-functions.php +++ b/includes/admin/wc-admin-functions.php @@ -62,9 +62,7 @@ function wc_create_page( $slug, $option = '', $page_title = '', $page_content = $option_value = get_option( $option ); - if ( $option_value > 0 ) { - $page_object = get_post( $option_value ); - + if ( $option_value > 0 && ( $page_object = get_post( $option_value ) ) ) { if ( 'page' === $page_object->post_type && ! in_array( $page_object->post_status, array( 'pending', 'trash', 'future', 'auto-draft' ) ) ) { // Valid page is already in place return $page_object->ID; From 87443763d8fa32e8853d508f0809206a8083b811 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 8 Aug 2016 13:43:42 +0100 Subject: [PATCH 297/298] Hook in the no products found template Closes #11257 cc @jameskoster --- includes/wc-template-functions.php | 12 +++++++++++- includes/wc-template-hooks.php | 1 + templates/archive-product.php | 9 ++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/includes/wc-template-functions.php b/includes/wc-template-functions.php index 80e9ebfede6..7c469a436a1 100644 --- a/includes/wc-template-functions.php +++ b/includes/wc-template-functions.php @@ -423,7 +423,7 @@ if ( ! function_exists( 'woocommerce_content' ) ) { woocommerce_product_loop_start( false ), 'after' => woocommerce_product_loop_end( false ) ) ) ) : ?> - + woocommerce_product_loop_start( false ), 'after' => woocommerce_product_loop_end( false ) ) ) ) : ?> - + From cfe28c9b258a2484f692d2c2c347f75ca1e5238a Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Mon, 8 Aug 2016 13:59:23 +0100 Subject: [PATCH 298/298] Made WC_Logger pluggable via wc_get_logger function. Closes #11474 --- includes/admin/class-wc-admin-status.php | 2 +- includes/class-wc-background-updater.php | 6 +++--- includes/class-wc-geo-ip.php | 6 +----- includes/class-wc-geolocation.php | 2 +- includes/class-wc-install.php | 2 +- includes/emails/class-wc-email.php | 2 +- .../gateways/paypal/class-wc-gateway-paypal.php | 2 +- includes/wc-core-functions.php | 13 +++++++++++++ readme.txt | 1 + tests/unit-tests/util/log.php | 4 ++-- 10 files changed, 25 insertions(+), 15 deletions(-) diff --git a/includes/admin/class-wc-admin-status.php b/includes/admin/class-wc-admin-status.php index 82191147e07..c1de87bc8d0 100644 --- a/includes/admin/class-wc-admin-status.php +++ b/includes/admin/class-wc-admin-status.php @@ -368,7 +368,7 @@ class WC_Admin_Status { } if ( ! empty( $_REQUEST[ 'handle' ] ) ) { - $logger = new WC_Logger(); + $logger = wc_get_logger(); $logger->remove( $_REQUEST[ 'handle' ] ); } diff --git a/includes/class-wc-background-updater.php b/includes/class-wc-background-updater.php index df0b2cda78b..02837f977a7 100644 --- a/includes/class-wc-background-updater.php +++ b/includes/class-wc-background-updater.php @@ -36,7 +36,7 @@ class WC_Background_Updater extends WP_Background_Process { */ public function dispatch() { $dispatched = parent::dispatch(); - $logger = new WC_Logger(); + $logger = wc_get_logger(); if ( is_wp_error( $dispatched ) ) { $logger->add( 'wc_db_updates', sprintf( 'Unable to dispatch WooCommerce updater: %s', $dispatched->get_error_message() ) ); @@ -97,7 +97,7 @@ class WC_Background_Updater extends WP_Background_Process { define( 'WC_UPDATING', true ); } - $logger = new WC_Logger(); + $logger = wc_get_logger(); include_once( dirname( __FILE__ ) . '/wc-update-functions.php' ); @@ -119,7 +119,7 @@ class WC_Background_Updater extends WP_Background_Process { * performed, or, call parent::complete(). */ protected function complete() { - $logger = new WC_Logger(); + $logger = wc_get_logger(); $logger->add( 'wc_db_updates', 'Data update complete' ); WC_Install::update_db_version(); parent::complete(); diff --git a/includes/class-wc-geo-ip.php b/includes/class-wc-geo-ip.php index 1dcfed3c555..fa26a6fe59e 100644 --- a/includes/class-wc-geo-ip.php +++ b/includes/class-wc-geo-ip.php @@ -1168,12 +1168,8 @@ class WC_Geo_IP { * @param string $message */ public static function log( $message ) { - if ( ! class_exists( 'WC_Logger' ) ) { - include_once( dirname( __FILE__ ) . '/class-wc-logger.php' ); - } - if ( empty( self::$log ) ) { - self::$log = new WC_Logger(); + self::$log = wc_get_logger(); } self::$log->add( 'geoip', $message ); } diff --git a/includes/class-wc-geolocation.php b/includes/class-wc-geolocation.php index f22d6f7b9be..5aa3899e70c 100644 --- a/includes/class-wc-geolocation.php +++ b/includes/class-wc-geolocation.php @@ -176,7 +176,7 @@ class WC_Geolocation { * Update geoip database. Adapted from https://wordpress.org/plugins/geoip-detect/. */ public static function update_database() { - $logger = new WC_Logger(); + $logger = wc_get_logger(); if ( ! is_callable( 'gzopen' ) ) { $logger->add( 'geolocation', 'Server does not support gzopen' ); diff --git a/includes/class-wc-install.php b/includes/class-wc-install.php index 5bea84ac6bc..04d8cb730f0 100644 --- a/includes/class-wc-install.php +++ b/includes/class-wc-install.php @@ -221,7 +221,7 @@ class WC_Install { */ private static function update() { $current_db_version = get_option( 'woocommerce_db_version' ); - $logger = new WC_Logger(); + $logger = wc_get_logger(); $update_queued = false; foreach ( self::$db_updates as $version => $update_callbacks ) { diff --git a/includes/emails/class-wc-email.php b/includes/emails/class-wc-email.php index 86bccb1c6cd..da968484645 100644 --- a/includes/emails/class-wc-email.php +++ b/includes/emails/class-wc-email.php @@ -411,7 +411,7 @@ class WC_Email extends WC_Settings_API { $emogrifier = new Emogrifier( $content, $css ); $content = $emogrifier->emogrify(); } catch ( Exception $e ) { - $logger = new WC_Logger(); + $logger = wc_get_logger(); $logger->add( 'emogrifier', $e->getMessage() ); } } diff --git a/includes/gateways/paypal/class-wc-gateway-paypal.php b/includes/gateways/paypal/class-wc-gateway-paypal.php index 414f7b67582..c6b56c19b1f 100644 --- a/includes/gateways/paypal/class-wc-gateway-paypal.php +++ b/includes/gateways/paypal/class-wc-gateway-paypal.php @@ -79,7 +79,7 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway { public static function log( $message ) { if ( self::$log_enabled ) { if ( empty( self::$log ) ) { - self::$log = new WC_Logger(); + self::$log = wc_get_logger(); } self::$log->add( 'paypal', $message ); } diff --git a/includes/wc-core-functions.php b/includes/wc-core-functions.php index 93fba552936..7823a3c9569 100644 --- a/includes/wc-core-functions.php +++ b/includes/wc-core-functions.php @@ -1415,3 +1415,16 @@ function wc_get_rounding_precision() { } return $precision; } + +/** + * Returns a new instance of a WC Logger. + * Use woocommerce_logging_class filter to change the logging class. + * @return WC_Logger + */ +function wc_get_logger() { + if ( ! class_exists( 'WC_Logger' ) ) { + include_once( dirname( __FILE__ ) . '/class-wc-logger.php' ); + } + $class = apply_filters( 'woocommerce_logging_class', 'WC_Logger' ); + return new $class; +} diff --git a/readme.txt b/readme.txt index 39d85ff8e6b..c914239596b 100644 --- a/readme.txt +++ b/readme.txt @@ -167,6 +167,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc * On multisite, when a user logs into a store with an account on a site, but not the current site, rather than error, add the user to the current site as a customer. * Show variable weights/dimensions even when parent values are not set. * Automatically sort tax rates rather than allow clunky manual sorting. +* Made WC_Logger pluggable via wc_get_logger function. [See changelog for all versions](https://raw.githubusercontent.com/woothemes/woocommerce/master/CHANGELOG.txt). diff --git a/tests/unit-tests/util/log.php b/tests/unit-tests/util/log.php index 152ff08b952..3e77ccf83b4 100644 --- a/tests/unit-tests/util/log.php +++ b/tests/unit-tests/util/log.php @@ -16,7 +16,7 @@ class WC_Tests_Log extends WC_Unit_Test_Case { * @since 2.4 */ public function test_add() { - $log = new WC_Logger(); + $log = wc_get_logger(); $log->add( 'unit-tests', 'this is a message' ); @@ -30,7 +30,7 @@ class WC_Tests_Log extends WC_Unit_Test_Case { * @since 2.4 */ public function test_clear() { - $log = new WC_Logger(); + $log = wc_get_logger(); $log->add( 'unit-tests', 'this is a message' ); $log->clear( 'unit-tests' );

    : Name ); ?>
    : ' . sprintf( __( '%s is available', 'woocommerce' ), esc_html( $update_theme_version ) ) . ''; + echo esc_html( $theme['version'] ); + if ( version_compare( $theme['version'], $theme['version_latest'], '<' ) ) { + echo ' – ' . sprintf( __( '%s is available', 'woocommerce' ), esc_html( $theme['version_latest'] ) ) . ''; } ?>
    : {'Author URI'}; ?>
    : ' : ' – ' . sprintf( __( 'If you\'re modifying WooCommerce on a parent theme you didn\'t build personally, then we recommend using a child theme. See: How to create a child theme', 'woocommerce' ), 'https://codex.wordpress.org/Child_Themes' ); + echo $theme['is_child_theme'] ? '' : ' – ' . sprintf( __( 'If you\'re modifying WooCommerce on a parent theme you didn\'t build personally, then we recommend using a child theme. See: How to create a child theme', 'woocommerce' ), 'https://codex.wordpress.org/Child_Themes' ); ?>
    : Name ); ?>
    : Version ); - - if ( version_compare( $parent_theme->Version, $update_theme_version, '<' ) ) { - echo ' – ' . sprintf( __( '%s is available', 'woocommerce' ), esc_html( $update_theme_version ) ) . ''; + echo esc_html( $theme['parent_version'] ); + if ( version_compare( $theme['parent_version'], $theme['parent_version_latest'], '<' ) ) { + echo ' – ' . sprintf( __( '%s is available', 'woocommerce' ), esc_html( $theme['parent_version_latest'] ) ) . ''; } ?>
    : {'Author URI'}; ?>
    : template, wc_get_core_supported_themes() ) ) { + if ( ! $theme['has_woocommerce_support'] ) { echo ' ' . __( 'Not Declared', 'woocommerce' ) . ''; } else { echo ''; @@ -729,62 +549,36 @@ global $wpdb;
    ::  
    ():  ', $found_plugin_files ); ?> + %s version %s is out of date. The core version is %s', 'woocommerce' ), $override['file'], $override['version'] ? $override['version'] : '-', $override['core_version'] ); + } else { + echo esc_html( $override['file'] ); + } + if ( $i !== ( count( $theme['overrides'] ) - 1 ) ) { + echo ', '; + } + echo '
    '; + } + ?> +
     :