PluginProbe
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant / 2.3.2
Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant v2.3.2
2.3.2 2.3.1 2.3.0 2.2.8 2.2.7 trunk 1.10.0 1.10.1 1.10.2 1.10.3 1.10.4 1.10.5 1.11.0 1.11.1 1.11.2 1.6 1.7 1.8 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 1.9.10 1.9.11 All 60 releases
merchant / inc / analytics / class-merchant-analytics-data-ajax.php

class-merchant-analytics-data-ajax.php in Product Labels, Quick View, Buy Now, Pre-Orders, Frequently Bought Together & More for WooCommerce – Merchant 2.3.2, at inc/analytics/class-merchant-analytics-data-ajax.php

386 lines 12.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // Exit if accessed directly.
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit;
6 }
7
8 /**
9 * Class Merchant_Analytics_Data
10 *
11 * This class is responsible for providing ajax hooks for analytics.
12 */
13 class Merchant_Analytics_Data_Ajax {
14 /**
15 * The single class instance.
16 *
17 * @var Merchant_Analytics_Data_Ajax|null
18 */
19 private static $instance = null;
20
21 /**
22 * @var Merchant_Analytics_Data_Reports
23 */
24 private $reports;
25
26 /**
27 * Constructor.
28 */
29 private function __construct() {
30 $this->reports = new Merchant_Analytics_Data_Reports();
31 }
32
33 /**
34 * Get the single class instance.
35 *
36 * @return Merchant_Analytics_Data_Ajax|null
37 */
38 public static function instance() {
39 if ( is_null( self::$instance ) ) {
40 self::$instance = new self();
41 }
42
43 return self::$instance;
44 }
45
46 /**
47 * Load WordPress hooks.
48 */
49 public function load_hooks() {
50 add_action( 'wp_ajax_merchant_get_revenue_chart_data', array( $this, 'get_revenue_chart_data' ) );
51 add_action( 'wp_ajax_merchant_get_avg_order_value_chart_data', array( $this, 'get_aov_chart_data' ) );
52 add_action( 'wp_ajax_merchant_get_analytics_cards_data', array( $this, 'get_analytics_cards_data' ) );
53 add_action( 'wp_ajax_merchant_get_top_performing_campaigns_table_data', array( $this, 'get_analytics_table_data' ) );
54 add_action( 'wp_ajax_merchant_get_all_campaigns_table_data', array( $this, 'get_all_campaigns_table_data' ) );
55 add_action( 'wp_ajax_merchant_get_impressions_chart_data', array( $this, 'get_impressions_chart_data' ) );
56 add_action( 'wp_ajax_merchant_update_campaign_status', array( $this, 'update_campaign_status' ) );
57 }
58
59 /**
60 * Get revenue chart data.
61 */
62 public function get_revenue_chart_data() {
63 // nonce verification.
64 check_ajax_referer( 'merchant', 'nonce' );
65
66 $this->verify_capability();
67
68 try {
69 // Get the date ranges.
70 $start_date = isset( $_GET['start_date'] ) ? sanitize_text_field( wp_unslash( $_GET['start_date'] ) ) : '';
71 $end_date = isset( $_GET['end_date'] ) ? sanitize_text_field( wp_unslash( $_GET['end_date'] ) ) : '';
72
73 if ( $start_date === '' || $end_date === '' ) {
74 wp_send_json_error( __( 'Invalid date range.', 'merchant' ) );
75 }
76
77 wp_send_json_success( $this->reports->get_revenue_chart_report( $start_date, $end_date ) );
78 } catch ( Exception $e ) {
79 wp_send_json_error( $e->getMessage() );
80 }
81 }
82
83 /**
84 * Get average order value chart data.
85 */
86 public function get_aov_chart_data() {
87 // nonce verification.
88 check_ajax_referer( 'merchant', 'nonce' );
89
90 $this->verify_capability();
91
92 try {
93 // Get the date ranges.
94 $start_date = isset( $_GET['start_date'] ) ? sanitize_text_field( wp_unslash( $_GET['start_date'] ) ) : '';
95 $end_date = isset( $_GET['end_date'] ) ? sanitize_text_field( wp_unslash( $_GET['end_date'] ) ) : '';
96
97 if ( $start_date === '' || $end_date === '' ) {
98 wp_send_json_error( __( 'Invalid date range.', 'merchant' ) );
99 }
100
101 wp_send_json_success( $this->reports->get_aov_chart_report( $start_date, $end_date ) );
102 } catch ( Exception $e ) {
103 wp_send_json_error( $e->getMessage() );
104 }
105 }
106
107 /**
108 * Get analytics cards data.
109 */
110 public function get_analytics_cards_data() {
111 // nonce verification.
112 check_ajax_referer( 'merchant', 'nonce' );
113
114 $this->verify_capability();
115
116 try {
117 $start_date = isset( $_GET['start_date'] ) ? sanitize_text_field( wp_unslash( $_GET['start_date'] ) ) : '';
118 $end_date = isset( $_GET['end_date'] ) ? sanitize_text_field( wp_unslash( $_GET['end_date'] ) ) : '';
119 $compare_start_date = isset( $_GET['compare_start_date'] ) ? sanitize_text_field( wp_unslash( $_GET['compare_start_date'] ) ) : '';
120 $compare_end_date = isset( $_GET['compare_end_date'] ) ? sanitize_text_field( wp_unslash( $_GET['compare_end_date'] ) ) : '';
121
122 if ( $start_date === '' || $end_date === '' || $compare_start_date === '' || $compare_end_date === '' ) {
123 wp_send_json_error( __( 'Invalid date ranges.', 'merchant' ) );
124 }
125 $start_range = array(
126 'start' => $start_date,
127 'end' => $end_date,
128 );
129 $compare_range = array(
130 'start' => $compare_start_date,
131 'end' => $compare_end_date,
132 );
133 $data = array();
134 $added_revenue = $this->reports->get_reveue_card_report( $start_range, $compare_range );
135 $added_orders = $this->reports->get_total_new_orders_card_report( $start_range, $compare_range );
136 $aov_rate = $this->reports->get_aov_card_report( $start_range, $compare_range );
137 $conversion_rate = $this->reports->get_conversion_rate_card_report( $start_range, $compare_range );
138 $impressions = $this->reports->get_impressions_card_report( $start_range, $compare_range );
139
140 $overview_data = array(
141 'cards' => array(
142 'revenue' => array(
143 'title' => __( 'Added revenue', 'merchant' ), // Raw string
144 'value' => wc_price( $added_revenue['revenue_second_period'] ), // Raw value
145 'change' => array(
146 'value' => wc_format_decimal( $added_revenue['revenue_change'][0], 2 ) . '%', // Raw value
147 'class' => $added_revenue['revenue_change'][1], // Raw value
148 ),
149 'tooltip' => __( 'Revenue added by Merchant.', 'merchant' ), // Raw string
150 ),
151 'total-orders' => array(
152 'title' => __( 'Total orders', 'merchant' ), // Raw string
153 'value' => $added_orders['orders_second_period'], // Raw value
154 'change' => array(
155 'value' => wc_format_decimal( $added_orders['orders_change'][0], 2 ) . '%', // Raw value
156 'class' => $added_orders['orders_change'][1], // Raw value
157 ),
158 'tooltip' => __( 'Total number of orders involving Merchant.', 'merchant' ), // Raw string
159 ),
160 'aov' => array(
161 'title' => __( 'Average order value', 'merchant' ), // Raw string
162 'value' => wc_price( $aov_rate['aov_second_period'] ), // Raw value
163 'change' => array(
164 'value' => wc_format_decimal( $aov_rate['change'][0], 2 ) . '%', // Raw value
165 'class' => $aov_rate['change'][1], // Raw value
166 ),
167 'tooltip' => __( 'Average order value for Merchant orders.', 'merchant' ), // Raw string
168 ),
169 'conversion-rate' => array(
170 'title' => __( 'Conversion rate', 'merchant' ), // Raw string
171 'value' => wc_format_decimal( $conversion_rate['conversion_second_period'], 2 ) . '%', // Raw value
172 'change' => array(
173 'value' => wc_format_decimal( $conversion_rate['change'][0], 2 ) . '%', // Raw value
174 'class' => $conversion_rate['change'][1], // Raw value
175 ),
176 'tooltip' => __( 'The percentage of Merchant offer viewers who made a purchase.', 'merchant' ), // Raw string
177 ),
178 'impressions' => array(
179 'title' => __( 'Impressions', 'merchant' ), // Raw string
180 'value' => $impressions['impressions_second_period'], // Raw value
181 'change' => array(
182 'value' => wc_format_decimal( $impressions['change'][0], 2 ) . '%', // Raw value
183 'class' => $impressions['change'][1], // Raw value
184 ),
185 'tooltip' => __( 'The number of times Merchant offers were seen.', 'merchant' ), // Raw string
186 ),
187 ),
188 );
189
190 ob_start();
191 require_once MERCHANT_DIR . 'admin/components/analytics-overview-cards.php';
192 $overview_html = ob_get_clean();
193
194 wp_send_json_success( $overview_html );
195 } catch ( Exception $e ) {
196 wp_send_json_error( $e->getMessage() );
197 }
198 }
199
200 /**
201 * Get analytics table data.
202 */
203 public function get_analytics_table_data() {
204 // nonce verification.
205 check_ajax_referer( 'merchant', 'nonce' );
206
207 try {
208 $start_date = isset( $_GET['start_date'] ) ? sanitize_text_field( wp_unslash( $_GET['start_date'] ) ) : '';
209 $end_date = isset( $_GET['end_date'] ) ? sanitize_text_field( wp_unslash( $_GET['end_date'] ) ) : '';
210
211 if ( $start_date === '' || $end_date === '' ) {
212 wp_send_json_error( __( 'Invalid date ranges.', 'merchant' ) );
213 }
214 $date_range = array(
215 'start' => $start_date,
216 'end' => $end_date,
217 );
218 $data = $this->reports->get_top_performing_campaigns( $date_range );
219
220 $data = array_map( static function ( $item ) {
221 $item['revenue'] = wc_price( $item['revenue'] );
222
223 return $item;
224 }, $data );
225 wp_send_json_success( $data );
226 } catch ( Exception $e ) {
227 wp_send_json_error( $e->getMessage() );
228 }
229 }
230
231 /**
232 * Get analytics table data.
233 */
234 public function get_all_campaigns_table_data() {
235 // nonce verification.
236 check_ajax_referer( 'merchant', 'nonce' );
237
238 $this->verify_capability();
239
240 try {
241 $start_date = isset( $_GET['start_date'] ) ? sanitize_text_field( wp_unslash( $_GET['start_date'] ) ) : '';
242 $end_date = isset( $_GET['end_date'] ) ? sanitize_text_field( wp_unslash( $_GET['end_date'] ) ) : '';
243
244 if ( $start_date === '' || $end_date === '' ) {
245 wp_send_json_error( __( 'Invalid date ranges.', 'merchant' ) );
246 }
247 $start_range = array(
248 'start' => $start_date,
249 'end' => $end_date,
250 );
251 $data = $this->reports->get_all_campaigns( $start_range );
252
253 $data = array_map( static function ( $item ) {
254 $item['revenue'] = wc_price( $item['revenue'] ?? '' );
255
256 return $item;
257 }, $data );
258 wp_send_json_success( $data );
259 } catch ( Exception $e ) {
260 wp_send_json_error( $e->getMessage() );
261 }
262 }
263
264 /**
265 * Get impressions chart data.
266 */
267 public function get_impressions_chart_data() {
268 // nonce verification.
269 check_ajax_referer( 'merchant', 'nonce' );
270
271 $this->verify_capability();
272
273 try {
274 // Get the date ranges.
275 $start_date = isset( $_GET['start_date'] ) ? sanitize_text_field( wp_unslash( $_GET['start_date'] ) ) : '';
276 $end_date = isset( $_GET['end_date'] ) ? sanitize_text_field( wp_unslash( $_GET['end_date'] ) ) : '';
277
278 if ( $start_date === '' || $end_date === '' ) {
279 wp_send_json_error( __( 'Invalid date range.', 'merchant' ) );
280 }
281
282 wp_send_json_success( $this->reports->get_impressions_chart_report( $start_date, $end_date ) );
283 } catch ( Exception $e ) {
284 wp_send_json_error( $e->getMessage() );
285 }
286 }
287
288 /**
289 * Update campaign status.
290 *
291 * @return void
292 */
293 public function update_campaign_status() {
294 check_ajax_referer( 'merchant', 'nonce' );
295
296 $this->verify_capability();
297
298 $campaign_data = $_POST['campaign_data'] ?? array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
299
300 if ( empty( $campaign_data ) ) {
301 wp_send_json_error( array( 'message' => esc_html__( 'No campaigns found.', 'merchant' ) ), 400 );
302 }
303
304 // Get current options
305 $db_options = get_option( 'merchant', array() );
306
307 if ( empty( $db_options ) ) {
308 wp_send_json_error( array( 'message' => esc_html__( 'No campaigns found.', 'merchant' ) ), 400 );
309 }
310
311 $should_update = false;
312 $new_status = '';
313
314 foreach ( $campaign_data as $module_id => $option ) {
315 if ( ! is_string( $module_id ) || empty( $module_id ) ) {
316 continue;
317 }
318
319 $campaign_key = sanitize_text_field( $option['campaign_key'] ?? '' );
320 $campaigns = $option['campaigns'] ?? array();
321
322 if ( empty( $campaign_key ) || empty( $campaigns ) ) {
323 continue;
324 }
325
326 foreach ( $campaigns as $index => $campaign ) {
327 $campaign_id = $campaign['campaign_id'] ?? null;
328 $status = sanitize_text_field( $campaign['status'] ?? '' );
329
330 if ( $campaign_id === null || ! in_array( $status, array( 'active', 'inactive' ), true ) ) {
331 continue;
332 }
333
334 // Check if the campaign exists in the database.
335 if ( isset( $db_options[ $module_id ][ $campaign_key ] ) ) {
336 $db_campaigns = &$db_options[ $module_id ][ $campaign_key ];
337
338 foreach ( $db_campaigns as &$item ) {
339 if ( isset( $item['flexible_id'] ) && $item['flexible_id'] === $campaign_id ) {
340 if ( $status === 'active' ) {
341 $item['campaign_status'] = 'active';
342 } else {
343 $item['campaign_status'] = 'inactive';
344 }
345 $new_status = $status;
346 $should_update = true;
347 }
348 }
349 }
350 }
351 }
352
353 if ( $should_update ) {
354 $updated = update_option( 'merchant', $db_options );
355 if ( $updated ) {
356 wp_send_json_success(
357 array(
358 'status' => $new_status,
359 'message' => esc_html__( 'Campaign updated successfully.', 'merchant' ),
360 )
361 );
362 }
363 }
364
365 wp_send_json_error( array( 'message' => esc_html__( 'No campaigns were updated.', 'merchant' ) ) );
366 }
367
368 /**
369 * Verify capability.
370 */
371 private function verify_capability() {
372 /**
373 * Filter to verify capability.
374 *
375 * @param bool $verify_capability Default is true.
376 *
377 * @since 1.10.0
378 */
379 if ( apply_filters( 'merchant_analytics_data_ajax_verify_capability', true ) && ! current_user_can( 'manage_options' ) ) {
380 wp_send_json_error( esc_html__( 'You are not allowed to do this.', 'merchant' ), 403 );
381 }
382 }
383 }
384
385 Merchant_Analytics_Data_Ajax::instance()->load_hooks();
386