Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Julian Jöris 2012-05-14 16:07:53 +02:00
commit 017c7e46f7
59 changed files with 15412 additions and 14668 deletions

View File

@ -158,6 +158,7 @@ function woocommerce_custom_product_columns( $column ) {
/* Custom inline data for woocommerce */
echo '
<div class="hidden" id="woocommerce_inline_' . $post->ID . '">
<div class="menu_order">' . $post->menu_order . '</div>
<div class="sku">' . $product->sku . '</div>
<div class="regular_price">' . $product->regular_price . '</div>
<div class="sale_price">' . $product->sale_price . '</div>
@ -943,4 +944,23 @@ function woocommerce_admin_product_bulk_edit_save( $post_id, $post ) {
// Clear transient
$woocommerce->clear_product_transients( $post_id );
}
}
/**
* Product sorting
*
* Based on Simple Page Ordering by 10up (http://wordpress.org/extend/plugins/simple-page-ordering/)
**/
add_filter( 'views_edit-product', 'woocommerce_default_sorting_link' );
function woocommerce_default_sorting_link( $views ) {
global $post_type, $wp_query;
$class = ( isset( $wp_query->query['orderby'] ) && $wp_query->query['orderby'] == 'menu_order title' ) ? 'current' : '';
$query_string = remove_query_arg(array( 'orderby', 'order' ));
$query_string = add_query_arg( 'orderby', urlencode('menu_order title'), $query_string );
$query_string = add_query_arg( 'order', urlencode('ASC'), $query_string );
$views['byorder'] = '<a href="'. $query_string . '" class="' . $class . '">' . __('Sort Products', 'woocommerce') . '</a>';
return $views;
}

View File

