diff --git a/admin/admin-dashboard.php b/admin/admin-dashboard.php index aefb072b4c5..530cf59fafe 100644 --- a/admin/admin-dashboard.php +++ b/admin/admin-dashboard.php @@ -1,6 +1,6 @@ -
-

-

-
- -
- -
- -
-

-
+add_action('right_now_content_table_end', 'woocommerce_content_right_now'); +add_action('right_now_table_end', 'woocommerce_right_now'); -
-

- - - - - - - - - - - - - - - - - - - -
publish ); - echo $num; - ?>
-
- -
- -

WooCommerce (). ' . __('Your server supports fsockopen.', 'woothemes'). ''; else echo '' . __('Your server does not support fsockopen.', 'woothemes'). ''; ?>

- -
-
-
- -
- -
-

-
- 8, - 'orderby' => 'post_date', - 'order' => 'DESC', - 'post_type' => 'shop_order', - 'post_status' => 'publish' - ); - $orders = get_posts( $args ); - if ($orders) : - echo '
    '; - foreach ($orders as $order) : - - $this_order = &new woocommerce_order( $order->ID ); - - echo ' -
  • - '.ucwords($this_order->status).' '.date_i18n('l jS \of F Y h:i:s A', strtotime($this_order->order_date)).'
    - '.sizeof($this_order->items).' '._n('item', 'items', sizeof($this_order->items), 'woothemes').' '.__('Total: ', 'woothemes').woocommerce_price($this_order->order_total).' -
  • '; - - endforeach; - echo '
'; - endif; - ?> -
-
- - -
-

-
- - 'product', - 'post_status' => 'publish', - 'ignore_sticky_posts' => 1, - 'posts_per_page' => -1 - ); - $my_query = new WP_Query($args); - if ($my_query->have_posts()) : while ($my_query->have_posts()) : $my_query->the_post(); - - $_product = &new woocommerce_product( $my_query->post->ID ); - if (!$_product->managing_stock()) continue; - - $thisitem = ' - '.$_product->stock.' - '.$my_query->post->post_title.' - '; - - if ($_product->stock<=$nostockamount) : - $outofstock[] = $thisitem; - continue; - endif; - - if ($_product->stock<=$lowstockamount) $lowinstock[] = $thisitem; - - endwhile; endif; - wp_reset_query(); - - if (sizeof($lowinstock)==0) : - $lowinstock[] = ''.__('No products are low in stock.', 'woothemes').''; - endif; - if (sizeof($outofstock)==0) : - $outofstock[] = ''.__('No products are out of stock.', 'woothemes').''; - endif; - ?> - -
-

- - - - -
-
-
-

- - - - -
-
-
- -
-
- - - -
-
- - -
-

- - -

-
-
- -
-
- -
-

-
- get_results("SELECT *, SUBSTRING(comment_content,1,100) AS comment_excerpt - FROM $wpdb->comments - LEFT JOIN $wpdb->posts ON ($wpdb->comments.comment_post_ID = $wpdb->posts.ID) - WHERE comment_approved = '1' - AND comment_type = '' - AND post_password = '' - AND post_type = 'product' - ORDER BY comment_date_gmt DESC - LIMIT 5" ); - - if ($comments) : - echo '
    '; - foreach ($comments as $comment) : - - echo '
  • '; - - echo get_avatar($comment->comment_author, '32'); - - $rating = get_comment_meta( $comment->comment_ID, 'rating', true ); - - echo '
    - '.$rating.' '.__('out of 5', 'woothemes').'
    '; - - echo '

    '.$comment->post_title.' reviewed by ' .strip_tags($comment->comment_author) .'

    '; - echo '
    '.strip_tags($comment->comment_excerpt).' [...]
  • '; - - endforeach; - echo '
'; - else : - echo '

'.__('There are no product reviews yet.', 'woothemes').'

'; - endif; - ?> -
-
- -
-

- -
- -
-
-
-
+ endwhile; endif; + wp_reset_query(); + + if (sizeof($lowinstock)==0) : + $lowinstock[] = ''.__('No products are low in stock.', 'woothemes').''; + endif; + if (sizeof($outofstock)==0) : + $outofstock[] = ''.__('No products are out of stock.', 'woothemes').''; + endif; + + ?> + +

