PageRenderTime 69ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/wp-content/plugins/woocommerce/includes/admin/reports/class-wc-report-sales-by-category.php

https://gitlab.com/webkod3r/tripolis
PHP | 438 lines | 311 code | 64 blank | 63 comment | 26 complexity | cbcfffa6b89278335146e55b6c3fae87 MD5 | raw file
  1. <?php
  2. if ( ! defined( 'ABSPATH' ) ) {
  3. exit; // Exit if accessed directly
  4. }
  5. /**
  6. * WC_Report_Sales_By_Category
  7. *
  8. * @author WooThemes
  9. * @category Admin
  10. * @package WooCommerce/Admin/Reports
  11. * @version 2.1.0
  12. */
  13. class WC_Report_Sales_By_Category extends WC_Admin_Report {
  14. /**
  15. * Chart colours.
  16. *
  17. * @var array
  18. */
  19. public $chart_colours = array();
  20. /**
  21. * Categories ids.
  22. *
  23. * @var array
  24. */
  25. public $show_categories = array();
  26. /**
  27. * Item sales.
  28. *
  29. * @var array
  30. */
  31. private $item_sales = array();
  32. /**
  33. * Item sales and times.
  34. *
  35. * @var array
  36. */
  37. private $item_sales_and_times = array();
  38. /**
  39. * Constructor.
  40. */
  41. public function __construct() {
  42. if ( isset( $_GET['show_categories'] ) ) {
  43. $this->show_categories = is_array( $_GET['show_categories'] ) ? array_map( 'absint', $_GET['show_categories'] ) : array( absint( $_GET['show_categories'] ) );
  44. }
  45. }
  46. /**
  47. * Get all product ids in a category (and its children).
  48. *
  49. * @param int $category_id
  50. * @return array
  51. */
  52. public function get_products_in_category( $category_id ) {
  53. $term_ids = get_term_children( $category_id, 'product_cat' );
  54. $term_ids[] = $category_id;
  55. $product_ids = get_objects_in_term( $term_ids, 'product_cat' );
  56. return array_unique( apply_filters( 'woocommerce_report_sales_by_category_get_products_in_category', $product_ids, $category_id ) );
  57. }
  58. /**
  59. * Get the legend for the main chart sidebar.
  60. *
  61. * @return array
  62. */
  63. public function get_chart_legend() {
  64. if ( ! $this->show_categories ) {
  65. return array();
  66. }
  67. $legend = array();
  68. $index = 0;
  69. foreach ( $this->show_categories as $category ) {
  70. $category = get_term( $category, 'product_cat' );
  71. $total = 0;
  72. $product_ids = $this->get_products_in_category( $category->term_id );
  73. foreach ( $product_ids as $id ) {
  74. if ( isset( $this->item_sales[ $id ] ) ) {
  75. $total += $this->item_sales[ $id ];
  76. }
  77. }
  78. $legend[] = array(
  79. 'title' => sprintf( __( '%s sales in %s', 'woocommerce' ), '<strong>' . wc_price( $total ) . '</strong>', $category->name ),
  80. 'color' => isset( $this->chart_colours[ $index ] ) ? $this->chart_colours[ $index ] : $this->chart_colours[ 0 ],
  81. 'highlight_series' => $index
  82. );
  83. $index++;
  84. }
  85. return $legend;
  86. }
  87. /**
  88. * Output the report.
  89. */
  90. public function output_report() {
  91. $ranges = array(
  92. 'year' => __( 'Year', 'woocommerce' ),
  93. 'last_month' => __( 'Last Month', 'woocommerce' ),
  94. 'month' => __( 'This Month', 'woocommerce' ),
  95. '7day' => __( 'Last 7 Days', 'woocommerce' )
  96. );
  97. $this->chart_colours = array( '#3498db', '#34495e', '#1abc9c', '#2ecc71', '#f1c40f', '#e67e22', '#e74c3c', '#2980b9', '#8e44ad', '#2c3e50', '#16a085', '#27ae60', '#f39c12', '#d35400', '#c0392b' );
  98. $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day';
  99. if ( ! in_array( $current_range, array( 'custom', 'year', 'last_month', 'month', '7day' ) ) ) {
  100. $current_range = '7day';
  101. }
  102. $this->calculate_current_range( $current_range );
  103. // Get item sales data
  104. if ( $this->show_categories ) {
  105. $order_items = $this->get_order_report_data( array(
  106. 'data' => array(
  107. '_product_id' => array(
  108. 'type' => 'order_item_meta',
  109. 'order_item_type' => 'line_item',
  110. 'function' => '',
  111. 'name' => 'product_id'
  112. ),
  113. '_line_total' => array(
  114. 'type' => 'order_item_meta',
  115. 'order_item_type' => 'line_item',
  116. 'function' => 'SUM',
  117. 'name' => 'order_item_amount'
  118. ),
  119. 'post_date' => array(
  120. 'type' => 'post_data',
  121. 'function' => '',
  122. 'name' => 'post_date'
  123. ),
  124. ),
  125. 'group_by' => 'ID, product_id, post_date',
  126. 'query_type' => 'get_results',
  127. 'filter_range' => true
  128. ) );
  129. $this->item_sales = array();
  130. $this->item_sales_and_times = array();
  131. if ( is_array( $order_items ) ) {
  132. foreach ( $order_items as $order_item ) {
  133. switch ( $this->chart_groupby ) {
  134. case 'day' :
  135. $time = strtotime( date( 'Ymd', strtotime( $order_item->post_date ) ) ) * 1000;
  136. break;
  137. case 'month' :
  138. default :
  139. $time = strtotime( date( 'Ym', strtotime( $order_item->post_date ) ) . '01' ) * 1000;
  140. break;
  141. }
  142. $this->item_sales_and_times[ $time ][ $order_item->product_id ] = isset( $this->item_sales_and_times[ $time ][ $order_item->product_id ] ) ? $this->item_sales_and_times[ $time ][ $order_item->product_id ] + $order_item->order_item_amount : $order_item->order_item_amount;
  143. $this->item_sales[ $order_item->product_id ] = isset( $this->item_sales[ $order_item->product_id ] ) ? $this->item_sales[ $order_item->product_id ] + $order_item->order_item_amount : $order_item->order_item_amount;
  144. }
  145. }
  146. }
  147. include( WC()->plugin_path() . '/includes/admin/views/html-report-by-date.php' );
  148. }
  149. /**
  150. * Get chart widgets.
  151. *
  152. * @return array
  153. */
  154. public function get_chart_widgets() {
  155. return array(
  156. array(
  157. 'title' => __( 'Categories', 'woocommerce' ),
  158. 'callback' => array( $this, 'category_widget' )
  159. )
  160. );
  161. }
  162. /**
  163. * Output category widget.
  164. */
  165. public function category_widget() {
  166. $categories = get_terms( 'product_cat', array( 'orderby' => 'name' ) );
  167. ?>
  168. <form method="GET">
  169. <div>
  170. <select multiple="multiple" data-placeholder="<?php esc_attr_e( 'Select categories&hellip;', 'woocommerce' ); ?>" class="wc-enhanced-select" id="show_categories" name="show_categories[]" style="width: 205px;">
  171. <?php
  172. $r = array();
  173. $r['pad_counts'] = 1;
  174. $r['hierarchical'] = 1;
  175. $r['hide_empty'] = 1;
  176. $r['value'] = 'id';
  177. $r['selected'] = $this->show_categories;
  178. include_once( WC()->plugin_path() . '/includes/walkers/class-product-cat-dropdown-walker.php' );
  179. echo wc_walk_category_dropdown_tree( $categories, 0, $r );
  180. ?>
  181. </select>
  182. <a href="#" class="select_none"><?php _e( 'None', 'woocommerce' ); ?></a>
  183. <a href="#" class="select_all"><?php _e( 'All', 'woocommerce' ); ?></a>
  184. <input type="submit" class="submit button" value="<?php esc_attr_e( 'Show', 'woocommerce' ); ?>" />
  185. <input type="hidden" name="range" value="<?php if ( ! empty( $_GET['range'] ) ) echo esc_attr( $_GET['range'] ) ?>" />
  186. <input type="hidden" name="start_date" value="<?php if ( ! empty( $_GET['start_date'] ) ) echo esc_attr( $_GET['start_date'] ) ?>" />
  187. <input type="hidden" name="end_date" value="<?php if ( ! empty( $_GET['end_date'] ) ) echo esc_attr( $_GET['end_date'] ) ?>" />
  188. <input type="hidden" name="page" value="<?php if ( ! empty( $_GET['page'] ) ) echo esc_attr( $_GET['page'] ) ?>" />
  189. <input type="hidden" name="tab" value="<?php if ( ! empty( $_GET['tab'] ) ) echo esc_attr( $_GET['tab'] ) ?>" />
  190. <input type="hidden" name="report" value="<?php if ( ! empty( $_GET['report'] ) ) echo esc_attr( $_GET['report'] ) ?>" />
  191. </div>
  192. <script type="text/javascript">
  193. jQuery(function(){
  194. // Select all/none
  195. jQuery( '.chart-widget' ).on( 'click', '.select_all', function() {
  196. jQuery(this).closest( 'div' ).find( 'select option' ).attr( 'selected', 'selected' );
  197. jQuery(this).closest( 'div' ).find('select').change();
  198. return false;
  199. });
  200. jQuery( '.chart-widget').on( 'click', '.select_none', function() {
  201. jQuery(this).closest( 'div' ).find( 'select option' ).removeAttr( 'selected' );
  202. jQuery(this).closest( 'div' ).find('select').change();
  203. return false;
  204. });
  205. });
  206. </script>
  207. </form>
  208. <?php
  209. }
  210. /**
  211. * Output an export link.
  212. */
  213. public function get_export_button() {
  214. $current_range = ! empty( $_GET['range'] ) ? sanitize_text_field( $_GET['range'] ) : '7day';
  215. ?>
  216. <a
  217. href="#"
  218. download="report-<?php echo esc_attr( $current_range ); ?>-<?php echo date_i18n( 'Y-m-d', current_time('timestamp') ); ?>.csv"
  219. class="export_csv"
  220. data-export="chart"
  221. data-xaxes="<?php esc_attr_e( 'Date', 'woocommerce' ); ?>"
  222. data-groupby="<?php echo $this->chart_groupby; ?>"
  223. >
  224. <?php _e( 'Export CSV', 'woocommerce' ); ?>
  225. </a>
  226. <?php
  227. }
  228. /**
  229. * Get the main chart.
  230. *
  231. * @return string
  232. */
  233. public function get_main_chart() {
  234. global $wp_locale;
  235. if ( ! $this->show_categories ) {
  236. ?>
  237. <div class="chart-container">
  238. <p class="chart-prompt"><?php _e( '&larr; Choose a category to view stats', 'woocommerce' ); ?></p>
  239. </div>
  240. <?php
  241. } else {
  242. $chart_data = array();
  243. $index = 0;
  244. foreach ( $this->show_categories as $category ) {
  245. $category = get_term( $category, 'product_cat' );
  246. $product_ids = $this->get_products_in_category( $category->term_id );
  247. $category_chart_data = array();
  248. for ( $i = 0; $i <= $this->chart_interval; $i ++ ) {
  249. $interval_total = 0;
  250. switch ( $this->chart_groupby ) {
  251. case 'day' :
  252. $time = strtotime( date( 'Ymd', strtotime( "+{$i} DAY", $this->start_date ) ) ) * 1000;
  253. break;
  254. case 'month' :
  255. default :
  256. $time = strtotime( date( 'Ym', strtotime( "+{$i} MONTH", $this->start_date ) ) . '01' ) * 1000;
  257. break;
  258. }
  259. foreach ( $product_ids as $id ) {
  260. if ( isset( $this->item_sales_and_times[ $time ][ $id ] ) ) {
  261. $interval_total += $this->item_sales_and_times[ $time ][ $id ];
  262. }
  263. }
  264. $category_chart_data[] = array( $time, (float) wc_format_decimal( $interval_total, wc_get_price_decimals() ) );
  265. }
  266. $chart_data[ $category->term_id ]['category'] = $category->name;
  267. $chart_data[ $category->term_id ]['data'] = $category_chart_data;
  268. $index ++;
  269. }
  270. ?>
  271. <div class="chart-container">
  272. <div class="chart-placeholder main"></div>
  273. </div>
  274. <script type="text/javascript">
  275. var main_chart;
  276. jQuery(function(){
  277. var drawGraph = function( highlight ) {
  278. var series = [
  279. <?php
  280. $index = 0;
  281. foreach ( $chart_data as $data ) {
  282. $color = isset( $this->chart_colours[ $index ] ) ? $this->chart_colours[ $index ] : $this->chart_colours[0];
  283. $width = $this->barwidth / sizeof( $chart_data );
  284. $offset = ( $width * $index );
  285. $series = $data['data'];
  286. foreach ( $series as $key => $series_data ) {
  287. $series[ $key ][0] = $series_data[0] + $offset;
  288. }
  289. echo '{
  290. label: "' . esc_js( $data['category'] ) . '",
  291. data: jQuery.parseJSON( "' . json_encode( $series ) . '" ),
  292. color: "' . $color . '",
  293. bars: {
  294. fillColor: "' . $color . '",
  295. fill: true,
  296. show: true,
  297. lineWidth: 1,
  298. align: "center",
  299. barWidth: ' . $width * 0.75 . ',
  300. stack: false
  301. },
  302. ' . $this->get_currency_tooltip() . ',
  303. enable_tooltip: true,
  304. prepend_label: true
  305. },';
  306. $index++;
  307. }
  308. ?>
  309. ];
  310. if ( highlight !== 'undefined' && series[ highlight ] ) {
  311. highlight_series = series[ highlight ];
  312. highlight_series.color = '#9c5d90';
  313. if ( highlight_series.bars ) {
  314. highlight_series.bars.fillColor = '#9c5d90';
  315. }
  316. if ( highlight_series.lines ) {
  317. highlight_series.lines.lineWidth = 5;
  318. }
  319. }
  320. main_chart = jQuery.plot(
  321. jQuery('.chart-placeholder.main'),
  322. series,
  323. {
  324. legend: {
  325. show: false
  326. },
  327. grid: {
  328. color: '#aaa',
  329. borderColor: 'transparent',
  330. borderWidth: 0,
  331. hoverable: true
  332. },
  333. xaxes: [ {
  334. color: '#aaa',
  335. reserveSpace: true,
  336. position: "bottom",
  337. tickColor: 'transparent',
  338. mode: "time",
  339. timeformat: "<?php if ( $this->chart_groupby == 'day' ) echo '%d %b'; else echo '%b'; ?>",
  340. monthNames: <?php echo json_encode( array_values( $wp_locale->month_abbrev ) ); ?>,
  341. tickLength: 1,
  342. minTickSize: [1, "<?php echo $this->chart_groupby; ?>"],
  343. tickSize: [1, "<?php echo $this->chart_groupby; ?>"],
  344. font: {
  345. color: "#aaa"
  346. }
  347. } ],
  348. yaxes: [
  349. {
  350. min: 0,
  351. tickDecimals: 2,
  352. color: 'transparent',
  353. font: { color: "#aaa" }
  354. }
  355. ],
  356. }
  357. );
  358. jQuery('.chart-placeholder').resize();
  359. }
  360. drawGraph();
  361. jQuery('.highlight_series').hover(
  362. function() {
  363. drawGraph( jQuery(this).data('series') );
  364. },
  365. function() {
  366. drawGraph();
  367. }
  368. );
  369. });
  370. </script>
  371. <?php
  372. }
  373. }
  374. }