@ -268,7 +268,7 @@ function woocommerce_order_downloads_save( $post_id, $post ) {
$format = array( '%d', '%s', '%s');
$expiry = array_key_exists($i, $access_expires) ? date('Y-m-d', strtotime($access_expires[$i])) : null;
$expiry = ( array_key_exists( $i, $access_expires ) && $access_expires[ $i ] != '' ) ? date( 'Y-m-d', strtotime( $access_expires[ $i ] ) ) : null;
if ( ! is_null($expiry)) {
$data['access_expires'] = $expiry;

View File

@ -96,7 +96,7 @@ function woocommerce_product_data_box() {
echo '</div>';
echo '<div class="options_group hide_if_virtual hide_if_grouped">';
// Weight
if( get_option('woocommerce_enable_weight', true) !== 'no' ) :
woocommerce_wp_text_input( array( 'id' => '_weight', 'label' => __('Weight', 'woocommerce') . ' ('.get_option('woocommerce_weight_unit').')', 'placeholder' => '0.00' ) );
@ -118,6 +118,21 @@ function woocommerce_product_data_box() {
echo '<input type="hidden" name="_height" value="'.get_post_meta($thepostid, '_height', true).'" />';
endif;
// Shipping Class
$classes = get_the_terms( $thepostid, 'product_shipping_class' );
if ( $classes && ! is_wp_error( $classes ) ) $current_shipping_class = current($classes)->term_id; else $current_shipping_class = '';
$args = array(
'taxonomy' => 'product_shipping_class',
'hide_empty' => 0,
'show_option_none' => __('No shipping class', 'woocommerce'),
'name' => 'product_shipping_class',
'id' => 'product_shipping_class',
'selected' => $current_shipping_class,
'class' => 'select short'
);
?><p class="form-field dimensions_field"><label for="product_shipping_class"><?php _e('Shipping class', 'woocommerce'); ?></label> <?php wp_dropdown_categories( $args ); ?> <span class="description"><?php _e('Shipping classes are used by certain shipping methods to group similar products.', 'woocommerce'); ?></span></p><?php
do_action('woocommerce_product_options_dimensions');
echo '</div>';
@ -137,7 +152,7 @@ function woocommerce_product_data_box() {
echo '</div>';
echo '<div class="options_group">';
echo '<div class="options_group hide_if_external">';
// Purchase note
woocommerce_wp_textarea_input( array( 'id' => '_purchase_note', 'label' => __('Purchase Note', 'woocommerce'), 'description' => __('Enter an optional note to send the customer after purchase.', 'woocommerce') ) );
@ -197,7 +212,7 @@ function woocommerce_product_data_box() {
<?php
if (get_option('woocommerce_manage_stock')=='yes') {
// manage stock
woocommerce_wp_checkbox( array( 'id' => '_manage_stock', 'wrapper_class' => 'show_if_simple show_if_variable', 'label' => __('Manage stock?', 'woocommerce') ) );
@ -488,8 +503,8 @@ function woocommerce_product_data_box() {
woocommerce_wp_select( array( 'id' => 'parent_id', 'label' => __('Grouping', 'woocommerce'), 'value' => $post->post_parent, 'options' => $post_parents ) );
// Ordering
woocommerce_wp_text_input( array( 'id' => 'menu_order', 'label' => _x('Sort Order', 'ordering', 'woocommerce'), 'value' => $post->menu_order ) );
// Ordering - removed due to adding page-attributes panel (same field)
//woocommerce_wp_text_input( array( 'id' => 'menu_order', 'label' => _x('Sort Order', 'ordering', 'woocommerce'), 'value' => $post->menu_order ) );
do_action('woocommerce_product_options_grouping');
@ -523,7 +538,7 @@ function woocommerce_process_product_meta( $post_id, $post ) {
$product_type = sanitize_title( stripslashes( $_POST['product-type'] ) );
$is_downloadable = (isset($_POST['_downloadable'])) ? 'yes' : 'no';
$is_virtual = (isset($_POST['_virtual'])) ? 'yes' : 'no';
if( !$product_type ) $product_type = 'simple';
if( ! $product_type ) $product_type = 'simple';
// Update post meta
update_post_meta( $post_id, '_regular_price', stripslashes( $_POST['_regular_price'] ) );
@ -546,6 +561,10 @@ function woocommerce_process_product_meta( $post_id, $post ) {
update_post_meta( $post_id, '_width', '' );
update_post_meta( $post_id, '_height', '' );
endif;
// Save shipping class
$product_shipping_class = ( $_POST['product_shipping_class'] > 0 && $product_type != 'external' ) ? (int) $_POST['product_shipping_class'] : '';
wp_set_object_terms( $post_id, $product_shipping_class, 'product_shipping_class');
// Unique SKU
$sku = get_post_meta($post_id, '_sku', true);
@ -595,8 +614,9 @@ function woocommerce_process_product_meta( $post_id, $post ) {
$is_taxonomy = ($attribute_is_taxonomy[$i]) ? 1 : 0;
if ( $is_taxonomy ) {
if ( isset( $attribute_values[$i] ) ) {
// Format values
if ( is_array( $attribute_values[$i] ) ) {
$values = array_map('htmlspecialchars', array_map('stripslashes', $attribute_values[$i]));
@ -606,28 +626,32 @@ function woocommerce_process_product_meta( $post_id, $post ) {
$values = explode('|', $values);
$values = array_map('trim', $values);
}
// Remove empty items in the array
$values = array_filter( $values );
// Update post terms
if ( taxonomy_exists( $attribute_names[$i] ) )
wp_set_object_terms( $post_id, $values, $attribute_names[$i] );
if ( $values ) {
// Add attribute to array, but don't set values
$attributes[ sanitize_title( $attribute_names[$i] ) ] = array(
'name' => htmlspecialchars(stripslashes($attribute_names[$i])),
'value' => '',
'position' => $attribute_position[$i],
'is_visible' => $is_visible,
'is_variation' => $is_variation,
'is_taxonomy' => $is_taxonomy
);
}
} else {
$values = array();
}
// Update post terms
if ( taxonomy_exists( $attribute_names[$i] ) )
wp_set_object_terms( $post_id, $values, $attribute_names[$i] );
if ( $values ) {
// Add attribute to array, but don't set values
$attributes[ sanitize_title( $attribute_names[$i] ) ] = array(
'name' => htmlspecialchars(stripslashes($attribute_names[$i])),
'value' => '',
'position' => $attribute_position[$i],
'is_visible' => $is_visible,
'is_variation' => $is_variation,
'is_taxonomy' => $is_taxonomy
);
}
} else {
if (!$attribute_values[$i]) continue;
if ( ! $attribute_values[$i] ) continue;
// Format values
$values = esc_html(stripslashes($attribute_values[$i]));
// Text based, separate by pipe
@ -861,6 +885,8 @@ function woocommerce_product_type_box() {
woocommerce_wp_checkbox( array( 'id' => '_downloadable', 'wrapper_class' => 'show_if_simple', 'label' => __('Downloadable', 'woocommerce'), 'description' => __('Enable this option if access is given to a downloadable file upon purchase of a product', 'woocommerce') ) );
do_action('woocommerce_product_options_product_type');
echo '</div>';
}

View File

@ -28,6 +28,7 @@ function woocommerce_meta_boxes() {
// Products
add_meta_box( 'woocommerce-product-type', __('Product Type', 'woocommerce'), 'woocommerce_product_type_box', 'product', 'normal', 'high' );
add_meta_box( 'woocommerce-product-data', __('Product Data', 'woocommerce'), 'woocommerce_product_data_box', 'product', 'normal', 'high' );
remove_meta_box( 'product_shipping_classdiv', 'product', 'side' );
// Excerpt
if ( function_exists('wp_editor') ) {

View File

@ -238,8 +238,10 @@ function woocommerce_compile_less_styles() {
if ( is_writable( $base_file ) && is_writable( $css_file ) ) {
// Colours changed - recompile less
include_once('includes/lessc.inc.php');
include_once('includes/cssmin.inc.php');
if ( ! class_exists( 'lessc' ) )
include_once('includes/lessc.inc.php');
if ( ! class_exists( 'cssmin' ) )
include_once('includes/cssmin.inc.php');
try {
// Set default if colours not set

View File

@ -49,21 +49,21 @@ add_action( 'admin_head', 'woocommerce_admin_menu_highlight' );
function woocommerce_admin_menu_highlight() {
global $parent_file, $submenu_file, $self, $post_type, $taxonomy;
$to_highlight = array( 'shop_order', 'shop_coupon' );
$to_highlight_types = array( 'shop_order', 'shop_coupon' );
if ( isset( $post_type ) ) {
if ( in_array( $post_type, $to_highlight ) ) {
if ( in_array( $post_type, $to_highlight_types ) ) {
$submenu_file = 'edit.php?post_type=' . $post_type;
$parent_file = 'woocommerce';
}
$screen = get_current_screen();
if ( 'product' == $post_type ) {
$screen = get_current_screen();
$not_replace = array( 'product_shipping_class', 'product_cat', 'product_tag' );
if ( $screen->base == 'edit-tags' && ! in_array( $taxonomy, $not_replace ) ) {
$submenu_file = 'woocommerce_attributes';
$parent_file = 'edit.php?post_type=' . $post_type;
if ( $screen->base == 'edit-tags' && 'pa_' == substr( $taxonomy, 0, 3 ) ) {
$submenu_file = 'woocommerce_attributes';
$parent_file = 'edit.php?post_type=' . $post_type;
}
}
}
}
@ -209,7 +209,7 @@ function woocommerce_admin_help_tab() {
* Admin Scripts
*/
function woocommerce_admin_scripts() {
global $woocommerce, $pagenow, $post;
global $woocommerce, $pagenow, $post, $wp_query;
$suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
@ -308,6 +308,13 @@ function woocommerce_admin_scripts() {
wp_localize_script( 'woocommerce_term_ordering', 'woocommerce_term_ordering_params', $woocommerce_term_order_params );
endif;
// Product sorting - only when sorting by menu order on the products page
if ( $screen->id == 'edit-product' && isset( $wp_query->query['orderby'] ) && $wp_query->query['orderby'] == 'menu_order title' ) {
wp_enqueue_script( 'woocommerce_product_ordering', $woocommerce->plugin_url() . '/assets/js/admin/product-ordering.js', array('jquery-ui-sortable'), '1.0', true );
}
// Reports pages
if ($screen->id=='woocommerce_page_woocommerce_reports') :

View File

@ -692,75 +692,64 @@ function woocommerce_monthly_sales() {
$start_date = strtotime($start_date);
$end_date = strtotime($end_date);
$total_sales = 0;
$total_orders = 0;
$order_items = 0;
// Get orders to display in widget
add_filter( 'posts_where', 'orders_within_range' );
$args = array(
'numberposts' => -1,
'orderby' => 'post_date',
'order' => 'ASC',
'post_type' => 'shop_order',
'post_status' => 'publish' ,
'suppress_filters'=> 0,
'tax_query' => array(
array(
'taxonomy' => 'shop_order_status',
'terms' => array('completed', 'processing', 'on-hold'),
'field' => 'slug',
'operator' => 'IN'
)
)
);
$orders = get_posts( $args );
$order_counts = array();
$order_amounts = array();
$total_sales = $total_orders = $order_items = 0;
$order_counts = $order_amounts = array();
// Blank date ranges to begin
$count = 0;
$months = ($end_date - $start_date) / (60 * 60 * 24 * 7 * 4);
while ($count < $months) :
while ( $count < $months ) :
$time = strtotime(date('Ym', strtotime('+ '.$count.' MONTH', $start_date)).'01').'000';
$order_counts[$time] = 0;
$order_amounts[$time] = 0;
$month = date( 'Ym', strtotime(date('Ym', strtotime('+ '.$count.' MONTH', $start_date)).'01') );
$months_orders = $wpdb->get_row("
SELECT SUM(meta.meta_value) AS total_sales, COUNT(posts.ID) AS total_orders FROM {$wpdb->posts} AS posts
LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID=rel.object_ID
LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_id )
WHERE meta.meta_key = '_order_total'
AND posts.post_type = 'shop_order'
AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status'
AND term.slug IN ('completed', 'processing', 'on-hold')
AND '{$month}' = date_format(posts.post_date,'%Y%m')
");
$order_counts[$time] = (int) $months_orders->total_orders;
$order_amounts[$time] = (float) $months_orders->total_sales;
$total_orders += (int) $months_orders->total_orders;
$total_sales += (float) $months_orders->total_sales;
// Count order items
$order_items_serialized = $wpdb->get_col("
SELECT meta.meta_value AS items FROM {$wpdb->posts} AS posts
LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID=rel.object_ID
LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_id )
WHERE meta.meta_key = '_order_items'
AND posts.post_type = 'shop_order'
AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status'
AND term.slug IN ('completed', 'processing', 'on-hold')
AND '{$month}' = date_format(posts.post_date,'%Y%m')
");
if ($order_items_serialized) foreach ($order_items_serialized as $order_items_array) {
$order_items_array = maybe_unserialize($order_items_array);
if (is_array($order_items_array)) foreach ($order_items_array as $item) $order_items += (int) $item['qty'];
}
$count++;
endwhile;
if ($orders) :
foreach ($orders as $order) :
$order_total = get_post_meta($order->ID, '_order_total', true);
$time = strtotime(date('Ym', strtotime($order->post_date)).'01').'000';
$order_items_array = (array) get_post_meta($order->ID, '_order_items', true);
foreach ($order_items_array as $item) $order_items += (int) $item['qty'];
$total_sales += $order_total;
$total_orders++;
if (isset($order_counts[$time])) :
$order_counts[$time]++;
else :
$order_counts[$time] = 1;
endif;
if (isset($order_amounts[$time])) :
$order_amounts[$time] = $order_amounts[$time] + $order_total;
else :
$order_amounts[$time] = (float) $order_total;
endif;
endforeach;
endif;
remove_filter( 'posts_where', 'orders_within_range' );
?>
<form method="post" action="">
<p><label for="show_year"><?php _e('Year:', 'woocommerce'); ?></label>
@ -1061,127 +1050,133 @@ function woocommerce_top_earners() {
*/
function woocommerce_product_sales() {
global $start_date, $end_date, $woocommerce;
global $wpdb, $woocommerce;
$chosen_product_id = (isset($_POST['product_id'])) ? $_POST['product_id'] : '';
$chosen_product_ids = ( isset( $_POST['product_ids'] ) ) ? (array) $_POST['product_ids'] : '';
if ($chosen_product_id) :
$start_date = date('Ym', strtotime( '-12 MONTHS', current_time('timestamp') )).'01';
$end_date = date('Ymd', current_time('timestamp'));
if ( $chosen_product_ids && is_array( $chosen_product_ids ) ) {
$start_date = date( 'Ym', strtotime( '-12 MONTHS', current_time('timestamp') ) ) . '01';
$end_date = date( 'Ymd', current_time( 'timestamp' ) );
$max_sales = $max_totals = 0;
$product_sales = $product_totals = array();
$start_date = strtotime($start_date);
$end_date = strtotime($end_date);
// Get titles and ID's related to product
$chosen_product_titles = array();
$children_ids = array();
// Get orders to display in widget
add_filter( 'posts_where', 'orders_within_range' );
foreach ( $chosen_product_ids as $product_id ) {
$children = (array) get_posts( 'post_parent=' . $product_id . '&fields=ids&post_status=any&numberposts=-1' );
$children_ids = $children_ids + $children;
$chosen_product_titles[] = get_the_title( $product_id );
}
// Get order items
$order_items = $wpdb->get_results("
SELECT meta.meta_value AS items, posts.post_date FROM {$wpdb->posts} AS posts
LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id
LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID=rel.object_ID
LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
LEFT JOIN {$wpdb->terms} AS term USING( term_id )
$args = array(
'numberposts' => -1,
'orderby' => 'post_date',
'order' => 'ASC',
'post_type' => 'shop_order',
'post_status' => 'publish' ,
'suppress_filters'=> 0,
'tax_query' => array(
array(
'taxonomy' => 'shop_order_status',
'terms' => array('completed', 'processing', 'on-hold'),
'field' => 'slug',
'operator' => 'IN'
)
)
);
$orders = get_posts( $args );
WHERE meta.meta_key = '_order_items'
AND posts.post_type = 'shop_order'
AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status'
AND term.slug IN ('completed', 'processing', 'on-hold')
AND posts.post_date > date_sub( NOW(), INTERVAL 1 YEAR )
ORDER BY posts.post_date ASC
");
$max_sales = 0;
$max_totals = 0;
$product_sales = array();
$product_totals = array();
if ( $order_items ) {
// Get ID's related to product
$chosen_product = new WC_Product( $chosen_product_id );
$child_ids = $chosen_product->get_children();
if ($orders) :
foreach ($orders as $order) :
$date = date('Ym', strtotime( $order->post_date ));
$order_items = (array) get_post_meta( $order->ID, '_order_items', true );
foreach ($order_items as $item) :
if (isset($item['line_total'])) $row_cost = $item['line_total'];
elseif (isset($item['cost'])) $row_cost = $item['cost'] * $item['qty'];
else continue;
if ($item['id']!=$chosen_product_id && !in_array($item['id'], $child_ids)) continue;
$product_sales[$date] = isset($product_sales[$date]) ? $product_sales[$date] + $item['qty'] : $item['qty'];
$product_totals[$date] = isset($product_totals[$date]) ? $product_totals[$date] + $row_cost : $row_cost;
if ($product_sales[$date] > $max_sales) $max_sales = $product_sales[$date];
if ($product_totals[$date] > $max_totals) $max_totals = $product_totals[$date];
endforeach;
endforeach;
endif;
remove_filter( 'posts_where', 'orders_within_range' );
endif;
?>
<form method="post" action="">
<p><label for="from"><?php _e('Product:', 'woocommerce'); ?></label>
<select name="product_id" id="product_id">
<?php
echo '<option value="">'.__('Choose an product&hellip;', 'woocommerce').'</option>';
foreach ( $order_items as $order_item ) {
$args = array(
'post_type' => 'product',
'posts_per_page' => -1,
'post_status' => 'publish',
'post_parent' => 0,
'order' => 'ASC',
'orderby' => 'title'
);
$products = get_posts( $args );
$date = date( 'Ym', strtotime( $order_item->post_date ) );
$items = maybe_unserialize( $order_item->items );
if ($products) foreach ($products as $product) :
foreach ( $items as $item ) {
if ( ! in_array( $item['id'], $chosen_product_ids ) && ! in_array( $item['id'], $children_ids ) )
continue;
$sku = get_post_meta($product->ID, '_sku', true);
if ( isset( $item['line_total'] ) ) $row_cost = $item['line_total'];
else $row_cost = $item['cost'] * $item['qty'];
if ($sku) $sku = ' SKU: '.$sku;
if ( ! $row_cost ) continue;
$product_sales[ $date ] = isset( $product_sales[ $date ] ) ? $product_sales[$date] + $item['qty'] : $item['qty'];
$product_totals[ $date ] = isset( $product_totals[ $date ] ) ? $product_totals[ $date ] + $row_cost : $row_cost;
echo '<option value="'.$product->ID.'" '.selected($chosen_product_id, $product->ID, false).'>'.$product->post_title.$sku.' (#'.$product->ID.''.$sku.')</option>';
if ( $product_sales[ $date ] > $max_sales ) $max_sales = $product_sales[ $date ];
if ( $product_totals[ $date ] > $max_totals ) $max_totals = $product_totals[ $date ];
}
}
}
?>
<h4><?php printf( __( 'Sales for %s:', 'woocommerce' ), implode( ', ', $chosen_product_titles ) ); ?></h4>
<table class="bar_chart">
<thead>
<tr>
<th><?php _e('Month', 'woocommerce'); ?></th>
<th colspan="2"><?php _e('Sales', 'woocommerce'); ?></th>
</tr>
</thead>
<tbody>
<?php
if (sizeof($product_sales)>0) foreach ($product_sales as $date => $sales) :
$width = ($sales>0) ? (round($sales) / round($max_sales)) * 100 : 0;
$width2 = ($product_totals[$date]>0) ? (round($product_totals[$date]) / round($max_totals)) * 100 : 0;
$orders_link = admin_url('edit.php?s&post_status=all&post_type=shop_order&action=-1&s=' . urlencode(get_the_title($chosen_product_id)) . '&m=' . date('Ym', strtotime($date.'01')) . '&shop_order_status=completed,processing,on-hold');
echo '<tr><th><a href="'.$orders_link.'">'.date_i18n('F', strtotime($date.'01')).'</a></th>
<td width="1%"><span>'.$sales.'</span><span class="alt">'.woocommerce_price($product_totals[$date]).'</span></td>
<td class="bars">
<span style="width:'.$width.'%">&nbsp;</span>
<span class="alt" style="width:'.$width2.'%">&nbsp;</span>
</td></tr>';
endforeach; else echo '<tr><td colspan="3">'.__('No sales :(', 'woocommerce').'</td></tr>';
?>
</tbody>
</table>
<?php
} else {
?>
<form method="post" action="">
<p><select id="product_ids" name="product_ids[]" class="ajax_chosen_select_products" multiple="multiple" data-placeholder="<?php _e('Search for a product...', 'woocommerce'); ?>" style="width: 400px;"></select> <input type="submit" style="vertical-align: top;" class="button" value="<?php _e('Show', 'woocommerce'); ?>" /></p>
<script type="text/javascript">
jQuery(function(){
// Ajax Chosen Product Selectors
jQuery("select.ajax_chosen_select_products").ajaxChosen({
method: 'GET',
url: '<?php echo admin_url('admin-ajax.php'); ?>',
dataType: 'json',
afterTypeDelay: 100,
data: {
action: 'woocommerce_json_search_products',
security: '<?php echo wp_create_nonce("search-products"); ?>'
}
}, function (data) {
endforeach;
?>
</select> <input type="submit" class="button" value="<?php _e('Show', 'woocommerce'); ?>" /></p>
</form>
<?php if ($chosen_product_id) : ?>
<table class="bar_chart">
<thead>
<tr>
<th><?php _e('Month', 'woocommerce'); ?></th>
<th colspan="2"><?php _e('Sales', 'woocommerce'); ?></th>
</tr>
</thead>
<tbody>
<?php
if (sizeof($product_sales)>0) foreach ($product_sales as $date => $sales) :
$width = ($sales>0) ? (round($sales) / round($max_sales)) * 100 : 0;
$width2 = ($product_totals[$date]>0) ? (round($product_totals[$date]) / round($max_totals)) * 100 : 0;
$orders_link = admin_url('edit.php?s&post_status=all&post_type=shop_order&action=-1&s=' . urlencode(get_the_title($chosen_product_id)) . '&m=' . date('Ym', strtotime($date.'01')) . '&shop_order_status=completed,processing,on-hold');
echo '<tr><th><a href="'.$orders_link.'">'.date_i18n('F', strtotime($date.'01')).'</a></th>
<td width="1%"><span>'.$sales.'</span><span class="alt">'.woocommerce_price($product_totals[$date]).'</span></td>
<td class="bars">
<span style="width:'.$width.'%">&nbsp;</span>
<span class="alt" style="width:'.$width2.'%">&nbsp;</span>
</td></tr>';
endforeach; else echo '<tr><td colspan="3">'.__('No sales :(', 'woocommerce').'</td></tr>';
?>
</tbody>
</table>
<?php
endif;
var terms = {};
jQuery.each(data, function (i, val) {
terms[i] = val;
});
return terms;
});
});
</script>
</form>
<?php
}
}
@ -1318,8 +1313,6 @@ function woocommerce_customer_overview() {
$count++;
endwhile;
foreach ($customers as $customer) :
if (strtotime($customer->user_registered) > $start_date) :
$time = strtotime(date('Ymd', strtotime($customer->user_registered))).'000';

View File

@ -195,6 +195,7 @@ function woocommerce_admin_fields($options) {
foreach ( $options as $value ) {
if ( ! isset( $value['type'] ) ) continue;
if ( ! isset( $value['id'] ) ) $value['id'] = '';
if ( ! isset( $value['name'] ) ) $value['name'] = '';
if ( ! isset( $value['class'] ) ) $value['class'] = '';
if ( ! isset( $value['css'] ) ) $value['css'] = '';
@ -742,15 +743,13 @@ function woocommerce_admin_fields($options) {
if ( empty( $colors['secondary'] ) ) $colors['secondary'] = '#f7f6f7';
if ( empty( $colors['highlight'] ) ) $colors['highlight'] = '#85ad74';
if ( empty( $colors['content_bg'] ) ) $colors['content_bg'] = '#ffffff';
if ( empty( $colors['subtext'] ) ) $colors['subtext'] = '#777777';
// Show inputs
woocommerce_frontend_css_color_picker( __('Primary', 'woocommerce'), 'woocommerce_frontend_css_primary', $colors['primary'], __('Call to action buttons/price slider/layered nav UI', 'woocommerce') );
woocommerce_frontend_css_color_picker( __('Secondary', 'woocommerce'), 'woocommerce_frontend_css_secondary', $colors['secondary'], __('Buttons and tabs', 'woocommerce') );
woocommerce_frontend_css_color_picker( __('Highlight', 'woocommerce'), 'woocommerce_frontend_css_highlight', $colors['highlight'], __('Price labels and Sale Flashes', 'woocommerce') );
echo '<div class="color_box_clear clear"></div>';
woocommerce_frontend_css_color_picker( __('Content BG', 'woocommerce'), 'woocommerce_frontend_css_content_bg', $colors['content_bg'], __('Your themes page background - used for tab active states', 'woocommerce') );
woocommerce_frontend_css_color_picker( __('Highlight', 'woocommerce'), 'woocommerce_frontend_css_highlight', $colors['highlight'], __('Price labels and Sale Flashes', 'woocommerce') );
woocommerce_frontend_css_color_picker( __('Content', 'woocommerce'), 'woocommerce_frontend_css_content_bg', $colors['content_bg'], __('Your themes page background - used for tab active states', 'woocommerce') );
woocommerce_frontend_css_color_picker( __('Subtext', 'woocommerce'), 'woocommerce_frontend_css_subtext', $colors['subtext'], __('Used for certain text and asides - breadcrumbs, small text etc.', 'woocommerce') );
} else {

View File

@ -538,9 +538,10 @@ $woocommerce_settings['catalog'] = apply_filters('woocommerce_catalog_settings',
'std' => 'title',
'type' => 'select',
'options' => apply_filters('woocommerce_default_catalog_orderby_options', array(
'title' => __( 'Sort by title', 'woocommerce' ),
'date' => __( 'Sort by date', 'woocommerce' ),
'price' => __( 'Sort by price', 'woocommerce' ),
'menu_order' => __( 'Default sorting', 'woocommerce' ),
'title' => __( 'Sort alphabetically', 'woocommerce' ),
'date' => __( 'Sort by most recent', 'woocommerce' ),
'price' => __( 'Sort by price', 'woocommerce' ),
)),
'desc_tip' => true,
),
@ -883,6 +884,20 @@ $woocommerce_settings['shipping'] = apply_filters('woocommerce_shipping_settings
'type' => 'checkbox',
'checkboxgroup' => 'end'
),
array(
'name' => __( 'Shipping methods display format', 'woocommerce' ),
'desc' => __( 'This controls how multiple shipping methods are displayed on the frontend.', 'woocommerce' ),
'id' => 'woocommerce_shipping_method_format',
'css' => 'min-width:150px;',
'std' => '',
'type' => 'select',
'options' => array(
'' => __( 'Radio buttons', 'woocommerce' ),
'select' => __( 'Select box', 'woocommerce' ),
),
'desc_tip' => true,
),
array(
'name' => __( 'Shipping destination', 'woocommerce' ),

File diff suppressed because one or more lines are too long

View File

@ -1288,7 +1288,7 @@ img.help_tip {
border-radius:3px;
padding: 4px 6px;
float: left;
width: 90px;
width: 80px;
margin: 0 10px 0 0;
strong {
text-align: left;
@ -1558,11 +1558,11 @@ img.help_tip {
}
.expand_all {
padding-left: 14px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAARklEQVQYGWP8//8/AzGACV3Rnj17/oMwujiGQnQFMD7RChlBbsRmFcwkEO3i4sJImonIumGmg0xBFifaRKIVgj2DbAUuNgCfThpracSKqwAAAABJRU5ErkJggg==) no-repeat left;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAI0lEQVQYV2PcvXv3fwY8gJEoBa6urozYDAFpBpswGBTg8yYA3kYtiYVhDhIAAAAASUVORK5CYII=) no-repeat left;
}
.close_all {
padding-left: 14px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAKUlEQVQYlWP8//8/Az7AhFeWGAUsDAwMDHv27MFqj4uLCyNBExhp70gAohwKC5KJ+HQAAAAASUVORK5CYII=) no-repeat left;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAHUlEQVQYV2NkIAAYd+/e/R+fGsIKCFpBUAHt3QAASf0MyQbFJwoAAAAASUVORK5CYII=) no-repeat left;
}
.toolbar {
margin: 0 !important;

File diff suppressed because one or more lines are too long

View File

@ -20,6 +20,7 @@
.text_shadow( 0, 1px, 0, lighten( @secondary, 4 ) );
list-style:none outside;
.clearfix();
width: auto;
&:before {
content: "";
@ -379,7 +380,7 @@ span.onsale {
.clearfix();
ul.products, ul {
float:none;
li {
li.product {
width: 48%;
img {
width: 100%;
@ -390,7 +391,7 @@ span.onsale {
}
ul.products {
li {
li.product {
float:left;
margin: 0 3.8% 2.992em 0;
padding: 0;
@ -1062,7 +1063,7 @@ ul.cart_list, ul.product_list_widget {
}
}
td, th {
padding: 6px 12px;
padding: 6px 3px;
}
small {
display:block;
@ -1077,7 +1078,7 @@ ul.cart_list, ul.product_list_widget {
}
tr td, tr th {
border-top: 1px solid @secondary;
padding: 6px 24px;
padding: 6px 6px;
}
a.button.alt {
width: 193px;
@ -1157,6 +1158,21 @@ form.login, form.checkout_coupon {
.border_radius(5px);
}
ul#shipping_method {
list-style: none outside;
margin: 0;
padding: 0;
li {
margin: 0;
padding: .25em 0 .25em 22px;
text-indent: -22px;
list-style: none outside;
}
.amount {
font-weight: bold;
}
}
/* =Checkout
-------------------------------------------------------------- */

View File

@ -0,0 +1,56 @@
/**
* Based on Simple Page Ordering by 10up (http://wordpress.org/extend/plugins/simple-page-ordering/)
*
* Modified - products have no children (non hierarchical)
*/
jQuery('table.widefat tbody th, table.widefat tbody td').css('cursor','move');
jQuery("table.widefat tbody").sortable({
items: 'tr:not(.inline-edit-row)',
cursor: 'move',
axis: 'y',
containment: 'table.widefat',
scrollSensitivity: 40,
helper: function(e, ui) {
ui.children().each(function() { jQuery(this).width(jQuery(this).width()); });
return ui;
},
start: function(event, ui) {
if ( ! ui.item.hasClass('alternate') ) ui.item.css( 'background-color', '#ffffff' );
ui.item.children('td,th').css('border-bottom-width','0');
ui.item.css( 'outline', '1px solid #dfdfdf' );
},
stop: function(event, ui) {
ui.item.removeAttr('style');
ui.item.children('td,th').css('border-bottom-width','1px');
},
update: function(event, ui) {
jQuery('table.widefat tbody th, table.widefat tbody td').css('cursor','default');
jQuery("table.widefat tbody").sortable('disable');
var postid = ui.item.find('.check-column input').val(); // this post id
var postparent = ui.item.find('.post_parent').html(); // post parent
var prevpostid = ui.item.prev().find('.check-column input').val();
var nextpostid = ui.item.next().find('.check-column input').val();
// show spinner
ui.item.find('.check-column input').hide().after('<img alt="processing" src="images/wpspin_light.gif" class="waiting" style="margin-left: 6px;" />');
// go do the sorting stuff via ajax
jQuery.post( ajaxurl, { action: 'woocommerce_product_ordering', id: postid, previd: prevpostid, nextid: nextpostid }, function(response){
var changes = jQuery.parseJSON(response);
jQuery.each(changes, function(key,value) { jQuery('#inline_'+key+' .menu_order').html(value); });
ui.item.find('.check-column input').show().siblings('img').remove();
jQuery('table.widefat tbody th, table.widefat tbody td').css('cursor','move');
jQuery("table.widefat tbody").sortable('enable');
});
// fix cell colors
jQuery( 'table.widefat tbody tr' ).each(function(){
var i = jQuery('table.widefat tbody tr').index(this);
if ( i%2 == 0 ) jQuery(this).addClass('alternate');
else jQuery(this).removeClass('alternate');
});
}
});

View File

@ -21,6 +21,7 @@ jQuery(document).ready(function(){
var stock = $wc_inline_data.find('.stock').text();
var featured = $wc_inline_data.find('.featured').text();
var manage_stock = $wc_inline_data.find('.manage_stock').text();
var menu_order = $wc_inline_data.find('.menu_order').text();
jQuery('input[name="_sku"]', '.inline-edit-row').val(sku);
jQuery('input[name="_regular_price"]', '.inline-edit-row').val(regular_price);
@ -30,6 +31,7 @@ jQuery(document).ready(function(){
jQuery('input[name="_width"]', '.inline-edit-row').val(width);
jQuery('input[name="_height"]', '.inline-edit-row').val(height);
jQuery('input[name="_stock"]', '.inline-edit-row').val(stock);
jQuery('input[name="menu_order"]', '.inline-edit-row').val(menu_order);
jQuery('select[name="_visibility"] option, select[name="_stock_status"] option').removeAttr('selected');

View File

@ -443,7 +443,7 @@ jQuery( function($){
// Get value
var select_val = $(this).val();
$('.hide_if_grouped').show();
$('.hide_if_grouped, .hide_if_external').show();
$('.show_if_simple, .show_if_variable, .show_if_grouped, .show_if_external').hide();
if (select_val=='simple') {
@ -469,6 +469,7 @@ jQuery( function($){
$('.show_if_external').show();
$('input#_downloadable').prop('checked', false).change();
$('input#_virtual').removeAttr('checked').change();
$('.hide_if_external').hide();
}
$('ul.tabs li:visible').eq(0).find('a').click();

File diff suppressed because one or more lines are too long

View File

@ -411,20 +411,25 @@ jQuery(document).ready(function($) {
$('.product_meta').find('.sku').text('');
}
$('.single_variation_wrap').find('.quantity').show();
if (variation.min_qty) {
$('.single_variation_wrap').find('input[name=quantity]').attr('data-min', variation.min_qty).val(variation.min_qty);
} else {
$('.single_variation_wrap').find('input[name=quantity]').removeAttr('data-min');
}
if (variation.max_qty) {
if ( variation.max_qty ) {
$('.single_variation_wrap').find('input[name=quantity]').attr('data-max', variation.max_qty);
} else {
$('.single_variation_wrap').find('input[name=quantity]').removeAttr('data-max');
}
if (variation.is_virtual=='yes' && variation.is_downloadable=='yes' && woocommerce_params.option_limit_download_qty=='yes') {
$('.single_variation_wrap').find('input[name=quantity]').attr('data-max', 1);
alert(variation.is_sold_individually);
if ( variation.is_sold_individually == 'yes' ) {
$('.single_variation_wrap').find('input[name=quantity]').val('1');
$('.single_variation_wrap').find('.quantity').hide();
}
$('.single_variation_wrap').slideDown('200').trigger('variationWrapShown').trigger('show_variation'); // depreciated variationWrapShown
@ -508,7 +513,7 @@ jQuery(document).ready(function($) {
$.uniform.update();
}
}).focus(function(){
}).bind( 'focusin', function() {
check_variations( $(this).attr('name') );
@ -516,9 +521,9 @@ jQuery(document).ready(function($) {
if (woocommerce_params.is_cart==1) {
$('select#shipping_method').live('change', function() {
$('select#shipping_method, input[name=shipping_method]').live('change', function() {
var method = $('#shipping_method').val();
var method = $(this).val();
$('div.cart_totals').block({message: null, overlayCSS: {background: '#fff url(' + woocommerce_params.plugin_url + '/assets/images/ajax-loader.gif) no-repeat center', opacity: 0.6}});
@ -548,7 +553,11 @@ jQuery(document).ready(function($) {
if (xhr) xhr.abort();
var method = $('#shipping_method').val();
if ( $('select#shipping_method').size() > 0 )
var method = $('select#shipping_method').val();
else
var method = $('input[name=shipping_method]:checked').val();
var payment_method = $('#order_review input[name=payment_method]:checked').val();
var country = $('#billing_country').val();
var state = $('#billing_state').val();
@ -646,7 +655,7 @@ jQuery(document).ready(function($) {
$('#order_review input[name=payment_method]:checked').click();
/* Update totals */
$('#shipping_method').live('change', function(){
$('select#shipping_method, input[name=shipping_method]').live('change', function(){
$('body').trigger('update_checkout');
});
$('input#billing_country, input#billing_state, #billing_postcode, input#shipping_country, input#shipping_state, #shipping_postcode').live('keydown', function(){

File diff suppressed because one or more lines are too long

View File

@ -615,6 +615,10 @@ class WC_Cart {
else
$product_data = new WC_Product( $product_id );
// Force quantity to 1 if sold individually
if ( $product_data->is_sold_individually() )
$quantity = 1;
// Type/Exists check
if ( $product_data->is_type('external') || ! $product_data->exists() ) {
$woocommerce->add_error( __('This product cannot be purchased.', 'woocommerce') );
@ -637,9 +641,11 @@ class WC_Cart {
}
// Downloadable/virtual qty check
if ( get_option('woocommerce_limit_downloadable_product_qty')=='yes' && $product_data->is_downloadable() && $product_data->is_virtual() ) {
$qty = ( $cart_item_key ) ? $this->cart_contents[$cart_item_key]['quantity'] + $quantity : $quantity;
if ( $qty > 1 ) {
if ( $product_data->is_sold_individually() ) {
$in_cart_quantity = ( $cart_item_key ) ? $this->cart_contents[$cart_item_key]['quantity'] + $quantity : $quantity;
// If its greater than 1, its already in the cart
if ( $in_cart_quantity > 1 ) {
$woocommerce->add_error( sprintf('<a href="%s" class="button">%s</a> %s', get_permalink(woocommerce_get_page_id('cart')), __('View Cart &rarr;', 'woocommerce'), __('You already have this item in your cart.', 'woocommerce') ) );
return false;
}
@ -968,12 +974,13 @@ class WC_Cart {
$this->discount_total = $this->discount_total + ( $discount_amount * $values['quantity'] );
} elseif ( $coupon->type == 'percent_product' ) {
$this->discount_total = $this->discount_total + ( $price / 100 ) * $coupon->amount;
$this->discount_total = $this->discount_total + round( ( $price / 100 ) * $coupon->amount, 2 );
}
}
}
}
}
}
/**
@ -1003,7 +1010,7 @@ class WC_Cart {
$percent_discount = ( round( $this->cart_contents_total + $this->tax_total , 2 ) / 100 ) * $coupon->amount;
$this->discount_total = $this->discount_total + $percent_discount;
$this->discount_total = $this->discount_total + round( $percent_discount, 2 );
break;
@ -1124,7 +1131,7 @@ class WC_Cart {
* OR
* ADJUST TAX - Checkout calculations when a tax class is modified
*/
if ( ( $woocommerce->customer->is_customer_outside_base() && defined('WOOCOMMERCE_CHECKOUT') ) || ( $_product->get_tax_class() !== $_product->tax_class ) ) {
if ( ( $woocommerce->customer->is_customer_outside_base() && ( defined('WOOCOMMERCE_CHECKOUT') || $woocommerce->customer->has_calculated_shipping() ) ) || ( $_product->get_tax_class() !== $_product->tax_class ) ) {
// Get tax rate for the store base, ensuring we use the unmodified tax_class for the product
$base_tax_rates = $this->tax->get_shop_base_rate( $_product->tax_class );
@ -1416,7 +1423,7 @@ class WC_Cart {
if ( ! is_array( $this->cart_contents ) ) return false;
if ( get_option( 'woocommerce_shipping_cost_requires_address' ) == 'yes' ) {
if ( empty( $_SESSION['calculated_shipping'] ) ) {
if ( ! $woocommerce->customer->has_calculated_shipping() ) {
if ( ! $woocommerce->customer->get_shipping_country() || ! $woocommerce->customer->get_shipping_state() ) return false;
}
}
@ -1664,12 +1671,12 @@ class WC_Cart {
} else {
// Display ex tax if the option is set, or prices exclude tax
if ($this->display_totals_ex_tax || !$this->prices_include_tax ) {
if ( $this->display_totals_ex_tax || ! $this->prices_include_tax ) {
$return = woocommerce_price( $this->subtotal_ex_tax );
if ( $this->tax_total>0 && $this->prices_include_tax ) {
$return .= ' <small>'.$woocommerce->countries->ex_tax_or_vat().'</small>';
$return .= ' <small>' . $woocommerce->countries->ex_tax_or_vat() . '</small>';
}
return $return;
@ -1678,7 +1685,7 @@ class WC_Cart {
$return = woocommerce_price( $this->subtotal );
if ( $this->tax_total>0 && !$this->prices_include_tax ) {
$return .= ' <small>'.$woocommerce->countries->inc_tax_or_vat().'</small>';
$return .= ' <small>' . $woocommerce->countries->inc_tax_or_vat() . '</small>';
}
return $return;

View File

@ -481,12 +481,12 @@ class WC_Checkout {
update_post_meta( $order_id, '_payment_method', $this->posted['payment_method']);
update_post_meta( $order_id, '_shipping_method_title', $shipping_method);
update_post_meta( $order_id, '_payment_method_title', $payment_method);
update_post_meta( $order_id, '_order_shipping', number_format($woocommerce->cart->shipping_total, 2, '.', ''));
update_post_meta( $order_id, '_order_discount', number_format($woocommerce->cart->get_order_discount_total(), 2, '.', ''));
update_post_meta( $order_id, '_cart_discount', number_format($woocommerce->cart->get_cart_discount_total(), 2, '.', ''));
update_post_meta( $order_id, '_order_tax', number_format($woocommerce->cart->tax_total, 2, '.', ''));
update_post_meta( $order_id, '_order_shipping_tax', number_format($woocommerce->cart->shipping_tax_total, 2, '.', ''));
update_post_meta( $order_id, '_order_total', number_format($woocommerce->cart->total, 2, '.', ''));
update_post_meta( $order_id, '_order_shipping', number_format( (float) $woocommerce->cart->shipping_total, 2, '.', '' ));
update_post_meta( $order_id, '_order_discount', number_format( (float) $woocommerce->cart->get_order_discount_total(), 2, '.', '' ));
update_post_meta( $order_id, '_cart_discount', number_format( (float) $woocommerce->cart->get_cart_discount_total(), 2, '.', '' ));
update_post_meta( $order_id, '_order_tax', number_format( (float) $woocommerce->cart->tax_total, 2, '.', '' ));
update_post_meta( $order_id, '_order_shipping_tax', number_format( (float) $woocommerce->cart->shipping_tax_total, 2, '.', '' ));
update_post_meta( $order_id, '_order_total', number_format( (float) $woocommerce->cart->total, 2, '.', '' ));
update_post_meta( $order_id, '_order_key', apply_filters('woocommerce_generate_order_key', uniqid('order_') ));
update_post_meta( $order_id, '_customer_user', (int) $user_id );
update_post_meta( $order_id, '_order_items', $order_items );
@ -614,12 +614,12 @@ class WC_Checkout {
$default_shipping_country = apply_filters('default_checkout_country', ($woocommerce->customer->get_shipping_country()) ? $woocommerce->customer->get_shipping_country() : $woocommerce->countries->get_base_country());
if ( empty( $_SESSION['calculated_shipping'] ) ) {
$default_billing_state = apply_filters('default_checkout_state', '');
$default_shipping_state = apply_filters('default_checkout_state', '');
} else {
if ( $woocommerce->customer->has_calculated_shipping() ) {
$default_billing_state = apply_filters('default_checkout_state', $woocommerce->customer->get_state());
$default_shipping_state = apply_filters('default_checkout_state', $woocommerce->customer->get_shipping_state());
} else {
$default_billing_state = apply_filters('default_checkout_state', '');
$default_shipping_state = apply_filters('default_checkout_state', '');
}
if ($input == "billing_country") return $default_billing_country;

View File

@ -39,6 +39,16 @@ class WC_Customer {
endif;
}
/**
* has_calculated_shipping function.
*
* @access public
* @return bool
*/
function has_calculated_shipping() {
if ( ! empty( $_SESSION['calculated_shipping'] ) && $_SESSION['calculated_shipping'] ) return true; else return false;
}
/** set location to base location */
function set_to_base() {
$default = get_option('woocommerce_default_country');

View File

@ -260,21 +260,21 @@ class WC_Order {
/** Gets shipping and product tax */
function get_total_tax() {
return $this->order_tax + $this->order_shipping_tax;
return apply_filters( 'woocommerce_order_amount_total_tax', $this->order_tax + $this->order_shipping_tax );
}
/**
* gets the total (product) discount amount - these are applied before tax
*/
function get_cart_discount() {
return $this->cart_discount;
return apply_filters( 'woocommerce_order_amount_cart_discount', $this->cart_discount );
}
/**
* gets the total (product) discount amount - these are applied before tax
*/
function get_order_discount() {
return $this->order_discount;
return apply_filters( 'woocommerce_order_amount_order_discount', $this->order_discount );
}
/**
@ -282,23 +282,23 @@ class WC_Order {
*/
function get_total_discount() {
if ($this->order_discount || $this->cart_discount) :
return $this->order_discount + $this->cart_discount;
return apply_filters( 'woocommerce_order_amount_total_discount', $this->order_discount + $this->cart_discount );
endif;
}
/** Gets shipping */
function get_shipping() {
return $this->order_shipping;
return apply_filters( 'woocommerce_order_amount_shipping', $this->order_shipping );
}
/** Gets shipping tax amount */
function get_shipping_tax() {
return $this->order_shipping_tax;
return apply_filters( 'woocommerce_order_amount_shipping_tax', $this->order_shipping_tax );
}
/** Gets order total */
function get_order_total() {
return $this->order_total;
function get_total() {
return apply_filters( 'woocommerce_order_amount_total', $this->order_total );
}
/** Get item subtotal - this is the cost before discount */
@ -308,17 +308,17 @@ class WC_Order {
else :
$price = ( $item['line_subtotal'] / $item['qty'] );
endif;
return ($round) ? number_format( $price, 2, '.', '') : $price;
return apply_filters( 'woocommerce_order_amount_item_subtotal', ($round) ? number_format( $price, 2, '.', '') : $price );
}
/** Get line subtotal - this is the cost before discount */
function get_line_subtotal( $item, $inc_tax = false, $round = true ) {
if ($inc_tax) :
if ( $inc_tax ) :
$price = $item['line_subtotal'] + $item['line_subtotal_tax'];
else :
$price = $item['line_subtotal'];
endif;
return ($round) ? number_format( $price, 2, '.', '') : $price;
return apply_filters( 'woocommerce_order_amount_line_subtotal', ($round) ? number_format( $price, 2, '.', '') : $price );
}
/** Calculate item cost - useful for gateways */
@ -328,30 +328,35 @@ class WC_Order {
else :
$price = $item['line_total'] / $item['qty'];
endif;
return ($round) ? number_format( $price, 2, '.', '') : $price;
return apply_filters( 'woocommerce_order_amount_item_total', ($round) ? number_format( $price, 2, '.', '') : $price );
}
/** Calculate item tax - useful for gateways */
function get_item_tax( $item, $round = true ) {
$price = $item['line_tax'] / $item['qty'];
return ($round) ? number_format( $price, 2, '.', '') : $price;
return apply_filters( 'woocommerce_order_amount_item_tax', ($round) ? number_format( $price, 2, '.', '') : $price );
}
/** Calculate line total - useful for gateways */
function get_line_total( $item, $inc_tax = false ) {
if ($inc_tax) :
return number_format( $item['line_total'] + $item['line_tax'] , 2, '.', '');
return apply_filters( 'woocommerce_order_amount_line_total', number_format( $item['line_total'] + $item['line_tax'] , 2, '.', '') );
else :
return number_format( $item['line_total'] , 2, '.', '');
return apply_filters( 'woocommerce_order_amount_line_total', number_format( $item['line_total'] , 2, '.', '') );
endif;
}
/** Calculate line tax - useful for gateways */
function get_line_tax( $item ) {
return number_format( $item['line_tax'], 2, '.', '');
return apply_filters( 'woocommerce_order_amount_line_tax', number_format( $item['line_tax'], 2, '.', '') );
}
/** Depreciated functions */
function get_order_total() {
return apply_filters( 'woocommerce_order_amount_total', $this->order_total );
}
function get_item_cost( $item, $inc_tax = false ) {
_deprecated_function( __FUNCTION__, '1.4', 'get_item_total()' );
return $this->get_item_total( $item, $inc_tax );
@ -371,9 +376,9 @@ class WC_Order {
if (!isset($item['line_subtotal']) || !isset($item['line_subtotal_tax'])) return;
if ($this->display_cart_ex_tax || !$this->prices_include_tax) :
if ($this->prices_include_tax) $ex_tax_label = 1; else $ex_tax_label = 0;
$subtotal = woocommerce_price( $this->get_line_subtotal( $item ), array('ex_tax_label' => $ex_tax_label ));
if ( $this->display_cart_ex_tax || ! $this->prices_include_tax ) :
if ( $this->prices_include_tax ) $ex_tax_label = 1; else $ex_tax_label = 0;
$subtotal = woocommerce_price( $this->get_line_subtotal( $item ), array('ex_tax_label' => $ex_tax_label ) );
else :
$subtotal = woocommerce_price( $this->get_line_subtotal( $item, true ) );
endif;
@ -395,21 +400,21 @@ class WC_Order {
$subtotal = 0;
if ( !$compound ) :
if ( ! $compound ) :
foreach ($this->get_items() as $item) :
if (!isset($item['line_subtotal']) || !isset($item['line_subtotal_tax'])) return;
if ( ! isset( $item['line_subtotal'] ) || ! isset( $item['line_subtotal_tax'] ) ) return;
$subtotal += $this->get_line_subtotal( $item );
if (!$this->display_cart_ex_tax) :
if ( ! $this->display_cart_ex_tax ) :
$subtotal += $item['line_subtotal_tax'];
endif;
endforeach;
$subtotal = woocommerce_price($subtotal);
$subtotal = woocommerce_price( $subtotal );
if ($this->display_cart_ex_tax && $this->prices_include_tax) :
$subtotal .= ' <small>'.$woocommerce->countries->ex_tax_or_vat().'</small>';
@ -417,7 +422,7 @@ class WC_Order {
else :
if ($this->prices_include_tax) return;
if ( $this->prices_include_tax ) return;
foreach ($this->get_items() as $item) :
@ -429,7 +434,7 @@ class WC_Order {
$subtotal += $this->get_shipping();
// Remove non-compound taxes
foreach ($this->get_taxes() as $tax) :
foreach ( $this->get_taxes() as $tax ) :
if (isset($tax['compound']) && $tax['compound']) continue;
@ -437,6 +442,9 @@ class WC_Order {
endforeach;
// Remove discounts
$subtotal = $subtotal - $this->get_cart_discount();
$subtotal = woocommerce_price($subtotal);
endif;

View File

@ -205,11 +205,16 @@ class WC_Query {
$order = 'asc';
$meta_key = '_price';
break;
default :
case 'title' :
$orderby = 'title';
$order = 'asc';
$meta_key = '';
break;
default :
$orderby = 'menu_order title';
$order = 'asc';
$meta_key = '';
break;
endswitch;
$args = array();

View File

@ -195,10 +195,10 @@ class WC_Tax {
$this->get_tax_rates();
$tax_class = sanitize_title($tax_class);
$tax_class = sanitize_title( $tax_class );
/* Checkout uses customer location, otherwise use store base rate */
if ( defined('WOOCOMMERCE_CHECKOUT') && WOOCOMMERCE_CHECKOUT ) :
/* Checkout uses customer location for the tax rates. Also, if shipping has been calculated, use the customers address. */
if ( ( defined('WOOCOMMERCE_CHECKOUT') && WOOCOMMERCE_CHECKOUT ) || $woocommerce->customer->has_calculated_shipping() ) {
$country = $woocommerce->customer->get_shipping_country();
$state = $woocommerce->customer->get_shipping_state();
@ -208,11 +208,11 @@ class WC_Tax {
return $matched_tax_rates;
else :
} else {
return $this->get_shop_base_rate( $tax_class );
endif;
}
}
@ -249,18 +249,18 @@ class WC_Tax {
$this->get_tax_rates();
if (defined('WOOCOMMERCE_CHECKOUT') && WOOCOMMERCE_CHECKOUT) :
if ( ( defined('WOOCOMMERCE_CHECKOUT') && WOOCOMMERCE_CHECKOUT ) || $woocommerce->customer->has_calculated_shipping() ) {
$country = $woocommerce->customer->get_shipping_country();
$state = $woocommerce->customer->get_shipping_state();
$postcode = $woocommerce->customer->get_shipping_postcode();
else :
} else {
$country = $woocommerce->countries->get_base_country();
$state = $woocommerce->countries->get_base_state();
$postcode = '';
endif;
}
// If we are here then shipping is taxable - work it out
if ( !is_null($tax_class) ) :
if ( ! is_null($tax_class) ) :
$matched_tax_rates = array();

View File

@ -274,7 +274,7 @@ class WC_Paypal extends WC_Payment_Gateway {
$paypal_args['item_name_1'] = sprintf( __('Order %s' , 'woocommerce'), $order->get_order_number() ) . " - " . implode(', ', $item_names);
$paypal_args['quantity_1'] = 1;
$paypal_args['amount_1'] = number_format($order->get_order_total() - $order->get_shipping() - $order->get_shipping_tax() + $order->get_order_discount(), 2, '.', '');
$paypal_args['amount_1'] = number_format($order->get_total() - $order->get_shipping() - $order->get_shipping_tax() + $order->get_order_discount(), 2, '.', '');
// Shipping Cost
$paypal_args['shipping_1'] = number_format( $order->get_shipping() + $order->get_shipping_tax() , 2, '.', '' );
@ -444,7 +444,7 @@ class WC_Paypal extends WC_Payment_Gateway {
'body' => $received_values,
'sslverify' => false,
'timeout' => 30,
'user-agent' => 'WooCommerce/'.$woocommerce->version
'user-agent' => 'WooCommerce/' . $woocommerce->version
);
// Get url
@ -543,11 +543,16 @@ class WC_Paypal extends WC_Payment_Gateway {
endif;
// Store PP Details
update_post_meta( (int) $posted['custom'], 'Payer PayPal address', $posted['payer_email']);
update_post_meta( (int) $posted['custom'], 'Transaction ID', $posted['txn_id']);
update_post_meta( (int) $posted['custom'], 'Payer first name', $posted['first_name']);
update_post_meta( (int) $posted['custom'], 'Payer last name', $posted['last_name']);
update_post_meta( (int) $posted['custom'], 'Payment type', $posted['payment_type']);
if ( ! empty( $posted['payer_email'] ) )
update_post_meta( (int) $posted['custom'], 'Payer PayPal address', $posted['payer_email'] );
if ( ! empty( $posted['txn_id'] ) )
update_post_meta( (int) $posted['custom'], 'Transaction ID', $posted['txn_id'] );
if ( ! empty( $posted['first_name'] ) )
update_post_meta( (int) $posted['custom'], 'Payer first name', $posted['first_name'] );
if ( ! empty( $posted['last_name'] ) )
update_post_meta( (int) $posted['custom'], 'Payer last name', $posted['last_name'] );
if ( ! empty( $posted['payment_type'] ) )
update_post_meta( (int) $posted['custom'], 'Payment type', $posted['payment_type'] );
// Payment completed
$order->add_order_note( __('IPN payment completed', 'woocommerce') );
@ -566,7 +571,7 @@ class WC_Paypal extends WC_Payment_Gateway {
case "refunded" :
// Only handle full refunds, not partial
if ($order->get_order_total() == ($posted['mc_gross']*-1)) {
if ($order->get_total() == ($posted['mc_gross']*-1)) {
// Mark order as refunded
$order->update_status('refunded', sprintf(__('Payment %s via IPN.', 'woocommerce'), strtolower($posted['payment_status']) ) );

View File

@ -45,154 +45,154 @@ class WC_Google_Analytics extends WC_Integration {
'title' => __('Google Analytics ID', 'woocommerce'),
'description' => __('Log into your google analytics account to find your ID. e.g. <code>UA-XXXXX-X</code>', 'woocommerce'),
'type' => 'text',
'default' => get_option('woocommerce_ga_id')
'default' => get_option('woocommerce_ga_id') // Backwards compat
),
'ga_standard_tracking_enabled' => array(
'title' => __('Tracking code', 'woocommerce'),
'label' => __('Add tracking code to your site\'s footer. You don\'t need to enable this if using a 3rd party analytics plugin.', 'woocommerce'),
'type' => 'checkbox',
'checkboxgroup' => 'start',
'default' => get_option('woocommerce_ga_standard_tracking_enabled') ? get_option('woocommerce_ga_standard_tracking_enabled') : 'no'
'default' => get_option('woocommerce_ga_standard_tracking_enabled') ? get_option('woocommerce_ga_standard_tracking_enabled') : 'no' // Backwards compat
),
'ga_ecommerce_tracking_enabled' => array(
'label' => __('Add eCommerce tracking code to the thankyou page', 'woocommerce'),
'type' => 'checkbox',
'checkboxgroup' => 'end',
'default' => get_option('woocommerce_ga_ecommerce_tracking_enabled') ? get_option('woocommerce_ga_ecommerce_tracking_enabled') : 'no'
'default' => get_option('woocommerce_ga_ecommerce_tracking_enabled') ? get_option('woocommerce_ga_ecommerce_tracking_enabled') : 'no' // Backwards compat
)
);
/**
* Google Analytics standard tracking
**/
function google_tracking_code() {
global $woocommerce;
if ( is_admin() || current_user_can('manage_options') || get_option('woocommerce_ga_standard_tracking_enabled') == "no" ) return;
$tracking_id = get_option('woocommerce_ga_id');
if ( ! $tracking_id ) return;
$loggedin = ( is_user_logged_in() ) ? 'yes' : 'no';
if ( is_user_logged_in() ) {
$user_id = get_current_user_id();
$current_user = get_user_by('id', $user_id);
$username = $current_user->user_login;
} else {
$user_id = '';
$username = __('Guest', 'woocommerce');
}
?>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(
['_setAccount', '<?php echo $tracking_id; ?>'],
['_setCustomVar', 1, 'logged-in', '<?php echo $loggedin; ?>', 1],
['_setCustomVar', 2, 'user-id', '<?php echo $user_id; ?>', 1],
['_setCustomVar', 3, 'username', '<?php echo $username; ?>', 1],
['_trackPageview']
);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<?php
}
/**
* Google Analytics eCommerce tracking
**/
function ecommerce_tracking_code( $order_id ) {
global $woocommerce;
if ( is_admin() || current_user_can('manage_options') || get_option('woocommerce_ga_ecommerce_tracking_enabled') == "no" ) return;
$tracking_id = get_option('woocommerce_ga_id');
if ( ! $tracking_id ) return;
// Doing eCommerce tracking so unhook standard tracking from the footer
remove_action('wp_footer', 'woocommerce_google_tracking');
// Get the order and output tracking code
$order = new WC_Order($order_id);
$loggedin = (is_user_logged_in()) ? 'yes' : 'no';
if (is_user_logged_in()) {
$user_id = get_current_user_id();
$current_user = get_user_by('id', $user_id);
$username = $current_user->user_login;
} else {
$user_id = '';
$username = __('Guest', 'woocommerce');
}
?>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(
['_setAccount', '<?php echo $tracking_id; ?>'],
['_setCustomVar', 1, 'logged-in', '<?php echo $loggedin; ?>', 1],
['_setCustomVar', 2, 'user-id', '<?php echo $user_id; ?>', 1],
['_setCustomVar', 3, 'username', '<?php echo $username; ?>', 1],
['_trackPageview']
);
_gaq.push(['_addTrans',
'<?php echo $order_id; ?>', // order ID - required
'<?php bloginfo('name'); ?>', // affiliation or store name
'<?php echo $order->order_total; ?>', // total - required
'<?php echo $order->get_total_tax(); ?>', // tax
'<?php echo $order->get_shipping(); ?>', // shipping
'<?php echo $order->billing_city; ?>', // city
'<?php echo $order->billing_state; ?>', // state or province
'<?php echo $order->billing_country; ?>' // country
]);
// Order items
<?php if ($order->get_items()) foreach($order->get_items() as $item) : $_product = $order->get_product_from_item( $item ); ?>
_gaq.push(['_addItem',
'<?php echo $order_id; ?>', // order ID - required
'<?php if (!empty($_product->sku))
echo __('SKU:', 'woocommerce') . ' ' . $_product->sku;
else
echo $_product->id;
?>', // SKU/code - required
'<?php echo $item['name']; ?>', // product name
'<?php if (isset($_product->variation_data)){
echo woocommerce_get_formatted_variation( $_product->variation_data, true );
} else {
$out = array();
$categories = get_the_terms($_product->id, 'product_cat');
foreach ( $categories as $category ){
$out[] = $category->name;
}
echo join( "/", $out);
}
?>', // category or variation
'<?php echo ($item['line_total']/$item['qty']); ?>', // unit price - required
'<?php echo $item['qty']; ?>' // quantity - required
]);
<?php endforeach; ?>
_gaq.push(['_trackTrans']); // submits transaction to the Analytics servers
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<?php
}
} // End init_form_fields()
/**
* Google Analytics standard tracking
**/
function google_tracking_code() {
global $woocommerce;
if ( is_admin() || current_user_can('manage_options') || $this->ga_standard_tracking_enabled == "no" ) return;
$tracking_id = $this->ga_id;
if ( ! $tracking_id ) return;
$loggedin = ( is_user_logged_in() ) ? 'yes' : 'no';
if ( is_user_logged_in() ) {
$user_id = get_current_user_id();
$current_user = get_user_by('id', $user_id);
$username = $current_user->user_login;
} else {
$user_id = '';
$username = __('Guest', 'woocommerce');
}
?>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(
['_setAccount', '<?php echo $tracking_id; ?>'],
['_setCustomVar', 1, 'logged-in', '<?php echo $loggedin; ?>', 1],
['_setCustomVar', 2, 'user-id', '<?php echo $user_id; ?>', 1],
['_setCustomVar', 3, 'username', '<?php echo $username; ?>', 1],
['_trackPageview']
);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<?php
}
/**
* Google Analytics eCommerce tracking
**/
function ecommerce_tracking_code( $order_id ) {
global $woocommerce;
if ( is_admin() || current_user_can('manage_options') || $this->ga_ecommerce_tracking_enabled == "no" ) return;
$tracking_id = $this->ga_id;
if ( ! $tracking_id ) return;
// Doing eCommerce tracking so unhook standard tracking from the footer
remove_action('wp_footer', array( &$this, 'google_tracking_code' ) );
// Get the order and output tracking code
$order = new WC_Order($order_id);
$loggedin = (is_user_logged_in()) ? 'yes' : 'no';
if (is_user_logged_in()) {
$user_id = get_current_user_id();
$current_user = get_user_by('id', $user_id);
$username = $current_user->user_login;
} else {
$user_id = '';
$username = __('Guest', 'woocommerce');
}
?>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(
['_setAccount', '<?php echo $tracking_id; ?>'],
['_setCustomVar', 1, 'logged-in', '<?php echo $loggedin; ?>', 1],
['_setCustomVar', 2, 'user-id', '<?php echo $user_id; ?>', 1],
['_setCustomVar', 3, 'username', '<?php echo $username; ?>', 1],
['_trackPageview']
);
_gaq.push(['_addTrans',
'<?php echo $order_id; ?>', // order ID - required
'<?php bloginfo('name'); ?>', // affiliation or store name
'<?php echo $order->order_total; ?>', // total - required
'<?php echo $order->get_total_tax(); ?>', // tax
'<?php echo $order->get_shipping(); ?>', // shipping
'<?php echo $order->billing_city; ?>', // city
'<?php echo $order->billing_state; ?>', // state or province
'<?php echo $order->billing_country; ?>' // country
]);
// Order items
<?php if ($order->get_items()) foreach($order->get_items() as $item) : $_product = $order->get_product_from_item( $item ); ?>
_gaq.push(['_addItem',
'<?php echo $order_id; ?>', // order ID - required
'<?php if (!empty($_product->sku))
echo __('SKU:', 'woocommerce') . ' ' . $_product->sku;
else
echo $_product->id;
?>', // SKU/code - required
'<?php echo $item['name']; ?>', // product name
'<?php if (isset($_product->variation_data)){
echo woocommerce_get_formatted_variation( $_product->variation_data, true );
} else {
$out = array();
$categories = get_the_terms($_product->id, 'product_cat');
foreach ( $categories as $category ){
$out[] = $category->name;
}
echo join( "/", $out);
}
?>', // category or variation
'<?php echo ($item['line_total']/$item['qty']); ?>', // unit price - required
'<?php echo $item['qty']; ?>' // quantity - required
]);
<?php endforeach; ?>
_gaq.push(['_trackTrans']); // submits transaction to the Analytics servers
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
<?php
}
}
/**

View File

@ -61,7 +61,7 @@ class WC_ShareYourCart extends WC_Integration {
*/
function init_share_your_cart() {
if ( ! $this->shareYourCartWooCommerce ) {
if ( empty( $this->shareYourCartWooCommerce ) ) {
// Share your cart api class
include_once('class-shareyourcart-woocommerce.php');

View File

@ -19,8 +19,8 @@ class WC_Flat_Rate extends WC_Shipping_Method {
$this->admin_page_heading = __('Flat Rates', 'woocommerce');
$this->admin_page_description = __('Flat rates let you define a standard rate per item, or per order.', 'woocommerce');
add_action('woocommerce_update_options_shipping_flat_rate', array(&$this, 'process_admin_options'));
add_action('woocommerce_update_options_shipping_flat_rate', array(&$this, 'process_flat_rates'));
add_action('woocommerce_update_options_shipping_'.$this->id, array(&$this, 'process_admin_options'));
add_action('woocommerce_update_options_shipping_'.$this->id, array(&$this, 'process_flat_rates'));
$this->init();
}

View File

@ -33,7 +33,7 @@ class WC_Free_Shipping extends WC_Shipping_Method {
$this->requires_coupon = $this->settings['requires_coupon'];
// Actions
add_action('woocommerce_update_options_shipping_free_shipping', array(&$this, 'process_admin_options'));
add_action('woocommerce_update_options_shipping_'.$this->id, array(&$this, 'process_admin_options'));
}
/**
@ -115,50 +115,55 @@ class WC_Free_Shipping extends WC_Shipping_Method {
function is_available( $package ) {
global $woocommerce;
if ($this->enabled=="no") return false;
if ( $this->enabled == "no" ) return false;
$ship_to_countries = '';
if ($this->availability == 'specific') :
if ( $this->availability == 'specific' ) {
$ship_to_countries = $this->countries;
else :
if (get_option('woocommerce_allowed_countries')=='specific') :
} else {
if ( get_option('woocommerce_allowed_countries') == 'specific' )
$ship_to_countries = get_option('woocommerce_specific_allowed_countries');
endif;
endif;
}
if (is_array($ship_to_countries)) :
if ( ! in_array( $package['destination']['country'], $ship_to_countries ) ) return false;
endif;
if ( is_array( $ship_to_countries ) )
if ( ! in_array( $package['destination']['country'], $ship_to_countries ) )
return false;
// Enabled logic
$is_available = true;
if ($this->requires_coupon=="yes") :
if ( $this->requires_coupon == "yes" ) {
if ($woocommerce->cart->applied_coupons) : foreach ($woocommerce->cart->applied_coupons as $code) :
$coupon = new WC_Coupon( $code );
if ( $woocommerce->cart->applied_coupons ) {
foreach ($woocommerce->cart->applied_coupons as $code) {
$coupon = new WC_Coupon( $code );
if ( $coupon->enable_free_shipping() ) :
return true;
endif;
endforeach; endif;
if ( $coupon->enable_free_shipping() )
return true;
}
}
return false;
// No coupon found, as it stands, free shipping is disabled
$is_available = false;
endif;
}
if (isset($woocommerce->cart->cart_contents_total)) :
if ( isset( $woocommerce->cart->cart_contents_total ) && ! empty( $this->min_amount ) ) {
if ($woocommerce->cart->prices_include_tax) :
if ( $woocommerce->cart->prices_include_tax )
$total = $woocommerce->cart->tax_total + $woocommerce->cart->cart_contents_total;
else :
else
$total = $woocommerce->cart->cart_contents_total;
endif;
if (isset($this->min_amount) && $this->min_amount && $this->min_amount > $total) return false;
if ( $this->min_amount > $total )
$is_available = false;
else
$is_available = true;
endif;
}
return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', true );
return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $is_available );
}
function calculate_shipping() {

View File

@ -22,8 +22,8 @@ class WC_International_Delivery extends WC_Flat_Rate {
$this->admin_page_heading = __('International Delivery', 'woocommerce');
$this->admin_page_description = __('International delivery based on flat rate shipping.', 'woocommerce');
add_action('woocommerce_update_options_shipping_international_delivery', array(&$this, 'process_admin_options'));
add_action('woocommerce_update_options_shipping_international_delivery', array(&$this, 'process_flat_rates'));
add_action('woocommerce_update_options_shipping_'.$this->id, array(&$this, 'process_admin_options'));
add_action('woocommerce_update_options_shipping_'.$this->id, array(&$this, 'process_flat_rates'));
$this->init();
}

View File

@ -35,7 +35,7 @@ class WC_Local_Delivery extends WC_Shipping_Method {
$this->availability = empty( $this->settings['availability'] ) ? '' : $this->settings['availability'];
$this->countries = empty( $this->settings['countries'] ) ? '' : $this->settings['countries'];
add_action('woocommerce_update_options_shipping_local_delivery', array(&$this, 'process_admin_options'));
add_action('woocommerce_update_options_shipping_'.$this->id, array(&$this, 'process_admin_options'));
}
function calculate_shipping( $package = array() ) {

View File

@ -31,7 +31,7 @@ class WC_Local_Pickup extends WC_Shipping_Method {
$this->availability = $this->settings['availability'];
$this->countries = $this->settings['countries'];
add_action('woocommerce_update_options_shipping_local_pickup', array(&$this, 'process_admin_options'));
add_action('woocommerce_update_options_shipping_'.$this->id, array(&$this, 'process_admin_options'));
}
function calculate_shipping() {

View File

@ -99,10 +99,7 @@ class WC_Shipping {
$this->shipping_label = null;
$this->packages = array();
$_cheapest_cost = $_cheapest_method = $chosen_method = '';
if ( isset( $_SESSION['_chosen_shipping_method'] ) )
$chosen_method = $_SESSION['_chosen_shipping_method'];
// Calculate costs for passed packages
$package_keys = array_keys( $packages );
$package_keys_size = sizeof( $package_keys );
@ -112,6 +109,12 @@ class WC_Shipping {
// Get available methods (in this case methods for all packages)
$_available_methods = $this->get_available_shipping_methods();
// Get chosen method
if ( ! empty( $_SESSION['_chosen_shipping_method'] ) && isset( $_SESSION['_available_methods_count'] ) && $_SESSION['_available_methods_count'] == sizeof( $_available_methods ) )
$chosen_method = $_SESSION['_chosen_shipping_method'];
$_SESSION['_available_methods_count'] = sizeof( $_available_methods );
if ( sizeof( $_available_methods ) > 0 ) {
// If not set, set a default

BIN
languages/woocommerce-fr_FR.mo Normal file → Executable file

Binary file not shown.

18866
languages/woocommerce-fr_FR.po Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@ -2428,7 +2428,7 @@ msgstr "rintraccia-ordine"
#: admin/woocommerce-admin-install.php:159
#@ woocommerce
msgid "Track your order"
msgstr "Rintraccia il uo ordine"
msgstr "Rintraccia il tuo ordine"
#: admin/woocommerce-admin-install.php:162
#@ woocommerce

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,10 +1,10 @@
=== WooCommerce excelling eCommerce ===
Contributors: woothemes, mikejolley, jameskoster
Contributors: woothemes, mikejolley, jameskoster, CoenJacobs
Tags: ecommerce, e-commerce, commerce, woothemes, wordpress ecommerce, affiliate, store, sales, sell, shop, shopping, cart, checkout, configurable, variable, widgets, reports, download, downloadable, digital, inventory, stock, reports, shipping, tax
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=paypal@woothemes.com&item_name=Donation+for+WooCommerce
Requires at least: 3.3
Tested up to: 3.4
Stable tag: 1.5.4
Stable tag: 1.5.5
WooCommerce is a powerful, extendable eCommerce plugin that helps you sell anything. Beautifully.
@ -147,7 +147,18 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
== Changelog ==
= 1.5.5 =
= 1.5.6 =
* Feature - Default display for shipping methods is radio buttons. Before, when methods were enabled/disabled based on coupons or customer, changed methods could go unnoticed. Radio options are always visible.
* Feature - Option to display shipping methods as a select box vs. radio buttons
* Tweak - When the count of available shipping methods changes, reset to default
* Tweak - Optimisations to monthly and product reports
* Tweak - Individually sold variation handling
* Tweak - Removed mdash; from shipping options
* Fix - Google Analytics options fix
* Fix - % discount rounding
= 1.5.5 - 10/05/2012 =
* Feature - New 'default' sorting order using menu_order, with drag and drop sorting (based on http://wordpress.org/extend/plugins/simple-page-ordering/)
* Feature - Settings now include colours for things like buttons and tabs.
* Feature - New integration section which allows other class-based integrations to be added.
* Feature - ShareYourCart integration built in.
@ -155,6 +166,8 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
* Feature - Collect shipping address even when not required option
* Feature - Stock display options - show no stock amount, low stock amount, or always show stock amount
* Feature - woocommerce_form_field select type
* Feature - Add WooCommerce Products to Appearance->Menus
* Feature - Optional hide free products from Best Sellers Widget
* Tweak - Removed nonces from add to cart urls, this makes them easier to make use of; you can hardcode add to cart links or link to your add to cart link from other places without needing to use WC functions.
* Tweak - Cart.php display with more filters
* Tweak - is_product_category and is_product_tag support term argument
@ -171,6 +184,9 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
* Tweak - Hidden some uncommon settings
* Tweak - Fixed labels for settings API.
* Tweak - New WC_Order Class Formatting Filters and Function for totals (thanks thenbrent)
* Tweak - Free shipping availability check to deal with min amount and coupon rules together
* Tweak - Shipping class added to product data panel instead of separate
* Tweak - After getting a shipping quote, use the shipping address for taxes on the cart page
* Fix - Replacing use of deprecated function get_current_theme() with wp_get_theme()
* Fix - Body classes now correct for WordPress themes with non alphanumeric characters
* Fix - PayPal http_build_query &amp; -> & on some PHP 5.3 servers
@ -180,8 +196,10 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
* Fix - per product flat rate.
* Fix - Use term_id instead of term slug to get term link (allows numeric slugs for product categories)
* Fix - Replace spaces with + signs in download url after decode (allows + characters in email addresses for downloads)
* Fix - Prevent setting download expire date to 1970-01-01 in rare cases
* Localization - Slovak translation by Dušan Beleščák
* Localization - Updated localisations
* Localization - Updated French translation by mediana (Ticket 1000 in GitHub, woohoo!)
= 1.5.4 - 16/04/2012 =
* Feature - Allow attributes to be added from the edit product page

View File

@ -37,7 +37,7 @@ function woocommerce_cart( $atts ) {
$state = $_POST['calc_shipping_state'];
$postcode = $_POST['calc_shipping_postcode'];
if ($postcode && !$validation->is_postcode( $postcode, $country )) :
if ($postcode && ! $validation->is_postcode( $postcode, $country )) :
$woocommerce->add_error( __('Please enter a valid postcode/ZIP.', 'woocommerce') );
$postcode = '';
elseif ($postcode) :

View File

@ -7,11 +7,11 @@ global $woocommerce;
$available_methods = $woocommerce->shipping->get_available_shipping_methods();
?>
<div class="cart_totals <?php if ( isset( $_SESSION['calculated_shipping'] ) && $_SESSION['calculated_shipping'] ) echo 'calculated_shipping'; ?>">
<div class="cart_totals <?php if ( $woocommerce->customer->has_calculated_shipping() ) echo 'calculated_shipping'; ?>">
<?php do_action('woocommerce_before_cart_totals'); ?>
<?php if ( ! $woocommerce->shipping->enabled || $available_methods || ! $woocommerce->customer->get_shipping_country() || empty( $_SESSION['calculated_shipping'] ) ) : ?>
<?php if ( ! $woocommerce->shipping->enabled || $available_methods || ! $woocommerce->customer->get_shipping_country() || ! $woocommerce->customer->has_calculated_shipping() ) : ?>
<h2><?php _e('Cart Totals', 'woocommerce'); ?></h2>
<table cellspacing="0" cellpadding="0">
@ -45,7 +45,7 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods();
$method->full_label = esc_html( $method->label );
if ( $method->cost > 0 ) {
$method->full_label .= ' &mdash; ';
$method->full_label .= ': ';
// Append price to label using the correct tax settings
if ( $woocommerce->cart->display_totals_ex_tax || ! $woocommerce->cart->prices_include_tax ) {
@ -65,20 +65,32 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods();
// Print a single available shipping method as plain text
if ( 1 === count( $available_methods ) ) {
echo $method->full_label;
echo '<input type="hidden" name="shipping_method" id="shipping_method" value="'.esc_attr( $method->id ).'">';
echo $method->full_label . '<input type="hidden" name="shipping_method" id="shipping_method" value="' . esc_attr( $method->id ) . '" />';
// Show multiple shipping methods in a select list
// Show multiple shipping methods
} else {
if ( get_option('woocommerce_shipping_method_format') == 'select' ) {
echo '<select name="shipping_method" id="shipping_method">';
foreach ( $available_methods as $method ) {
echo '<option value="'.esc_attr( $method->id ).'" '.selected( $method->id, $_SESSION['_chosen_shipping_method'], false).'>';
echo strip_tags( $method->full_label );
echo '</option>';
echo '<select name="shipping_method" id="shipping_method">';
foreach ( $available_methods as $method )
echo '<option value="' . esc_attr( $method->id ) . '" ' . selected( $method->id, $_SESSION['_chosen_shipping_method'], false ) . '>' . strip_tags( $method->full_label ) . '</option>';
echo '</select>';
} else {
echo '<ul id="shipping_method">';
foreach ( $available_methods as $method )
echo '<li><input type="radio" name="shipping_method" id="shipping_method_' . sanitize_title( $method->id ) . '" value="' . esc_attr( $method->id ) . '" ' . checked( $method->id, $_SESSION['_chosen_shipping_method'], false) . ' /> <label for="shipping_method_' . sanitize_title( $method->id ) . '">' . $method->full_label . '</label></li>';
echo '</ul>';
}
echo '</select>';
}
// No shipping methods are available
@ -98,7 +110,7 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods();
<?php } ?>
<?php
if (get_option('woocommerce_display_cart_taxes')=='yes' && $woocommerce->cart->get_cart_tax()) :
if ( get_option('woocommerce_display_cart_taxes') == 'yes' && $woocommerce->cart->get_cart_tax() ) :
$taxes = $woocommerce->cart->get_taxes();
@ -111,7 +123,14 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods();
if ($tax==0) continue;
?>
<tr class="tax-rate tax-rate-<?php echo $key; ?>">
<th><?php if (get_option('woocommerce_prices_include_tax')=='yes') : _e('incl.', 'woocommerce'); endif; ?> <?php echo $woocommerce->cart->tax->get_rate_label( $key ); ?></th>
<th>
<?php
if ( get_option( 'woocommerce_display_totals_excluding_tax' ) == 'no' && get_option( 'woocommerce_prices_include_tax' ) == 'yes' ) {
_e( 'incl.', 'woocommerce' );
}
echo $woocommerce->cart->tax->get_rate_label( $key );
?>
</th>
<td><?php echo woocommerce_price($tax); ?></td>
</tr>
<?php
@ -132,7 +151,14 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods();
if ($tax==0) continue;
?>
<tr class="tax-rate tax-rate-<?php echo $key; ?>">
<th><?php if (get_option('woocommerce_prices_include_tax')=='yes') : _e('incl.', 'woocommerce'); endif; ?> <?php echo $woocommerce->cart->tax->get_rate_label( $key ); ?></th>
<th>
<?php
if ( get_option( 'woocommerce_display_totals_excluding_tax' ) == 'no' && get_option( 'woocommerce_prices_include_tax' ) == 'yes' ) {
_e( 'incl.', 'woocommerce' );
}
echo $woocommerce->cart->tax->get_rate_label( $key );
?>
</th>
<td><?php echo woocommerce_price($tax); ?></td>
</tr>
<?php
@ -149,7 +175,7 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods();
<?php
endif;
elseif (get_option('woocommerce_display_cart_taxes_if_zero')=='yes') :
elseif ( get_option('woocommerce_display_cart_taxes_if_zero') == 'yes' ) :
?>
<tr class="tax">
@ -185,18 +211,13 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods();
</tbody>
</table>
<p><small><?php
if ($woocommerce->customer->is_customer_outside_base()) :
$estimated_text = ' ' . sprintf(__('(taxes estimated for %s)', 'woocommerce'), $woocommerce->countries->estimated_for_prefix() . __($woocommerce->countries->countries[ $woocommerce->countries->get_base_country() ], 'woocommerce') );
else :
$estimated_text = '';
endif;
$estimated_text = ( $woocommerce->customer->is_customer_outside_base() && ! $woocommerce->customer->has_calculated_shipping() ) ? sprintf( ' ' . __('(taxes estimated for %s)', 'woocommerce'), $woocommerce->countries->estimated_for_prefix() . __($woocommerce->countries->countries[ $woocommerce->countries->get_base_country() ], 'woocommerce') ) : '';
printf(__('Note: Shipping and taxes are estimated%s and will be updated during checkout based on your billing and shipping information.', 'woocommerce'), $estimated_text );
?></small></p>
<?php elseif( $woocommerce->cart->needs_shipping() ) : ?>

View File

@ -49,7 +49,7 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods();
$method->full_label = esc_html( $method->label );
if ( $method->cost > 0 ) {
$method->full_label .= ' &mdash; ';
$method->full_label .= ': ';
// Append price to label using the correct tax settings
if ( $woocommerce->cart->display_totals_ex_tax || ! $woocommerce->cart->prices_include_tax ) {
@ -72,17 +72,30 @@ $available_methods = $woocommerce->shipping->get_available_shipping_methods();
echo $method->full_label;
echo '<input type="hidden" name="shipping_method" id="shipping_method" value="'.esc_attr( $method->id ).'">';
// Show multiple shipping methods in a select list
// Show multiple shipping methods
} else {
echo '<select name="shipping_method" id="shipping_method">';
foreach ( $available_methods as $method ) {
echo '<option value="'.esc_attr( $method->id ).'" '.selected( $method->id, $_SESSION['_chosen_shipping_method'], false).'>';
echo strip_tags( $method->full_label );
echo '</option>';
}
echo '</select>';
if ( get_option('woocommerce_shipping_method_format') == 'select' ) {
echo '<select name="shipping_method" id="shipping_method">';
foreach ( $available_methods as $method )
echo '<option value="' . esc_attr( $method->id ) . '" ' . selected( $method->id, $_SESSION['_chosen_shipping_method'], false ) . '>' . strip_tags( $method->full_label ) . '</option>';
echo '</select>';
} else {
echo '<ul id="shipping_method">';
foreach ( $available_methods as $method )
echo '<li><input type="radio" name="shipping_method" id="shipping_method_' . sanitize_title( $method->id ) . '" value="' . esc_attr( $method->id ) . '" ' . checked( $method->id, $_SESSION['_chosen_shipping_method'], false) . ' /> <label for="shipping_method_' . sanitize_title( $method->id ) . '">' . $method->full_label . '</label></li>';
echo '</ul>';
}
}
// No shipping methods are available

View File

@ -7,12 +7,14 @@
<select name="sort" class="orderby">
<?php
$catalog_orderby = apply_filters('woocommerce_catalog_orderby', array(
'title' => __('Alphabetically', 'woocommerce'),
'date' => __('Most Recent', 'woocommerce'),
'price' => __('Price', 'woocommerce')
'menu_order' => __('Default sorting', 'woocommerce'),
'title' => __('Sort alphabetically', 'woocommerce'),
'date' => __('Sort by most recent', 'woocommerce'),
'price' => __('Sort by price', 'woocommerce')
));
foreach ($catalog_orderby as $id => $name) echo '<option value="'.$id.'" '.selected( $_SESSION['orderby'], $id, false ).'>'.$name.'</option>';
foreach ( $catalog_orderby as $id => $name )
echo '<option value="' . $id . '" ' . selected( $_SESSION['orderby'], $id, false ) . '>' . $name . '</option>';
?>
</select>
</form>

View File

@ -12,7 +12,7 @@ $quantites_required = false;
foreach ( $product->get_children() as $child_id ) {
$child_product = $product->get_child( $child_id );
if ( ! $child_product->is_downloadable() && ! $child_product->is_virtual() && ! $child_product->is_type('external') )
if ( ! $child_product->is_sold_individually() && ! $child_product->is_type('external') )
$quantites_required = true;
$grouped_products[] = array(

View File

@ -40,7 +40,7 @@ global $woocommerce, $product, $post;
<?php endif;?>
</select> <?php
if ( sizeof($attributes) == $loop ) {
echo '<a class="reset_variations" href="#reset">'.__('Reset selection', 'woocommerce').'</a>';
echo '<a class="reset_variations" href="#reset">'.__('Clear selection', 'woocommerce').'</a>';
}
?></td>
</tr>

View File

@ -44,8 +44,9 @@ if ( empty( $attributes ) && ( ! $product->enable_dimensions_display() || ( ! $p
if ( $attribute['is_taxonomy'] ) :
$post_terms = wp_get_post_terms( $product->id, $attribute['name'] );
$values = array();
foreach ($post_terms as $term)
$values[] = $term->name;
foreach ( $post_terms as $term )
if ( ! empty( $term->name ) )
$values[] = $term->name;
echo implode( ', ', $values );
else :
// Convert pipes to commas

View File

@ -59,14 +59,18 @@ class WooCommerce_Widget_Best_Sellers extends WP_Widget {
$number = 15;
$query_args = array(
'posts_per_page' => $number,
'post_status' => 'publish',
'post_type' => 'product',
'meta_key' => 'total_sales',
'orderby' => 'meta_value',
'no_found_rows' => 1
'posts_per_page' => $number,
'post_status' => 'publish',
'post_type' => 'product',
'meta_key' => 'total_sales',
'orderby' => 'meta_value',
'no_found_rows' => 1,
);
if ( isset( $instance['hide_free'] ) && 1 == $instance['hide_free'] ) {
$query_args['meta_query'] = array( array( 'key' => '_price', 'value' => 0, 'compare' => '>' ) );
}
$r = new WP_Query($query_args);
if ($r->have_posts()) :
@ -85,7 +89,12 @@ class WooCommerce_Widget_Best_Sellers extends WP_Widget {
<?php
endif;
if (isset($args['widget_id']) && isset($cache[$args['widget_id']])) $cache[$args['widget_id']] = ob_get_flush();
$content = ob_get_clean();
if ( isset( $args['widget_id'] ) ) $cache[$args['widget_id']] = $content;
echo $content;
wp_cache_set('widget_best_sellers', $cache, 'widget');
}
@ -93,7 +102,12 @@ class WooCommerce_Widget_Best_Sellers extends WP_Widget {
function update( $new_instance, $old_instance ) {
$instance = $old_instance;
$instance['title'] = strip_tags($new_instance['title']);
$instance['number'] = (int) $new_instance['number'];
$instance['number'] = (int) $new_instance['number'];
$instance['hide_free'] = 0;
if ( isset( $new_instance['hide_free'] ) ) {
$instance['hide_free'] = 1;
}
$this->flush_widget_cache();
@ -111,6 +125,7 @@ class WooCommerce_Widget_Best_Sellers extends WP_Widget {
function form( $instance ) {
$title = isset($instance['title']) ? esc_attr($instance['title']) : '';
if ( !isset($instance['number']) || !$number = (int) $instance['number'] ) $number = 5;
if ( isset( $instance['hide_free'] ) && 1 == $instance['hide_free'] ) $hide_free_checked = ' checked="checked"';
?>
<p><label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:', 'woocommerce'); ?></label>
@ -119,6 +134,9 @@ class WooCommerce_Widget_Best_Sellers extends WP_Widget {
<p><label for="<?php echo $this->get_field_id('number'); ?>"><?php _e('Number of products to show:', 'woocommerce'); ?></label>
<input id="<?php echo esc_attr( $this->get_field_id('number') ); ?>" name="<?php echo esc_attr( $this->get_field_name('number') ); ?>" type="text" value="<?php echo esc_attr( $number ); ?>" size="3" /></p>
<p><input id="<?php echo esc_attr( $this->get_field_id('hide_free') ); ?>" name="<?php echo esc_attr( $this->get_field_name('hide_free') ); ?>" type="checkbox"<?php echo $hide_free_checked; ?> />
<label for="<?php echo $this->get_field_id('hide_free'); ?>"><?php _e('Hide free products', 'woocommerce'); ?></label></p>
<?php
}
}

View File

@ -83,7 +83,12 @@ class WooCommerce_Widget_Featured_Products extends WP_Widget {
<?php endif;
$cache[$args['widget_id']] = ob_get_flush();
$content = ob_get_clean();
if ( isset( $args['widget_id'] ) ) $cache[$args['widget_id']] = $content;
echo $content;
wp_cache_set('widget_featured_products', $cache, 'widget');
}

View File

@ -94,7 +94,7 @@ class WooCommerce_Widget_Login extends WP_Widget {
<p><label for="user_pass"><?php _e('Password', 'woocommerce'); ?></label> <input name="pwd" class="input-text" id="user_pass" type="password" /></p>
<p><input type="submit" class="submitbutton" name="wp-submit" id="wp-submit" value="<?php _e('Login &raquo;', 'woocommerce'); ?>" /> <a href="<?php echo wp_lostpassword_url(); ?>"><?php echo __('Lost password?', 'woocommerce'); ?></a></p>
<p><input type="submit" class="submitbutton" name="wp-submit" id="wp-submit" value="<?php _e('Login &rarr;', 'woocommerce'); ?>" /> <a href="<?php echo wp_lostpassword_url(); ?>"><?php echo __('Lost password?', 'woocommerce'); ?></a></p>
<div>
<input type="hidden" name="redirect_to" class="redirect_to" value="<?php echo $redirect_to; ?>" />

View File

@ -118,7 +118,12 @@ class WooCommerce_Widget_On_Sale extends WP_Widget {
<?php
endif;
if (isset($args['widget_id']) && isset($cache[$args['widget_id']])) $cache[$args['widget_id']] = ob_get_flush();
$content = ob_get_clean();
if ( isset( $args['widget_id'] ) ) $cache[$args['widget_id']] = $content;
echo $content;
wp_cache_set('widget_onsale', $cache, 'widget');
}

View File

@ -95,7 +95,12 @@ class WooCommerce_Widget_Recent_Products extends WP_Widget {
endif;
if (isset($args['widget_id']) && isset($cache[$args['widget_id']])) $cache[$args['widget_id']] = ob_get_flush();
$content = ob_get_clean();
if ( isset( $args['widget_id'] ) ) $cache[$args['widget_id']] = $content;
echo $content;
wp_cache_set('widget_recent_products', $cache, 'widget');
}

View File

@ -90,7 +90,12 @@ class WooCommerce_Widget_Recent_Reviews extends WP_Widget {
echo $after_widget;
endif;
if (isset($args['widget_id']) && isset($cache[$args['widget_id']])) $cache[$args['widget_id']] = ob_get_flush();
$content = ob_get_clean();
if ( isset( $args['widget_id'] ) ) $cache[$args['widget_id']] = $content;
echo $content;
wp_cache_set('widget_recent_reviews', $cache, 'widget');
}

View File

@ -84,7 +84,12 @@ class WooCommerce_Widget_Recently_Viewed extends WP_Widget {
endif;
if (isset($args['widget_id']) && isset($cache[$args['widget_id']])) $cache[$args['widget_id']] = ob_get_flush();
$content = ob_get_clean();
if ( isset( $args['widget_id'] ) ) $cache[$args['widget_id']] = $content;
echo $content;
wp_cache_set('recently_viewed_products', $cache, 'widget');
}

View File

@ -86,8 +86,12 @@ class WooCommerce_Widget_Top_Rated_Products extends WP_Widget {
wp_reset_query();
remove_filter( 'posts_clauses', array(&$this, 'order_by_rating_post_clauses') );
$cache[$args['widget_id']] = ob_get_flush();
$content = ob_get_clean();
if ( isset( $args['widget_id'] ) ) $cache[$args['widget_id']] = $content;
echo $content;
wp_cache_set('widget_top_rated_products', $cache, 'widget');
}

View File

@ -535,15 +535,6 @@ function woocommerce_grant_access_to_download() {
$order = new WC_Order( $order_id );
$user_email = $order->billing_email;
if ($order->user_id>0) :
$user_info = get_userdata($order->user_id);
if ($user_info->user_email) :
$user_email = $user_info->user_email;
endif;
else :
$order->user_id = 0;
endif;
$limit = trim(get_post_meta($product_id, '_download_limit', true));
$expiry = trim(get_post_meta($product_id, '_download_expiry', true));
@ -559,7 +550,7 @@ function woocommerce_grant_access_to_download() {
$data = array(
'product_id' => $product_id,
'user_id' => $order->user_id,
'user_id' => (int) $order->user_id,
'user_email' => $user_email,
'order_id' => $order->id,
'order_key' => $order->order_key,
@ -1003,6 +994,8 @@ function woocommerce_upsell_crosssell_search_products() {
/**
* Ajax request handling for categories ordering
*/
add_action('wp_ajax_woocommerce-term-ordering', 'woocommerce_term_ordering');
function woocommerce_term_ordering() {
global $wpdb;
@ -1022,4 +1015,63 @@ function woocommerce_term_ordering() {
die;
}
}
add_action('wp_ajax_woocommerce-term-ordering', 'woocommerce_term_ordering');
/**
* Ajax request handling for product ordering
*
* Based on Simple Page Ordering by 10up (http://wordpress.org/extend/plugins/simple-page-ordering/)
*/
add_action( 'wp_ajax_woocommerce_product_ordering', 'woocommerce_product_ordering' );
function woocommerce_product_ordering() {
// check permissions again and make sure we have what we need
if ( ! current_user_can('edit_others_pages') || empty( $_POST['id'] ) || ( ! isset( $_POST['previd'] ) && ! isset( $_POST['nextid'] ) ) )
die(-1);
// real post?
if ( ! $post = get_post( $_POST['id'] ) )
die(-1);
$previd = isset( $_POST['previd'] ) ? $_POST['previd'] : false;
$nextid = isset( $_POST['nextid'] ) ? $_POST['nextid'] : false;
$new_pos = array(); // store new positions for ajax
$siblings = get_posts(array(
'numberposts' => -1,
'post_type' => 'product',
'post_status' => 'publish,pending,draft,future,private',
'orderby' => 'menu_order title',
'order' => 'ASC',
'exclude' => $post->ID
)); // fetch all the siblings (relative ordering)
$menu_order = 0;
foreach( $siblings as $sibling ) :
// if this is the post that comes after our repositioned post, set our repositioned post position and increment menu order
if ( $nextid == $sibling->ID ) {
wp_update_post(array( 'ID' => $post->ID, 'menu_order' => $menu_order ));
$new_pos[$post->ID] = $menu_order;
$menu_order++;
}
// if repositioned post has been set, and new items are already in the right order, we can stop
if ( isset( $new_pos[$post->ID] ) && $sibling->menu_order >= $menu_order )
break;
// set the menu order of the current sibling and increment the menu order
wp_update_post(array( 'ID' => $sibling->ID, 'menu_order' => $menu_order ));
$new_pos[$sibling->ID] = $menu_order;
$menu_order++;
if ( ! $nextid && $previd == $sibling->ID ) {
wp_update_post(array( 'ID' => $post->ID, 'menu_order' => $menu_order ));
$new_pos[$post->ID] = $menu_order;
$menu_order++;
}
endforeach;
die( json_encode($new_pos) );
}

View File

@ -212,7 +212,7 @@ function woocommerce_update_cart_action() {
// Update Cart
elseif (isset($_POST['update_cart']) && $_POST['update_cart'] && $woocommerce->verify_nonce('cart')) :
$cart_totals = $_POST['cart'];
$cart_totals = isset( $_POST['cart'] ) ? $_POST['cart'] : '';
if (sizeof($woocommerce->cart->get_cart())>0) :
foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) :

View File

@ -353,7 +353,8 @@ if ( ! function_exists( 'woocommerce_variable_add_to_cart' ) ) {
'min_qty' => 1,
'max_qty' => $variation->stock,
'is_downloadable' => $variation->is_downloadable() ,
'is_virtual' => $variation->is_virtual()
'is_virtual' => $variation->is_virtual(),
'is_sold_individually' => $variation->is_sold_individually() ? 'yes' : 'no',
) , $product, $variation );
}
}

View File

@ -7,7 +7,7 @@
* Author: WooThemes
* Author URI: http://woothemes.com
* Requires at least: 3.3
* Tested up to: 3.3
* Tested up to: 3.4
*
* Text Domain: woocommerce
* Domain Path: /languages/
@ -87,7 +87,7 @@ class Woocommerce {
// Installation
if ( is_admin() && !defined('DOING_AJAX') ) $this->install();
// Actions
add_action( 'init', array( &$this, 'init' ), 0 );
add_action( 'init', array( &$this, 'include_template_functions' ), 25 );
@ -282,10 +282,11 @@ class Woocommerce {
**/
function load_plugin_textdomain() {
// Note: the first-loaded translation file overrides any following ones if the same translation is present
$locale = apply_filters( 'plugin_locale', get_locale(), 'woocommerce' );
$variable_lang = ( get_option( 'woocommerce_informal_localisation_type' ) == 'yes' ) ? 'informal' : 'formal';
load_textdomain( 'woocommerce', WP_LANG_DIR.'/woocommerce/woocommerce-'.get_locale().'.mo' );
load_textdomain( 'woocommerce', WP_LANG_DIR.'/woocommerce/woocommerce-'.$locale.'.mo' );
load_plugin_textdomain( 'woocommerce', false, dirname( plugin_basename( __FILE__ ) ).'/languages/'.$variable_lang );
load_plugin_textdomain( 'woocommerce', false, dirname( plugin_basename( __FILE__ ) ).'/languages');
load_plugin_textdomain( 'woocommerce', false, dirname( plugin_basename( __FILE__ ) ).'/languages' );
}
/**
@ -557,6 +558,7 @@ class Woocommerce {
array('product'),
array(
'hierarchical' => false,
'update_count_callback' => '_update_post_term_count',
'show_ui' => false,
'show_in_nav_menus' => false,
'query_var' => $admin_only_query_var,
@ -694,6 +696,7 @@ class Woocommerce {
array('product'),
array(
'hierarchical' => $hierarchical,
'update_count_callback' => '_update_post_term_count',
'labels' => array(
'name' => $label,
'singular_name' => $label,
@ -757,9 +760,9 @@ class Woocommerce {
'hierarchical' => false, // Hierarcal causes memory issues - WP loads all records!
'rewrite' => array( 'slug' => $product_base, 'with_front' => false, 'feeds' => $base_slug ),
'query_var' => true,
'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail', 'comments', 'custom-fields' ),
'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail', 'comments', 'custom-fields', 'page-attributes' ),
'has_archive' => $base_slug,
'show_in_nav_menus' => false
'show_in_nav_menus' => true
)
);
@ -982,7 +985,6 @@ class Woocommerce {
'update_order_review_nonce' => wp_create_nonce("update-order-review"),
'update_shipping_method_nonce' => wp_create_nonce("update-shipping-method"),
'option_guest_checkout' => get_option('woocommerce_enable_guest_checkout'),
'option_limit_download_qty' => get_option('woocommerce_limit_downloadable_product_qty'),
'checkout_url' => add_query_arg( 'action', 'woocommerce-checkout', $this->ajax_url() ),
'option_ajax_add_to_cart' => get_option('woocommerce_enable_ajax_add_to_cart'),
'is_checkout' => ( is_page(woocommerce_get_page_id('checkout')) ) ? 1 : 0,