class-wc-report-customers.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. <?php
  2. /**
  3. * Class WC_Report_Customers file.
  4. *
  5. * @package WooCommerce\Reports
  6. */
  7. if ( ! defined( 'ABSPATH' ) ) {
  8. exit; // Exit if accessed directly.
  9. }
  10. /**
  11. * WC_Report_Customers
  12. *
  13. * @package WooCommerce/Admin/Reports
  14. * @version 2.1.0
  15. */
  16. class WC_Report_Customers extends WC_Admin_Report {
  17. /**
  18. * Chart colors.
  19. *
  20. * @var array
  21. */
  22. public $chart_colours = array();
  23. /**
  24. * Customers.
  25. *
  26. * @var array
  27. */
  28. public $customers = array();
  29. /**
  30. * Get the legend for the main chart sidebar.
  31. *
  32. * @return array
  33. */
  34. public function get_chart_legend() {
  35. $legend = array();
  36. $legend[] = array(
  37. /* translators: %s: signups amount */
  38. 'title' => sprintf( __( '%s signups in this period', 'woocommerce' ), '<strong>' . count( $this->customers ) . '</strong>' ),
  39. 'color' => $this->chart_colours['signups'],
  40. 'highlight_series' => 2,
  41. );
  42. return $legend;
  43. }
  44. /**
  45. * Get chart widgets.
  46. *
  47. * @return array
  48. */
  49. public function get_chart_widgets() {
  50. $widgets = array();
  51. $widgets[] = array(
  52. 'title' => '',
  53. 'callback' => array( $this, 'customers_vs_guests' ),
  54. );
  55. return $widgets;
  56. }
  57. /**
  58. * Output customers vs guests chart.
  59. */
  60. public function customers_vs_guests() {
  61. $customer_order_totals = $this->get_order_report_data(
  62. array(
  63. 'data' => array(
  64. 'ID' => array(
  65. 'type' => 'post_data',
  66. 'function' => 'COUNT',
  67. 'name' => 'total_orders',
  68. ),
  69. ),
  70. 'where_meta' => array(
  71. array(
  72. 'meta_key' => '_customer_user',
  73. 'meta_value' => '0',
  74. 'operator' => '>',
  75. ),
  76. ),
  77. 'filter_range' => true,
  78. )
  79. );
  80. $guest_order_totals = $this->get_order_report_data(
  81. array(
  82. 'data' => array(
  83. 'ID' => array(
  84. 'type' => 'post_data',
  85. 'function' => 'COUNT',
  86. 'name' => 'total_orders',
  87. ),
  88. ),
  89. 'where_meta' => array(
  90. array(
  91. 'meta_key' => '_customer_user',
  92. 'meta_value' => '0',
  93. 'operator' => '=',
  94. ),
  95. ),
  96. 'filter_range' => true,
  97. )
  98. );
  99. ?>
  100. <div class="chart-container">
  101. <div class="chart-placeholder customers_vs_guests pie-chart" style="height:200px"></div>
  102. <ul class="pie-chart-legend">
  103. <li style="border-color: <?php echo esc_attr( $this->chart_colours['customers'] ); ?>"><?php esc_html_e( 'Customer sales', 'woocommerce' ); ?></li>
  104. <li style="border-color: <?php echo esc_attr( $this->chart_colours['guests'] ); ?>"><?php esc_html_e( 'Guest sales', 'woocommerce' ); ?></li>
  105. </ul>
  106. </div>
  107. <script type="text/javascript">
  108. jQuery(function(){
  109. jQuery.plot(
  110. jQuery('.chart-placeholder.customers_vs_guests'),
  111. [
  112. {
  113. label: '<?php esc_html_e( 'Customer orders', 'woocommerce' ); ?>',
  114. data: "<?php echo esc_html( $customer_order_totals->total_orders ); ?>",
  115. color: '<?php echo esc_html( $this->chart_colours['customers'] ); ?>'
  116. },
  117. {
  118. label: '<?php esc_html_e( 'Guest orders', 'woocommerce' ); ?>',
  119. data: "<?php echo esc_html( $guest_order_totals->total_orders ); ?>",
  120. color: '<?php echo esc_html( $this->chart_colours['guests'] ); ?>'
  121. }
  122. ],
  123. {
  124. grid: {
  125. hoverable: true
  126. },
  127. series: {
  128. pie: {
  129. show: true,
  130. radius: 1,
  131. innerRadius: 0.6,
  132. label: {
  133. show: false
  134. }
  135. },
  136. enable_tooltip: true,
  137. append_tooltip: "<?php echo esc_html( ' ' . __( 'orders', 'woocommerce' ) ); ?>",
  138. },
  139. legend: {
  140. show: false
  141. }
  142. }
  143. );
  144. jQuery('.chart-placeholder.customers_vs_guests').resize();
  145. });
  146. </script>
  147. <?php
  148. }
  149. /**
  150. * Output the report.
  151. */
  152. public function output_report() {
  153. $ranges = array(
  154. 'year' => __( 'Year', 'woocommerce' ),
  155. 'last_month' => __( 'Last month', 'woocommerce' ),
  156. 'month' => __( 'This month', 'woocommerce' ),
  157. '7day' => __( 'Last 7 days', 'woocommerce' ),
  158. );
  159. $this->chart_colours = array(
  160. 'signups' => '#3498db',
  161. 'customers' => '#1abc9c',
  162. 'guests' => '#8fdece',
  163. );
  164. $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( wp_unslash( $_GET['range'] ) ) : '7day';
  165. if ( ! in_array( $current_range, array( 'custom', 'year', 'last_month', 'month', '7day' ), true ) ) {
  166. $current_range = '7day';
  167. }
  168. $this->check_current_range_nonce( $current_range );
  169. $this->calculate_current_range( $current_range );
  170. $admin_users = new WP_User_Query(
  171. array(
  172. 'role' => 'administrator',
  173. 'fields' => 'ID',
  174. )
  175. );
  176. $manager_users = new WP_User_Query(
  177. array(
  178. 'role' => 'shop_manager',
  179. 'fields' => 'ID',
  180. )
  181. );
  182. $users_query = new WP_User_Query(
  183. array(
  184. 'fields' => array( 'user_registered' ),
  185. 'exclude' => array_merge( $admin_users->get_results(), $manager_users->get_results() ),
  186. )
  187. );
  188. $this->customers = $users_query->get_results();
  189. foreach ( $this->customers as $key => $customer ) {
  190. if ( strtotime( $customer->user_registered ) < $this->start_date || strtotime( $customer->user_registered ) > $this->end_date ) {
  191. unset( $this->customers[ $key ] );
  192. }
  193. }
  194. include WC()->plugin_path() . '/includes/admin/views/html-report-by-date.php';
  195. }
  196. /**
  197. * Output an export link.
  198. */
  199. public function get_export_button() {
  200. $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( wp_unslash( $_GET['range'] ) ) : '7day';
  201. ?>
  202. <a
  203. href="#"
  204. download="report-<?php echo esc_attr( $current_range ); ?>-<?php echo esc_attr( date_i18n( 'Y-m-d', current_time( 'timestamp' ) ) ); ?>.csv"
  205. class="export_csv"
  206. data-export="chart"
  207. data-xaxes="<?php esc_attr_e( 'Date', 'woocommerce' ); ?>"
  208. data-groupby="<?php echo esc_attr( $this->chart_groupby ); ?>"
  209. >
  210. <?php esc_html_e( 'Export CSV', 'woocommerce' ); ?>
  211. </a>
  212. <?php
  213. }
  214. /**
  215. * Output the main chart.
  216. */
  217. public function get_main_chart() {
  218. global $wp_locale;
  219. $customer_orders = $this->get_order_report_data(
  220. array(
  221. 'data' => array(
  222. 'ID' => array(
  223. 'type' => 'post_data',
  224. 'function' => 'COUNT',
  225. 'name' => 'total_orders',
  226. ),
  227. 'post_date' => array(
  228. 'type' => 'post_data',
  229. 'function' => '',
  230. 'name' => 'post_date',
  231. ),
  232. ),
  233. 'where_meta' => array(
  234. array(
  235. 'meta_key' => '_customer_user',
  236. 'meta_value' => '0',
  237. 'operator' => '>',
  238. ),
  239. ),
  240. 'group_by' => $this->group_by_query,
  241. 'order_by' => 'post_date ASC',
  242. 'query_type' => 'get_results',
  243. 'filter_range' => true,
  244. )
  245. );
  246. $guest_orders = $this->get_order_report_data(
  247. array(
  248. 'data' => array(
  249. 'ID' => array(
  250. 'type' => 'post_data',
  251. 'function' => 'COUNT',
  252. 'name' => 'total_orders',
  253. ),
  254. 'post_date' => array(
  255. 'type' => 'post_data',
  256. 'function' => '',
  257. 'name' => 'post_date',
  258. ),
  259. ),
  260. 'where_meta' => array(
  261. array(
  262. 'meta_key' => '_customer_user',
  263. 'meta_value' => '0',
  264. 'operator' => '=',
  265. ),
  266. ),
  267. 'group_by' => $this->group_by_query,
  268. 'order_by' => 'post_date ASC',
  269. 'query_type' => 'get_results',
  270. 'filter_range' => true,
  271. )
  272. );
  273. $signups = $this->prepare_chart_data( $this->customers, 'user_registered', '', $this->chart_interval, $this->start_date, $this->chart_groupby );
  274. $customer_orders = $this->prepare_chart_data( $customer_orders, 'post_date', 'total_orders', $this->chart_interval, $this->start_date, $this->chart_groupby );
  275. $guest_orders = $this->prepare_chart_data( $guest_orders, 'post_date', 'total_orders', $this->chart_interval, $this->start_date, $this->chart_groupby );
  276. $chart_data = array(
  277. 'signups' => array_values( $signups ),
  278. 'customer_orders' => array_values( $customer_orders ),
  279. 'guest_orders' => array_values( $guest_orders ),
  280. );
  281. ?>
  282. <div class="chart-container">
  283. <div class="chart-placeholder main"></div>
  284. </div>
  285. <script type="text/javascript">
  286. var main_chart;
  287. jQuery(function(){
  288. var chart_data = jQuery.parseJSON( '<?php echo wp_json_encode( $chart_data ); ?>' );
  289. var drawGraph = function( highlight ) {
  290. var series = [
  291. {
  292. label: "<?php echo esc_js( __( 'Customer orders', 'woocommerce' ) ); ?>",
  293. data: chart_data.customer_orders,
  294. color: '<?php echo esc_html( $this->chart_colours['customers'] ); ?>',
  295. bars: { fillColor: '<?php echo esc_html( $this->chart_colours['customers'] ); ?>', fill: true, show: true, lineWidth: 0, barWidth: <?php echo esc_html( $this->barwidth ); ?> * 0.5, align: 'center' },
  296. shadowSize: 0,
  297. enable_tooltip: true,
  298. append_tooltip: "<?php echo esc_html( ' ' . __( 'customer orders', 'woocommerce' ) ); ?>",
  299. stack: true,
  300. },
  301. {
  302. label: "<?php echo esc_js( __( 'Guest orders', 'woocommerce' ) ); ?>",
  303. data: chart_data.guest_orders,
  304. color: '<?php echo esc_html( $this->chart_colours['guests'] ); ?>',
  305. bars: { fillColor: '<?php echo esc_html( $this->chart_colours['guests'] ); ?>', fill: true, show: true, lineWidth: 0, barWidth: <?php echo esc_html( $this->barwidth ); ?> * 0.5, align: 'center' },
  306. shadowSize: 0,
  307. enable_tooltip: true,
  308. append_tooltip: "<?php echo esc_html( ' ' . __( 'guest orders', 'woocommerce' ) ); ?>",
  309. stack: true,
  310. },
  311. {
  312. label: "<?php echo esc_js( __( 'Signups', 'woocommerce' ) ); ?>",
  313. data: chart_data.signups,
  314. color: '<?php echo esc_html( $this->chart_colours['signups'] ); ?>',
  315. points: { show: true, radius: 5, lineWidth: 3, fillColor: '#fff', fill: true },
  316. lines: { show: true, lineWidth: 4, fill: false },
  317. shadowSize: 0,
  318. enable_tooltip: true,
  319. append_tooltip: "<?php echo esc_html( ' ' . __( 'new users', 'woocommerce' ) ); ?>",
  320. stack: false
  321. },
  322. ];
  323. if ( highlight !== 'undefined' && series[ highlight ] ) {
  324. highlight_series = series[ highlight ];
  325. highlight_series.color = '#9c5d90';
  326. if ( highlight_series.bars )
  327. highlight_series.bars.fillColor = '#9c5d90';
  328. if ( highlight_series.lines ) {
  329. highlight_series.lines.lineWidth = 5;
  330. }
  331. }
  332. main_chart = jQuery.plot(
  333. jQuery('.chart-placeholder.main'),
  334. series,
  335. {
  336. legend: {
  337. show: false
  338. },
  339. grid: {
  340. color: '#aaa',
  341. borderColor: 'transparent',
  342. borderWidth: 0,
  343. hoverable: true
  344. },
  345. xaxes: [ {
  346. color: '#aaa',
  347. position: "bottom",
  348. tickColor: 'transparent',
  349. mode: "time",
  350. timeformat: "<?php echo ( 'day' === $this->chart_groupby ) ? '%d %b' : '%b'; ?>",
  351. monthNames: <?php echo wp_json_encode( array_values( $wp_locale->month_abbrev ) ); ?>,
  352. tickLength: 1,
  353. minTickSize: [1, "<?php echo esc_html( $this->chart_groupby ); ?>"],
  354. tickSize: [1, "<?php echo esc_html( $this->chart_groupby ); ?>"],
  355. font: {
  356. color: "#aaa"
  357. }
  358. } ],
  359. yaxes: [
  360. {
  361. min: 0,
  362. minTickSize: 1,
  363. tickDecimals: 0,
  364. color: '#ecf0f1',
  365. font: { color: "#aaa" }
  366. }
  367. ],
  368. }
  369. );
  370. jQuery('.chart-placeholder').resize();
  371. }
  372. drawGraph();
  373. jQuery('.highlight_series').hover(
  374. function() {
  375. drawGraph( jQuery(this).data('series') );
  376. },
  377. function() {
  378. drawGraph();
  379. }
  380. );
  381. });
  382. </script>
  383. <?php
  384. }
  385. }