PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/admin/woocommerce-admin-dashboard.php

https://github.com/CammoKing/woocommerce
PHP | 459 lines | 295 code | 105 blank | 59 comment | 25 complexity | 7393f1cc4ccf77024bd67395c796653c MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /**
  3. * Functions used for displaying the WooCommerce dashboard widgets
  4. *
  5. * @author WooThemes
  6. * @category Admin
  7. * @package WooCommerce/Admin/Dashboard
  8. * @version 1.6.4
  9. */
  10. if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
  11. // Only hook in admin parts if the user has admin access
  12. if ( current_user_can( 'view_woocommerce_reports' ) || current_user_can( 'manage_woocommerce' ) || current_user_can( 'publish_shop_orders' ) )
  13. add_action( 'wp_dashboard_setup', 'woocommerce_init_dashboard_widgets' );
  14. /**
  15. * Init the dashboard widgets.
  16. *
  17. * @access public
  18. * @return void
  19. */
  20. function woocommerce_init_dashboard_widgets() {
  21. global $current_month_offset, $the_month_num, $the_year;
  22. $current_month_offset = 0;
  23. if (isset($_GET['wc_sales_month'])) $current_month_offset = (int) $_GET['wc_sales_month'];
  24. $the_month_num = date('n', strtotime('NOW '.($current_month_offset).' MONTH'));
  25. $the_year = date('Y', strtotime('NOW '.($current_month_offset).' MONTH'));
  26. $sales_heading = '';
  27. if ($the_month_num!=date('m')) :
  28. $sales_heading .= '<a href="index.php?wc_sales_month='.($current_month_offset+1).'" class="next">'.date_i18n('F', strtotime('01-'.($the_month_num+1).'-2011')).' &rarr;</a>';
  29. endif;
  30. $sales_heading .= '<a href="index.php?wc_sales_month='.($current_month_offset-1).'" class="previous">&larr; '.date_i18n('F', strtotime('01-'.($the_month_num-1).'-2011')).'</a><span>'.__( 'Monthly Sales', 'woocommerce' ).'</span>';
  31. if ( current_user_can( 'publish_shop_orders' ) ) {
  32. wp_add_dashboard_widget( 'woocommerce_dashboard_right_now', __( 'WooCommerce Right Now', 'woocommerce' ), 'woocommerce_dashboard_widget_right_now' );
  33. wp_add_dashboard_widget( 'woocommerce_dashboard_recent_orders', __( 'WooCommerce Recent Orders', 'woocommerce' ), 'woocommerce_dashboard_recent_orders');
  34. wp_add_dashboard_widget( 'woocommerce_dashboard_recent_reviews', __( 'WooCommerce Recent Reviews', 'woocommerce' ), 'woocommerce_dashboard_recent_reviews' );
  35. }
  36. if ( current_user_can( 'view_woocommerce_reports' ) || current_user_can( 'publish_shop_orders' ) ) {
  37. wp_add_dashboard_widget( 'woocommerce_dashboard_sales', $sales_heading, 'woocommerce_dashboard_sales' );
  38. }
  39. }
  40. /**
  41. * WooCommerce Right Now widget.
  42. *
  43. * Adds a dashboard widget with shop statistics.
  44. *
  45. * @access public
  46. * @return void
  47. */
  48. function woocommerce_dashboard_widget_right_now() {
  49. global $woocommerce;
  50. $product_count = wp_count_posts( 'product' );
  51. $product_cat_count = wp_count_terms( 'product_cat' );
  52. $product_tag_count = wp_count_terms( 'product_tag' );
  53. $product_attr_count = count( $woocommerce->get_attribute_taxonomies() );
  54. $pending_count = get_term_by( 'slug', 'pending', 'shop_order_status' )->count;
  55. $completed_count = get_term_by( 'slug', 'completed', 'shop_order_status' )->count;
  56. $on_hold_count = get_term_by( 'slug', 'on-hold', 'shop_order_status' )->count;
  57. $processing_count = get_term_by( 'slug', 'processing', 'shop_order_status' )->count;
  58. ?>
  59. <div class="table table_shop_content">
  60. <p class="sub woocommerce_sub"><?php _e( 'Shop Content', 'woocommerce' ); ?></p>
  61. <table>
  62. <tr class="first">
  63. <?php
  64. $num = number_format_i18n( $product_count->publish );
  65. $text = _n( 'Product', 'Products', intval( $product_count->publish ), 'woocommerce' );
  66. $link = add_query_arg( array( 'post_type' => 'product' ), get_admin_url( null, 'edit.php' ) );
  67. $num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
  68. $text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
  69. ?>
  70. <td class="first b b-products"><?php echo $num; ?></td>
  71. <td class="t products"><?php echo $text; ?></td>
  72. </tr>
  73. <tr>
  74. <?php
  75. $num = number_format_i18n( $product_cat_count );
  76. $text = _n( 'Product Category', 'Product Categories', $product_cat_count, 'woocommerce' );
  77. $link = add_query_arg( array( 'taxonomy' => 'product_cat', 'post_type' => 'product' ), get_admin_url( null, 'edit-tags.php' ) );
  78. $num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
  79. $text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
  80. ?>
  81. <td class="first b b-product_cats"><?php echo $num; ?></td>
  82. <td class="t product_cats"><?php echo $text; ?></td>
  83. </tr>
  84. <tr>
  85. <?php
  86. $num = number_format_i18n( $product_tag_count );
  87. $text = _n( 'Product Tag', 'Product Tags', $product_tag_count, 'woocommerce' );
  88. $link = add_query_arg( array( 'taxonomy' => 'product_tag', 'post_type' => 'product' ), get_admin_url( null, 'edit-tags.php' ) );
  89. $num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
  90. $text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
  91. ?>
  92. <td class="first b b-product_tag"><?php echo $num; ?></td>
  93. <td class="t product_tag"><?php echo $text; ?></td>
  94. </tr>
  95. <tr>
  96. <?php
  97. $num = number_format_i18n( $product_attr_count );
  98. $text = _n( 'Attribute', 'Attributes', $product_attr_count, 'woocommerce' );
  99. $link = add_query_arg( array( 'page' => 'woocommerce_attributes' ), get_admin_url( null, 'admin.php' ) );
  100. $num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
  101. $text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
  102. ?>
  103. <td class="first b b-attributes"><?php echo $num; ?></td>
  104. <td class="t attributes"><?php echo $text; ?></td>
  105. </tr>
  106. <?php do_action( 'woocommerce_right_now_shop_content_table_end' ); ?>
  107. </table>
  108. </div>
  109. <div class="table table_orders">
  110. <p class="sub woocommerce_sub"><?php _e( 'Orders', 'woocommerce' ); ?></p>
  111. <table>
  112. <tr class="first">
  113. <?php
  114. $num = number_format_i18n( $pending_count );
  115. $text = __( 'Pending', 'woocommerce' );
  116. $link = add_query_arg( array( 'post_type' => 'shop_order', 'shop_order_status' => 'pending' ), get_admin_url( null, 'edit.php' ) );
  117. $num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
  118. $text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
  119. ?>
  120. <td class="b b-pending"><?php echo $num; ?></td>
  121. <td class="last t pending"><?php echo $text; ?></td>
  122. </tr>
  123. <tr>
  124. <?php
  125. $num = number_format_i18n( $on_hold_count );
  126. $text = __( 'On-Hold', 'woocommerce' );
  127. $link = add_query_arg( array( 'post_type' => 'shop_order', 'shop_order_status' => 'on-hold' ), get_admin_url( null, 'edit.php' ) );
  128. $num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
  129. $text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
  130. ?>
  131. <td class="b b-on-hold"><?php echo $num; ?></td>
  132. <td class="last t on-hold"><?php echo $text; ?></td>
  133. </tr>
  134. <tr>
  135. <?php
  136. $num = number_format_i18n( $processing_count );
  137. $text = __( 'Processing', 'woocommerce' );
  138. $link = add_query_arg( array( 'post_type' => 'shop_order', 'shop_order_status' => 'processing' ), get_admin_url( null, 'edit.php' ) );
  139. $num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
  140. $text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
  141. ?>
  142. <td class="b b-processing"><?php echo $num; ?></td>
  143. <td class="last t processing"><?php echo $text; ?></td>
  144. </tr>
  145. <tr>
  146. <?php
  147. $num = number_format_i18n( $completed_count );
  148. $text = __( 'Completed', 'woocommerce' );
  149. $link = add_query_arg( array( 'post_type' => 'shop_order', 'shop_order_status' => 'completed' ), get_admin_url( null, 'edit.php' ) );
  150. $num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
  151. $text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
  152. ?>
  153. <td class="b b-completed"><?php echo $num; ?></td>
  154. <td class="last t completed"><?php echo $text; ?></td>
  155. </tr>
  156. <?php do_action( 'woocommerce_right_now_orders_table_end' ); ?>
  157. </table>
  158. </div>
  159. <div class="versions">
  160. <p id="wp-version-message">
  161. <?php printf( __( 'You are using <strong>WooCommerce %s</strong>.', 'woocommerce' ), $woocommerce->version ); ?>
  162. </p>
  163. </div>
  164. <?php
  165. }
  166. /**
  167. * Recent orders widget
  168. *
  169. * @access public
  170. * @return void
  171. */
  172. function woocommerce_dashboard_recent_orders() {
  173. $args = array(
  174. 'numberposts' => 8,
  175. 'orderby' => 'post_date',
  176. 'order' => 'DESC',
  177. 'post_type' => 'shop_order',
  178. 'post_status' => 'publish'
  179. );
  180. $orders = get_posts( $args );
  181. if ($orders) :
  182. echo '<ul class="recent-orders">';
  183. foreach ($orders as $order) :
  184. $this_order = new WC_Order( $order->ID );
  185. echo '
  186. <li>
  187. <span class="order-status '.sanitize_title($this_order->status).'">'.ucwords(__($this_order->status, 'woocommerce')).'</span> <a href="'.admin_url('post.php?post='.$order->ID).'&action=edit">' . get_the_time( __( 'l jS \of F Y h:i:s A', 'woocommerce' ), $order->ID ) . '</a><br />
  188. <small>'.sizeof($this_order->get_items()).' '._n('item', 'items', sizeof($this_order->get_items()), 'woocommerce').' <span class="order-cost">'.__('Total:', 'woocommerce' ) . ' ' . woocommerce_price($this_order->order_total).'</span></small>
  189. </li>';
  190. endforeach;
  191. echo '</ul>';
  192. else:
  193. echo '<p>' . __( 'There are no product orders yet.', 'woocommerce' ) . '</p>';
  194. endif;
  195. }
  196. /**
  197. * Recent reviews widget
  198. *
  199. * @access public
  200. * @return void
  201. */
  202. function woocommerce_dashboard_recent_reviews() {
  203. global $wpdb;
  204. $comments = $wpdb->get_results( $wpdb->prepare( "SELECT *, SUBSTRING(comment_content,1,100) AS comment_excerpt
  205. FROM $wpdb->comments
  206. LEFT JOIN $wpdb->posts ON ($wpdb->comments.comment_post_ID = $wpdb->posts.ID)
  207. WHERE comment_approved = '1'
  208. AND comment_type = ''
  209. AND post_password = ''
  210. AND post_type = 'product'
  211. ORDER BY comment_date_gmt DESC
  212. LIMIT 5" ) );
  213. if ( $comments ) {
  214. echo '<ul>';
  215. foreach ( $comments as $comment ) {
  216. echo '<li>';
  217. echo get_avatar( $comment->comment_author, '32' );
  218. $rating = get_comment_meta( $comment->comment_ID, 'rating', true );
  219. echo '<div class="star-rating" title="' . $rating . '">
  220. <span style="width:'. ( $rating * 10 ) . 'px">' . $rating . ' ' . __( 'out of 5', 'woocommerce' ) . '</span></div>';
  221. echo '<h4 class="meta"><a href="' . get_permalink( $comment->ID ) . '#comment-' . absint( $comment->comment_ID ) .'">' . esc_html__( $comment->post_title ) . '</a> reviewed by ' . esc_html( $comment->comment_author ) .'</h4>';
  222. echo '<blockquote>' . wp_kses_data( $comment->comment_excerpt ) . ' [...]</blockquote></li>';
  223. }
  224. echo '</ul>';
  225. } else {
  226. echo '<p>' . __( 'There are no product reviews yet.', 'woocommerce' ) . '</p>';
  227. }
  228. }
  229. /**
  230. * Orders this month filter function - filters orders for the month
  231. *
  232. * @access public
  233. * @param string $where (default: '')
  234. * @return void
  235. */
  236. function orders_this_month( $where = '' ) {
  237. global $the_month_num, $the_year;
  238. $month = $the_month_num;
  239. $year = (int) $the_year;
  240. $first_day = strtotime("{$year}-{$month}-01");
  241. //$last_day = strtotime('-1 second', strtotime('+1 month', $first_day));
  242. $last_day = strtotime('+1 month', $first_day);
  243. $after = date('Y-m-d', $first_day);
  244. $before = date('Y-m-d', $last_day);
  245. $where .= " AND post_date > '$after'";
  246. $where .= " AND post_date < '$before'";
  247. return $where;
  248. }
  249. /**
  250. * Sales widget
  251. *
  252. * @access public
  253. * @return void
  254. */
  255. function woocommerce_dashboard_sales() {
  256. add_action( 'admin_footer', 'woocommerce_dashboard_sales_js' );
  257. ?><div id="placeholder" style="width:100%; height:300px; position:relative;"></div><?php
  258. }
  259. /**
  260. * Sales widget javascript
  261. *
  262. * @access public
  263. * @return void
  264. */
  265. function woocommerce_dashboard_sales_js() {
  266. global $woocommerce, $wp_locale;
  267. $screen = get_current_screen();
  268. if (!$screen || $screen->id!=='dashboard') return;
  269. global $current_month_offset, $the_month_num, $the_year;
  270. // Get orders to display in widget
  271. add_filter( 'posts_where', 'orders_this_month' );
  272. $args = array(
  273. 'numberposts' => -1,
  274. 'orderby' => 'post_date',
  275. 'order' => 'DESC',
  276. 'post_type' => 'shop_order',
  277. 'post_status' => 'publish' ,
  278. 'suppress_filters' => false,
  279. 'tax_query' => array(
  280. array(
  281. 'taxonomy' => 'shop_order_status',
  282. 'terms' => apply_filters( 'woocommerce_reports_order_statuses', array( 'completed', 'processing', 'on-hold' ) ),
  283. 'field' => 'slug',
  284. 'operator' => 'IN'
  285. )
  286. )
  287. );
  288. $orders = get_posts( $args );
  289. $order_counts = array();
  290. $order_amounts = array();
  291. // Blank date ranges to begin
  292. $month = $the_month_num;
  293. $year = (int) $the_year;
  294. $first_day = strtotime("{$year}-{$month}-01");
  295. $last_day = strtotime('-1 second', strtotime('+1 month', $first_day));
  296. if ((date('m') - $the_month_num)==0) :
  297. $up_to = date('d', strtotime('NOW'));
  298. else :
  299. $up_to = date('d', $last_day);
  300. endif;
  301. $count = 0;
  302. while ($count < $up_to) :
  303. $time = strtotime(date('Ymd', strtotime('+ '.$count.' DAY', $first_day))).'000';
  304. $order_counts[$time] = 0;
  305. $order_amounts[$time] = 0;
  306. $count++;
  307. endwhile;
  308. if ($orders) :
  309. foreach ($orders as $order) :
  310. $order_data = new WC_Order($order->ID);
  311. if ($order_data->status=='cancelled' || $order_data->status=='refunded') continue;
  312. $time = strtotime(date('Ymd', strtotime($order->post_date))).'000';
  313. if (isset($order_counts[$time])) :
  314. $order_counts[$time]++;
  315. else :
  316. $order_counts[$time] = 1;
  317. endif;
  318. if (isset($order_amounts[$time])) :
  319. $order_amounts[$time] = $order_amounts[$time] + $order_data->order_total;
  320. else :
  321. $order_amounts[$time] = (float) $order_data->order_total;
  322. endif;
  323. endforeach;
  324. endif;
  325. remove_filter( 'posts_where', 'orders_this_month' );
  326. /* Script variables */
  327. $params = array(
  328. 'currency_symbol' => get_woocommerce_currency_symbol(),
  329. 'number_of_sales' => absint( array_sum( $order_counts ) ),
  330. 'sales_amount' => woocommerce_price( array_sum( $order_amounts ) ),
  331. 'sold' => __( 'Sold', 'woocommerce' ),
  332. 'earned' => __( 'Earned', 'woocommerce' ),
  333. 'month_names' => array_values( $wp_locale->month_abbrev ),
  334. );
  335. $order_counts_array = array();
  336. foreach ($order_counts as $key => $count) :
  337. $order_counts_array[] = array($key, $count);
  338. endforeach;
  339. $order_amounts_array = array();
  340. foreach ($order_amounts as $key => $amount) :
  341. $order_amounts_array[] = array($key, $amount);
  342. endforeach;
  343. $order_data = array( 'order_counts' => $order_counts_array, 'order_amounts' => $order_amounts_array );
  344. $params['order_data'] = json_encode($order_data);
  345. // Queue scripts
  346. $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
  347. wp_register_script( 'woocommerce_dashboard_sales', $woocommerce->plugin_url() . '/assets/js/admin/dashboard_sales'.$suffix.'.js', 'jquery', '1.0' );
  348. wp_register_script( 'flot', $woocommerce->plugin_url() . '/assets/js/admin/jquery.flot'.$suffix.'.js', 'jquery', '1.0' );
  349. wp_register_script( 'flot-resize', $woocommerce->plugin_url() . '/assets/js/admin/jquery.flot.resize'.$suffix.'.js', 'jquery', '1.0' );
  350. wp_localize_script( 'woocommerce_dashboard_sales', 'params', $params );
  351. wp_print_scripts('flot');
  352. wp_print_scripts('flot-resize');
  353. wp_print_scripts('woocommerce_dashboard_sales');
  354. }