+ + + + + + + + + + + + + + + + + +
publish ); + echo $num; + ?>
+

+ + +
+

+ + + + + + + + + + + + + + + + + +
pending_count; ?>
on_hold_count; ?>
processing_count; ?>
completed_count; ?>
+

+ + + '.__('Next Month →', 'woo themes').''; + endif; + + $sales_heading .= ''.__('Monthly Sales', 'woothemes').''; + + wp_add_dashboard_widget('woocommmerce_dashboard_sales', $sales_heading, 'woocommmerce_dashboard_sales'); + wp_add_dashboard_widget('woocommmerce_dashboard_recent_orders', __('WooCommerce recent orders', 'woothemes'), 'woocommmerce_dashboard_recent_orders'); + wp_add_dashboard_widget('woocommmerce_dashboard_recent_reviews', __('WooCommerce recent reviews', 'woothemes'), 'woocommmerce_dashboard_recent_reviews'); +} + +/** + * Recent orders widget + */ +function woocommmerce_dashboard_recent_orders() { + + $args = array( + 'numberposts' => 8, + 'orderby' => 'post_date', + 'order' => 'DESC', + 'post_type' => 'shop_order', + 'post_status' => 'publish' + ); + $orders = get_posts( $args ); + if ($orders) : + echo ''; + endif; +} + +/** + * Recent reviews widget + */ +function woocommmerce_dashboard_recent_reviews() { + global $wpdb; + $comments = $wpdb->get_results("SELECT *, SUBSTRING(comment_content,1,100) AS comment_excerpt + FROM $wpdb->comments + LEFT JOIN $wpdb->posts ON ($wpdb->comments.comment_post_ID = $wpdb->posts.ID) + WHERE comment_approved = '1' + AND comment_type = '' + AND post_password = '' + AND post_type = 'product' + ORDER BY comment_date_gmt DESC + LIMIT 5" ); + + if ($comments) : + echo ''; + else : + echo '

'.__('There are no product reviews yet.', 'woothemes').'

