PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.14.1
Independent Analytics – WordPress Analytics Plugin v2.14.1
2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / IAWP / Ecommerce / WooCommerce_Order.php
independent-analytics / IAWP / Ecommerce Last commit date
EDD_Order.php 1 year ago Fluent_Cart_Order.php 9 months ago PMPro_Order.php 1 year ago SureCart_Event_Sync_Job.php 1 year ago SureCart_Order.php 1 year ago SureCart_Store.php 1 year ago WooCommerce_Order.php 7 months ago WooCommerce_Status_Manager.php 1 year ago
WooCommerce_Order.php
213 lines
1 <?php
2
3 namespace IAWP\Ecommerce;
4
5 use IAWP\Illuminate_Builder;
6 use IAWP\Models\Visitor;
7 use IAWP\Query;
8 /** @internal */
9 class WooCommerce_Order
10 {
11 private $order_id;
12 private $status;
13 private $total;
14 private $total_refunded;
15 private $total_refunds;
16 private $is_discounted;
17 /**
18 * @param int $order_id WooCommerce order ID
19 */
20 public function __construct(int $order_id)
21 {
22 $order = wc_get_order($order_id);
23 // Total based on order currency, not shop currency
24 $total = \intval(\round($order->get_total() * 100));
25 // Refund amount based on order currency, not shop currency
26 $total_refunded = \intval(\round(\floatval($order->get_total_refunded()) * 100));
27 [$total, $total_refunded] = $this->convert_to_base_currency($order, $total, $total_refunded);
28 $this->order_id = $order_id;
29 $this->status = $order->get_status();
30 $this->total = $total;
31 $this->total_refunded = $total_refunded;
32 $this->total_refunds = \count($order->get_refunds());
33 $this->is_discounted = $this->is_discounted_order($order);
34 }
35 public function insert() : void
36 {
37 $visitor = Visitor::fetch_current_visitor();
38 if (!$visitor->has_recorded_session()) {
39 return;
40 }
41 $orders_table = Query::get_table_name(Query::ORDERS);
42 Illuminate_Builder::new()->from($orders_table)->insertOrIgnore(['is_included_in_analytics' => (new \IAWP\Ecommerce\WooCommerce_Status_Manager())->is_tracked_status($this->status), 'woocommerce_order_id' => $this->order_id, 'woocommerce_order_status' => $this->status, 'view_id' => $visitor->most_recent_view_id(), 'initial_view_id' => $visitor->most_recent_initial_view_id(), 'total' => $this->total, 'total_refunded' => $this->total_refunded, 'total_refunds' => $this->total_refunds, 'is_discounted' => $this->is_discounted, 'created_at' => (new \DateTime())->format('Y-m-d H:i:s')]);
43 }
44 public function update() : void
45 {
46 $orders_table = Query::get_table_name(Query::ORDERS);
47 Illuminate_Builder::new()->from($orders_table)->where('woocommerce_order_id', '=', $this->order_id)->update(['is_included_in_analytics' => (new \IAWP\Ecommerce\WooCommerce_Status_Manager())->is_tracked_status($this->status), 'woocommerce_order_status' => $this->status, 'total' => $this->total, 'total_refunded' => $this->total_refunded, 'total_refunds' => $this->total_refunds, 'is_discounted' => $this->is_discounted]);
48 }
49 private function convert_to_base_currency($order, $total, $total_refunded)
50 {
51 $exchange_rate = $this->exchange_rate($order);
52 if (\is_float($exchange_rate)) {
53 // Exchange rate is from shop currency to order currency (divide)
54 $total = \intval(\round($total / $exchange_rate));
55 $total_refunded = \intval(\round($total_refunded / $exchange_rate));
56 }
57 return [$total, $total_refunded];
58 }
59 private function is_discounted_order($order) : bool
60 {
61 if ($order->get_total_discount() > 0) {
62 return \true;
63 }
64 foreach ($order->get_items() as $item) {
65 if ($item->get_product()->is_on_sale()) {
66 return \true;
67 }
68 }
69 return \false;
70 }
71 private function exchange_rate($order) : ?float
72 {
73 $rate_getters = [fn() => $this->aelia_exchange_rate($order), fn() => $this->wpml_exchange_rate($order), fn() => $this->curcy_exchange_rate($order), fn() => $this->pbc_exchange_rate($order), fn() => $this->yith_exchange_rate($order), fn() => $this->woopayments_exchange_rate($order), fn() => $this->yay_currency_exchange_rate($order)];
74 foreach ($rate_getters as $rate_getter) {
75 $exchange_rate = $rate_getter();
76 if (\is_float($exchange_rate)) {
77 return $exchange_rate;
78 }
79 }
80 return null;
81 }
82 private function aelia_exchange_rate($order) : ?float
83 {
84 $exchange_rate = $order->get_meta('_base_currency_exchange_rate');
85 if (!\is_numeric($exchange_rate)) {
86 return null;
87 }
88 return 1 / \floatval($exchange_rate);
89 }
90 private function wpml_exchange_rate($order) : ?float
91 {
92 $currency_code = $order->get_currency();
93 if (!\is_plugin_active('woocommerce-multilingual/wpml-woocommerce.php')) {
94 return null;
95 }
96 $wcml_options = \get_option('_wcml_settings');
97 if (!\is_array($wcml_options)) {
98 return null;
99 }
100 if (!\array_key_exists('currency_options', $wcml_options)) {
101 return null;
102 }
103 if (!\is_array($wcml_options['currency_options']) || !\array_key_exists($currency_code, $wcml_options['currency_options'])) {
104 return null;
105 }
106 if (!\is_array($wcml_options['currency_options'][$currency_code]) || !\array_key_exists('rate', $wcml_options['currency_options'][$currency_code])) {
107 return null;
108 }
109 $exchange_rate = \floatval($wcml_options['currency_options'][$currency_code]['rate']);
110 // Was there an error parsing value as float?
111 if ($exchange_rate === 0.0) {
112 return null;
113 }
114 return $exchange_rate;
115 }
116 private function curcy_exchange_rate($order) : ?float
117 {
118 $rates = $order->get_meta('wmc_order_info');
119 $currency = $order->get_currency();
120 if (!\is_array($rates)) {
121 return null;
122 }
123 $rate = $rates[$currency]['rate'] ?? null;
124 if (!\is_numeric($rate)) {
125 return null;
126 }
127 return (float) $rate;
128 }
129 private function pbc_exchange_rate($order) : ?float
130 {
131 $exchange_rate = $order->get_meta('_wcpbc_base_exchange_rate');
132 if (!\is_numeric($exchange_rate)) {
133 return null;
134 }
135 return 1 / \floatval($exchange_rate);
136 }
137 private function yith_exchange_rate($order) : ?float
138 {
139 $currency = $order->get_currency();
140 $is_yith_order = !empty($order->get_meta('_yith_wcmcs_default_currency_on_creation'));
141 if (!$is_yith_order) {
142 return null;
143 }
144 try {
145 $rates = \yith_wcmcs_get_currencies();
146 if (!\array_key_exists($currency, $rates)) {
147 return null;
148 }
149 return $rates[$currency]->get_rate('raw');
150 } catch (\Throwable $e) {
151 return null;
152 }
153 }
154 private function woopayments_exchange_rate($order) : ?float
155 {
156 $rate = $order->get_meta('_wcpay_multi_currency_order_exchange_rate');
157 if (!\is_numeric($rate)) {
158 return null;
159 }
160 return (float) $rate;
161 }
162 private function yay_currency_exchange_rate($order) : ?float
163 {
164 $rate = $order->get_meta('yay_currency_order_rate');
165 if (!\is_numeric($rate)) {
166 return null;
167 }
168 return (float) $rate;
169 }
170 public static function register_hooks()
171 {
172 // Required for block checkout
173 \add_action('woocommerce_store_api_checkout_order_processed', function ($order) {
174 try {
175 $woocommerce_order = new self($order->get_id());
176 $woocommerce_order->insert();
177 } catch (\Throwable $e) {
178 \error_log('Independent Analytics was unable to track the analytics for a WooCommerce order. Please report this error to Independent Analytics. The error message is below.');
179 \error_log($e->getMessage());
180 }
181 });
182 // Required for shortcode checkout
183 \add_action('woocommerce_checkout_order_created', function ($order) {
184 try {
185 $woocommerce_order = new self($order->get_id());
186 $woocommerce_order->insert();
187 } catch (\Throwable $e) {
188 \error_log('Independent Analytics was unable to track the analytics for a WooCommerce order. Please report this error to Independent Analytics. The error message is below.');
189 \error_log($e->getMessage());
190 }
191 });
192 \add_action('woocommerce_order_status_changed', function ($order_id) {
193 try {
194 $woocommerce_order = new self($order_id);
195 $woocommerce_order->update();
196 } catch (\Throwable $e) {
197 \error_log('Independent Analytics was unable to track the analytics for a WooCommerce order. Please report this error to Independent Analytics. The error message is below.');
198 \error_log($e->getMessage());
199 }
200 });
201 // Captures a partial refund, something that woocommerce_order_status_changed will not do
202 \add_action('woocommerce_order_refunded', function ($order_id) {
203 try {
204 $woocommerce_order = new self($order_id);
205 $woocommerce_order->update();
206 } catch (\Throwable $e) {
207 \error_log('Independent Analytics was unable to track the analytics for a WooCommerce order. Please report this error to Independent Analytics. The error message is below.');
208 \error_log($e->getMessage());
209 }
210 });
211 }
212 }
213