PluginProbe
StoreEngine — Complete eCommerce Solution with Memberships, Licensing, Affiliates & More / 2.2.0
StoreEngine — Complete eCommerce Solution with Memberships, Licensing, Affiliates & More v2.2.0
2.3.0 2.2.0 2.1.1 2.1.0 2.0.0 1.10.0 1.9.1 1.9.0 1.2.1 1.2.2 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6.0 All 59 releases
storeengine / includes / classes / analytics.php

analytics.php in StoreEngine — Complete eCommerce Solution with Memberships, Licensing, Affiliates & More 2.2.0, at includes/classes/analytics.php

119 lines 5.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace StoreEngine\Classes;
4
5 use StoreEngine\Utils\Helper;
6
7 if ( ! defined( 'ABSPATH' ) ) {
8 exit;
9 }
10
11 class Analytics {
12
13 public function get_orders_totals( string $start, string $end ) {
14 global $wpdb;
15
16 // phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
17 return $wpdb->get_row( $wpdb->prepare(
18 "SELECT
19 COUNT(*) as total_orders,
20 SUM(total_amount) as total_sales,
21 SUM(tax_amount) as total_tax
22 FROM
23 {$wpdb->prefix}storeengine_orders
24 WHERE
25 date_created_gmt BETWEEN %s AND %s AND type = %s AND status IN {$this->get_paid_statuses()}",
26 $start, $end, 'order'
27 ) );
28 // phpcs:enable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
29 }
30
31 public function get_total_refunds( string $start, string $end ) {
32 global $wpdb;
33
34 // phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
35 return $wpdb->get_row( $wpdb->prepare(
36 "SELECT
37 ABS(SUM(o.total_amount)) as total_refunds
38 FROM
39 {$wpdb->prefix}storeengine_orders o
40 JOIN {$wpdb->prefix}storeengine_orders co ON o.parent_order_id = co.id
41 WHERE
42 co.date_created_gmt BETWEEN %s AND %s AND o.type = %s AND co.status in {$this->get_paid_statuses()}",
43 $start, $end, 'refund_order'
44 ) );
45 // phpcs:enable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
46 }
47
48 public function get_product_sold( string $start, string $end ) {
49 global $wpdb;
50
51 // phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
52 return $wpdb->get_row( $wpdb->prepare(
53 "SELECT SUM(p.product_qty) as total_products_sold
54 FROM {$wpdb->prefix}storeengine_orders o
55 JOIN {$wpdb->prefix}storeengine_order_product_lookup p ON p.order_id = o.id
56 WHERE o.date_created_gmt BETWEEN %s AND %s AND o.type = %s AND o.status IN {$this->get_paid_statuses()}",
57 $start, $end, 'order'
58 ) );
59 // phpcs:enable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
60 }
61
62 public function get_top_products(): array {
63 global $wpdb;
64
65 // phpcs:disable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
66 $products = $wpdb->get_results(
67 "SELECT op.product_id,
68 SUM(op.product_qty) AS total_sales,
69 p.post_title AS product_name,
70 pm1.meta_value AS thumbnail,
71 pm2.meta_value AS gallery,
72 SUM(op.product_net_revenue) AS total_net_revenue
73 FROM {$wpdb->prefix}storeengine_order_product_lookup op
74 INNER JOIN {$wpdb->prefix}storeengine_orders o ON o.id = op.order_id AND o.status IN {$this->get_paid_statuses()}
75 INNER JOIN $wpdb->posts p ON p.ID = op.product_id
76 LEFT JOIN $wpdb->postmeta pm1 ON pm1.post_id = op.product_id AND pm1.meta_key = '_thumbnail_id'
77 LEFT JOIN $wpdb->postmeta pm2 ON pm2.post_id = op.product_id AND pm2.meta_key = '_storeengine_product_gallery_ids'
78 GROUP BY op.product_id, p.post_title
79 ORDER BY total_sales DESC
80 LIMIT 5" );
81 // phpcs:enable PluginCheck.Security.DirectDB.UnescapedDBParameter, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared
82 $top_products = [];
83
84
85 foreach ( $products as $product ) {
86 if ( ! $product->thumbnail && $product->gallery ) {
87 $gallery = maybe_unserialize( $product->gallery );
88 if ( ! empty( $gallery ) && is_array( $gallery ) ) {
89 $product->thumbnail = $gallery[0];
90 }
91 }
92
93 $top_products[] = [
94 'product_id' => (int) $product->product_id,
95 'product_name' => $product->product_name,
96 'product_image' => $product->thumbnail ? wp_get_attachment_image_url( $product->thumbnail ) : null,
97 'total_sales' => (int) $product->total_sales,
98 'total_net_revenue' => (float) $product->total_net_revenue,
99 ];
100 }
101
102 return $top_products;
103 }
104
105 /**
106 * @return string
107 */
108 private function get_paid_statuses(): string {
109 global $wpdb;
110
111 $paid_statuses = Helper::get_order_paid_statuses();
112 $placeholders = array_fill(0, count($paid_statuses), '%s');
113 $placeholders = '(' . implode(',', $placeholders) . ')';
114
115 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared -- Sanitizing dynamic range of value.
116 return $wpdb->prepare($placeholders, $paid_statuses);
117 }
118 }
119