'; + endif; +} + +/** + * Orders this month filter function + */ +function orders_this_month( $where = '' ) { + global $current_month_offset; + + $month = $current_month_offset; + $year = (int) date('Y'); + + $first_day = strtotime("{$year}-{$month}-01"); + $last_day = strtotime('-1 second', strtotime('+1 month', $first_day)); + + $after = date('Y-m-d', $first_day); + $before = date('Y-m-d', $last_day); + + $where .= " AND post_date > '$after'"; + $where .= " AND post_date < '$before'"; + + return $where; +} + +/** + * Sales widget + */ +function woocommmerce_dashboard_sales() { + + ?>
id!=='dashboard') return; + + global $current_month_offset; + + // Get orders to display in widget + add_filter( 'posts_where', 'orders_this_month' ); + + $args = array( + 'numberposts' => -1, + 'orderby' => 'post_date', + 'order' => 'DESC', + 'post_type' => 'shop_order', + 'post_status' => 'publish' , + 'suppress_filters' => false + ); + $orders = get_posts( $args ); + + $order_counts = array(); + $order_amounts = array(); + + // Blank date ranges to begin + $month = $current_month_offset; + $year = (int) date('Y'); + + $first_day = strtotime("{$year}-{$month}-01"); + $last_day = strtotime('-1 second', strtotime('+1 month', $first_day)); + + if ((date('m') - $current_month_offset)==0) : + $up_to = date('d', strtotime('NOW')); + else : + $up_to = date('d', $last_day); + endif; + $count = 0; + + while ($count < $up_to) : + + $time = strtotime(date('Ymd', strtotime('+ '.$count.' DAY', $first_day))).'000'; + + $order_counts[$time] = 0; + $order_amounts[$time] = 0; + + $count++; + endwhile; + + if ($orders) : + foreach ($orders as $order) : + + $order_data = &new woocommerce_order($order->ID); + + if ($order_data->status=='cancelled' || $order_data->status=='refunded') continue; + + $time = strtotime(date('Ymd', strtotime($order->post_date))).'000'; + + 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_data->order_total; + else : + $order_amounts[$time] = (float) $order_data->order_total; + endif; + + endforeach; + endif; + + remove_filter( 'posts_where', 'orders_this_month' ); + + /* Script variables */ + $params = array( + 'currency_symbol' => get_woocommerce_currency_symbol() + ); + + $order_counts_array = array(); + foreach ($order_counts as $key => $count) : + $order_counts_array[] = array($key, $count); + endforeach; + + $order_amounts_array = array(); + foreach ($order_amounts as $key => $amount) : + $order_amounts_array[] = array($key, $amount); + endforeach; + + $order_data = array( 'order_counts' => $order_counts_array, 'order_amounts' => $order_amounts_array ); + + $params['order_data'] = json_encode($order_data); + + // Queue + wp_register_script( 'woocommerce_dashboard_sales', woocommerce::plugin_url() . '/assets/js/woocommerce_dashboard_sales.js', 'jquery', '1.0' ); + wp_localize_script( 'woocommerce_dashboard_sales', 'params', $params ); + wp_print_scripts('woocommerce_dashboard_sales'); + +} +add_action('admin_footer', 'woocommmerce_dashboard_sales_js'); + + + diff --git a/admin/admin-init.php b/admin/admin-init.php index 2db5611554a..9f06caab467 100644 --- a/admin/admin-init.php +++ b/admin/admin-init.php @@ -25,17 +25,14 @@ add_action('admin_init', 'woocommerce_admin_init'); * Admin Menus * * Sets up the admin menus in wordpress. - * - * @since 1.0 */ function woocommerce_admin_menu() { global $menu; $menu[] = array( '', 'read', 'separator-woocommerce', '', 'wp-menu-separator' ); - add_menu_page(__('WooCommerce'), __('WooCommerce'), 'manage_woocommerce', 'woocommerce' , 'woocommerce_dashboard', woocommerce::plugin_url() . '/assets/images/icons/menu_icons.png', 56); - add_submenu_page('woocommerce', __('Dashboard', 'woothemes'), __('Dashboard', 'woothemes'), 'manage_woocommerce', 'woocommerce', 'woocommerce_dashboard'); - add_submenu_page('woocommerce', __('General Settings', 'woothemes'), __('Settings', 'woothemes') , 'manage_woocommerce', 'woocommerce-settings', 'woocommerce_settings'); + add_menu_page(__('WooCommerce'), __('WooCommerce'), 'manage_woocommerce', 'woocommerce' , 'woocommerce_settings', woocommerce::plugin_url() . '/assets/images/icons/menu_icons.png', 56); + add_submenu_page('woocommerce', __('General Settings', 'woothemes'), __('Settings', 'woothemes') , 'manage_woocommerce', 'woocommerce', 'woocommerce_settings'); add_submenu_page('edit.php?post_type=product', __('Attributes', 'woothemes'), __('Attributes', 'woothemes'), 'manage_woocommerce', 'attributes', 'woocommerce_attributes'); } diff --git a/assets/css/admin.css b/assets/css/admin.css index 7352c09f4c3..ab0ba0612fb 100644 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -328,20 +328,24 @@ table.wp-list-table .column-featured, table.wp-list-table .column-sellable, tabl text-align: center !important; } /* Dashboard */ -#woocommerce_dashboard { - padding: 0 5px; +#dashboard_right_now p.woocommerce_sub { + position: static; + top: auto; + left: auto; + margin: 15px 5px 0; + padding: 0 0 5px 0; + border-bottom: #ECECEC 1px solid; } -#woocommerce_dashboard div.postbox div.inside { - margin: 10px; - position: relative; +#dashboard_right_now .onhold { + color: red; } -#woocommerce_dashboard div.postbox h3 { - cursor: default !important; +#dashboard_right_now .pending { + color: #e66f00; } -#woocommerce_dashboard div.postbox a { - text-decoration: none; +#dashboard_right_now .complete { + color: green; } -.stats h3 a { +#woocommmerce_dashboard_sales h3 a { float: right; margin-left: 8px; } @@ -376,131 +380,53 @@ ul.recent-orders li .pending { ul.recent-orders li .refunded, ul.recent-orders li .cancelled { color: #999; } -.woocommerce_right_now p.sub, .woocommerce_right_now .table, .woocommerce_right_now .versions { - margin: -12px; -} -.woocommerce_right_now .inside { - font-size: 12px; - padding-top: 20px; -} -.woocommerce_right_now p.sub { - font-style: italic; - font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; - padding: 5px 10px 15px; - color: #777; - font-size: 13px; - position: absolute; - top: -17px; - left: 15px; -} -.woocommerce_right_now .table { - margin: 0 -9px; - padding: 0 10px; - position: relative; -} -.woocommerce_right_now .table_content { - float: left; - border-top: #ececec 1px solid; - width: 45%; -} -.woocommerce_right_now .table_discussion { - float: right; - border-top: #ececec 1px solid; - width: 45%; -} -.woocommerce_right_now table td { - padding: 3px 0; - white-space: nowrap; -} -.woocommerce_right_now table tr.first td { - border-top: none; -} -.woocommerce_right_now td.b { - padding-right: 6px; - text-align: right; - font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; - font-size: 14px; - width: 1%; -} -.woocommerce_right_now td.b a { - font-size: 18px; -} -.woocommerce_right_now td.b a:hover { - color: #d54e21; -} -.woocommerce_right_now .t { - font-size: 12px; - padding-right: 12px; - padding-top: 6px; - color: #777; -} -.woocommerce_right_now .t a { - white-space: nowrap; -} -.woocommerce_right_now .onhold { - color: red; -} -.woocommerce_right_now .pending { - color: #e66f00; -} -.woocommerce_right_now .complete { - color: green; -} -.woocommerce_right_now .versions { - padding: 4px 15px 12px; - clear: both; -} -.woocommerce-rss-widget ul li, .woocommerce-links-widget ul li { - line-height: 1.5em; - margin-bottom: 12px; -} -.woocommerce-links-widget ul.links { +#woocommmerce_dashboard_useful_links ul.links { float: left; width: 49%; } -.woocommerce-links-widget .social { +#woocommmerce_dashboard_useful_links .social { float: right; width: 49%; } -.woocommerce-links-widget .social h4 { +#woocommmerce_dashboard_useful_links .social h4 { color: #999; } -.woocommerce-links-widget .social h4.first { +#woocommmerce_dashboard_useful_links .social h4.first { margin-top: 0; } -.woocommerce-links-widget .social img { +#woocommmerce_dashboard_useful_links .social img { width: 49%; } -.woocommerce-links-widget .social p { +#woocommmerce_dashboard_useful_links .social p { color: #ccc; line-height: 1.5em; font-style: italic; } -.woocommerce-reviews-widget li { +#woocommmerce_dashboard_recent_reviews li { line-height: 1.5em; margin-bottom: 12px; } -.woocommerce-reviews-widget h4.meta { +#woocommmerce_dashboard_recent_reviews h4.meta { line-height: 1.4; margin: -0.2em 0 0 0; font-weight: normal; color: #999; } -.woocommerce-reviews-widget blockquote { +#woocommmerce_dashboard_recent_reviews blockquote { padding: 0; margin: 0; } -.woocommerce-reviews-widget .avatar { +#woocommmerce_dashboard_recent_reviews .avatar { float: left; margin: 0 10px 5px 0; } -.woocommerce-reviews-widget .star-rating { +#woocommmerce_dashboard_recent_reviews .star-rating { float: right; width: 80px; height: 16px; background: url(../images/star.png) repeat-x left 0; } -.woocommerce-reviews-widget .star-rating span { +#woocommmerce_dashboard_recent_reviews .star-rating span { background: url(../images/star.png) repeat-x left -32px; height: 0; padding-top: 16px; @@ -552,25 +478,6 @@ p.taxrow label input { .woocommerce table.widefat table.coupon_rows tbody td input.text { width: 95px; } -a.tips { - height: 16px; - width: 16px; - margin: 4px -8px 0 0; - float: right; - background: url(../images/tip.png) no-repeat top left; -} -#easyTooltip { - padding: 8px; - border: 3px solid #b9e3f0; - background: #E3F4F9; - font-size: 12px; - width: 400px; - -moz-border-radius: 8px; - -webkit-border-radius: 8px; - -o-border-radius: 8px; - -khtml-border-radius: 8px; - border-radius: 8px; -} .woocommerce #tabs-wrap table a.remove { margin-left: 4px; } diff --git a/assets/css/admin.less b/assets/css/admin.less index 22427eeb496..6a34aabd2e5 100644 --- a/assets/css/admin.less +++ b/assets/css/admin.less @@ -360,21 +360,25 @@ table.wp-list-table .column-featured, table.wp-list-table .column-sellable, tabl } /* Dashboard */ -#woocommerce_dashboard { - padding: 0 5px; +#dashboard_right_now p.woocommerce_sub { + position: static; + top: auto; + left: auto; + margin: 15px 5px 0; + padding: 0 0 5px 0; + border-bottom: #ECECEC 1px solid; } -#woocommerce_dashboard div.postbox div.inside { - margin: 10px; - position: relative; +#dashboard_right_now .onhold { + color: red; } -#woocommerce_dashboard div.postbox h3 { - cursor: default !important; +#dashboard_right_now .pending { + color: #e66f00; } -#woocommerce_dashboard div.postbox a { - text-decoration: none; +#dashboard_right_now .complete { + color: green; } -.stats { +#woocommmerce_dashboard_sales { h3 a { float: right; margin-left: 8px; @@ -415,88 +419,7 @@ ul.recent-orders { } } -.woocommerce_right_now p.sub, -.woocommerce_right_now .table, .woocommerce_right_now .versions { - margin: -12px; -} -.woocommerce_right_now .inside { - font-size: 12px; - padding-top: 20px; -} -.woocommerce_right_now p.sub { - font-style: italic; - font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; - padding: 5px 10px 15px; - color: #777; - font-size: 13px; - position: absolute; - top: -17px; - left: 15px; -} -.woocommerce_right_now .table { - margin: 0 -9px; - padding: 0 10px; - position: relative; -} -.woocommerce_right_now .table_content { - float: left; - border-top: #ececec 1px solid; - width: 45%; -} -.woocommerce_right_now .table_discussion { - float: right; - border-top: #ececec 1px solid; - width: 45%; -} -.woocommerce_right_now table td { - padding: 3px 0; - white-space: nowrap; -} -.woocommerce_right_now table tr.first td { - border-top: none; -} -.woocommerce_right_now td.b { - padding-right: 6px; - text-align: right; - font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif; - font-size: 14px; - width: 1%; -} -.woocommerce_right_now td.b a { - font-size: 18px; -} -.woocommerce_right_now td.b a:hover { - color: #d54e21; -} -.woocommerce_right_now .t { - font-size: 12px; - padding-right: 12px; - padding-top: 6px; - color: #777; -} -.woocommerce_right_now .t a { - white-space: nowrap; -} -.woocommerce_right_now .onhold { - color: red; -} -.woocommerce_right_now .pending { - color: #e66f00; -} -.woocommerce_right_now .complete { - color: green; -} -.woocommerce_right_now .versions { - padding: 4px 15px 12px; - clear: both; -} - -.woocommerce-rss-widget ul li, .woocommerce-links-widget ul li { - line-height: 1.5em; - margin-bottom: 12px; -} - -.woocommerce-links-widget { +#woocommmerce_dashboard_useful_links { ul.links { float: left; width: 49%; @@ -521,7 +444,7 @@ ul.recent-orders { } } -.woocommerce-reviews-widget { +#woocommmerce_dashboard_recent_reviews { li { line-height: 1.5em; margin-bottom: 12px; @@ -610,25 +533,7 @@ p.taxrow label { } -a.tips { - height: 16px; - width: 16px; - margin: 4px -8px 0 0; - float: right; - background: url(../images/tip.png) no-repeat top left; -} -#easyTooltip { - padding:8px; - border:3px solid #b9e3f0; - background:#E3F4F9; - font-size: 12px; - width:400px; - -moz-border-radius:8px; - -webkit-border-radius:8px; - -o-border-radius:8px; - -khtml-border-radius:8px; - border-radius:8px; -} + .woocommerce #tabs-wrap table a.remove { margin-left: 4px; } diff --git a/assets/images/icons/menu_icons.png b/assets/images/icons/menu_icons.png index 81c07e942ba..a5843612a95 100644 Binary files a/assets/images/icons/menu_icons.png and b/assets/images/icons/menu_icons.png differ diff --git a/assets/js/woocommerce_dashboard_sales.js b/assets/js/woocommerce_dashboard_sales.js new file mode 100644 index 00000000000..50230d7bbe2 --- /dev/null +++ b/assets/js/woocommerce_dashboard_sales.js @@ -0,0 +1,97 @@ +jQuery(function(){ + + function weekendAreas(axes) { + var markings = []; + var d = new Date(axes.xaxis.min); + // go to the first Saturday + d.setUTCDate(d.getUTCDate() - ((d.getUTCDay() + 1) % 7)) + d.setUTCSeconds(0); + d.setUTCMinutes(0); + d.setUTCHours(0); + var i = d.getTime(); + do { + // when we don't set yaxis, the rectangle automatically + // extends to infinity upwards and downwards + markings.push({ xaxis: { from: i, to: i + 2 * 24 * 60 * 60 * 1000 } }); + i += 7 * 24 * 60 * 60 * 1000; + } while (i < axes.xaxis.max); + + return markings; + } + + var order_data = jQuery.parseJSON( params.order_data.replace(/"/g, '"') ); + + var d = order_data.order_counts; + var d2 = order_data.order_amounts; + + for (var i = 0; i < d.length; ++i) d[i][0] += 60 * 60 * 1000; + for (var i = 0; i < d2.length; ++i) d2[i][0] += 60 * 60 * 1000; + + var plot = jQuery.plot(jQuery("#placeholder"), [ { label: "Number of sales", data: d }, { label: "Sales amount", data: d2, yaxis: 2 } ], { + series: { + lines: { show: true }, + points: { show: true } + }, + grid: { + show: true, + aboveData: false, + color: '#ccc', + backgroundColor: '#fff', + borderWidth: 2, + borderColor: '#ccc', + clickable: false, + hoverable: true, + markings: weekendAreas + }, + xaxis: { + mode: "time", + timeformat: "%d %b", + tickLength: 1, + minTickSize: [1, "day"] + }, + yaxes: [ { min: 0, tickSize: 1, tickDecimals: 0 }, { position: "right", min: 0, tickDecimals: 2 } ], + colors: ["#21759B", "#ed8432"] + }); + + function showTooltip(x, y, contents) { + jQuery('
' + contents + '
').css( { + position: 'absolute', + display: 'none', + top: y + 5, + left: x + 5, + border: '1px solid #fdd', + padding: '2px', + 'background-color': '#fee', + opacity: 0.80 + }).appendTo("body").fadeIn(200); + } + + var previousPoint = null; + jQuery("#placeholder").bind("plothover", function (event, pos, item) { + if (item) { + if (previousPoint != item.dataIndex) { + previousPoint = item.dataIndex; + + jQuery("#tooltip").remove(); + + if (item.series.label=="Number of sales") { + + var y = item.datapoint[1]; + showTooltip(item.pageX, item.pageY, item.series.label + " - " + y); + + } else { + + var y = item.datapoint[1].toFixed(2); + showTooltip(item.pageX, item.pageY, item.series.label + " - " + params.currency_symbol + y); + + } + + } + } + else { + jQuery("#tooltip").remove(); + previousPoint = null; + } + }); + +}); \ No newline at end of file diff --git a/classes/product.class.php b/classes/product.class.php index 6f4d5160254..ca94ade2c2a 100644 --- a/classes/product.class.php +++ b/classes/product.class.php @@ -200,7 +200,7 @@ class woocommerce_product { /** Get the title of the post */ function get_title () { $this->get_post_data(); - return apply_filters('woocommerce_product_title', $this->post->post_title, $this); + return apply_filters('woocommerce_product_title', get_the_title($this->post->ID), $this); }