1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
<?php
namespace AutomateWoo;
/** * @class Conversions * @since 2.1 */ class Conversions {
/** * Max number of days that a purchase to be considered a conversion. * * @return int */ public static function get_conversion_window() { return absint( apply_filters( 'automatewoo_conversion_window', AW()->options()->conversion_window ) ); }
/** * Check if an order is a conversion and record it. * * @param int $order_id */ public static function check_order_for_conversion( $order_id ) {
$order = wc_get_order( Clean::id( $order_id ) ); if ( ! $order ) { return; }
$customer = Customer_Factory::get_by_order( $order ); if ( ! $customer ) { return; }
$conversion_window_end = aw_normalize_date( $order->get_date_created() ); // convert to UTC
if ( ! $conversion_window_end ) { return; }
$conversion_window_start = clone $conversion_window_end; $conversion_window_start->modify( ( -1 * self::get_conversion_window() ) . ' days' );
$logs = self::get_logs_by_customer( $customer, $conversion_window_start, $conversion_window_end ); if ( ! $logs ) { return; }
foreach ( $logs as $log ) { if ( self::is_valid_conversion( $order, $log ) ) { $order->update_meta_data( '_aw_conversion', $log->get_workflow_id() ); $order->update_meta_data( '_aw_conversion_log', $log->get_id() ); $order->save();
/** * Fires when a conversion is recorded for an order. * * @since 4.9.0 */ do_action( 'automatewoo/conversion/recorded', $order, $log );
break; // break loop here so that only one log/workflow gets the conversion } } }
/** * Get the logs for a customer that are within the conversion window. * * @param Customer $customer * @param DateTime $conversion_window_start * @param DateTime $conversion_window_end * @return Log[] */ public static function get_logs_by_customer( $customer, $conversion_window_start, $conversion_window_end ) { $query = new Log_Query(); $query->where( 'conversion_tracking_enabled', true ); $query->where_customer_or_legacy_user( $customer, true ); $query->where_date_between( $conversion_window_start, $conversion_window_end ); $query->set_ordering( 'date', 'DESC' );
return $query->get_results(); }
/** * Clear cached conversion data. * * @since 6.1.9 */ public static function clear_cache() { // Clear cached dashboard conversions. Cache::flush_group( 'dashboard' ); }
/** * Checks if order and log (i.e. sent workflow) is a valid conversion. * * @since 4.8.0 * * @param \WC_Order $order * @param Log $log * * @return bool */ protected static function is_valid_conversion( $order, $log ) { $is_valid = false;
// Check the log shows that it has been opened i.e. has tracking data if ( $log->get_meta( 'tracking_data' ) ) { $is_valid = true; }
// Exclude orders that were not created via the checkout from conversion tracking if ( $is_valid && ! self::is_order_created_via_checkout( $order ) ) { $is_valid = false; }
// Confirm that the workflow is still active and has conversion tracking enabled if ( $is_valid ) { $workflow = $log->get_workflow(); if ( ! $workflow || ! $workflow->is_active() || ! $workflow->is_conversion_tracking_enabled() ) { $is_valid = false; } }
return (bool) apply_filters( 'automatewoo/conversions/is_valid_conversion', $is_valid, $order, $log->get_workflow_id(), $log ); }
/** * Checks if the order was created via the checkout. * * We consider an order with the 'created_via' prop set to checkout or an order with a cart hash to be created via the checkout. * * This method should return false for automatic subscription renewals, rest API orders and POS orders. * * @since 4.8.0 * * @param \WC_Order $order * * @return bool */ protected static function is_order_created_via_checkout( $order ) { return 'checkout' === $order->get_created_via() || $order->get_cart_hash(); } }
|