Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
89.19% |
33 / 37 |
|
33.33% |
1 / 3 |
CRAP | |
0.00% |
0 / 1 |
Order | |
89.19% |
33 / 37 |
|
33.33% |
1 / 3 |
10.13 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
schedule_check_for_transactions | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
4 | |||
unschedule_check_for_transactions | |
91.67% |
22 / 24 |
|
0.00% |
0 / 1 |
5.01 |
1 | <?php |
2 | /** |
3 | * Constants for order meta keys. |
4 | * |
5 | * @package brianhenryie/bh-wp-bitcoin-gateway |
6 | */ |
7 | |
8 | namespace BrianHenryIE\WP_Bitcoin_Gateway\WooCommerce; |
9 | |
10 | use ActionScheduler; |
11 | use BrianHenryIE\WP_Bitcoin_Gateway\Action_Scheduler\Background_Jobs; |
12 | use BrianHenryIE\WP_Bitcoin_Gateway\API\Addresses\Bitcoin_Wallet; |
13 | use BrianHenryIE\WP_Bitcoin_Gateway\API\Model\Bitcoin_Order; |
14 | use BrianHenryIE\WP_Bitcoin_Gateway\API_Interface; |
15 | use Psr\Log\LoggerAwareTrait; |
16 | use Psr\Log\LoggerInterface; |
17 | use WC_Order; |
18 | |
19 | /** |
20 | * Defines constants for metakeys. |
21 | * Handles order status change events, to schedule/unschedule background tasks. |
22 | */ |
23 | class Order { |
24 | use LoggerAwareTrait; |
25 | |
26 | /** |
27 | * Used to check is the gateway a Bitcoin gateway. |
28 | */ |
29 | protected API_Interface $api; |
30 | |
31 | const BITCOIN_ADDRESS_META_KEY = 'bh_wp_bitcoin_gateway_address'; |
32 | |
33 | const EXCHANGE_RATE_AT_TIME_OF_PURCHASE_META_KEY = 'bh_wp_bitcoin_gateway_exchange_rate_at_time_of_purchase'; |
34 | |
35 | const ORDER_TOTAL_BITCOIN_AT_TIME_OF_PURCHASE_META_KEY = 'bh_wp_bitcoin_gateway_bitcoin_total_at_time_of_purchase'; |
36 | |
37 | const BITCOIN_AMOUNT_RECEIVED_META_KEY = 'bh_wp_bitcoin_gateway_bitcoin_amount_received'; |
38 | |
39 | const LAST_CHECKED_META_KEY = 'bh_wp_bitcoin_gateway_last_checked_time'; |
40 | |
41 | /** |
42 | * Constructor. |
43 | * |
44 | * @param API_Interface $api The main plugin functions. |
45 | * @param LoggerInterface $logger A PSR logger. |
46 | */ |
47 | public function __construct( API_Interface $api, LoggerInterface $logger ) { |
48 | $this->setLogger( $logger ); |
49 | $this->api = $api; |
50 | } |
51 | |
52 | /** |
53 | * When an order's status is set to "on-hold", schedule a background job to check for payments. |
54 | * |
55 | * @hooked woocommerce_order_status_changed |
56 | * @see WC_Order::status_transition() |
57 | * |
58 | * @param int $order_id The id of the order whose status has changed. |
59 | * @param string $status_from The old status. |
60 | * @param string $status_to The new status. |
61 | */ |
62 | public function schedule_check_for_transactions( int $order_id, string $status_from, string $status_to ): void { |
63 | |
64 | if ( 'on-hold' !== $status_to ) { |
65 | return; |
66 | } |
67 | |
68 | if ( ! $this->api->is_order_has_bitcoin_gateway( $order_id ) ) { |
69 | return; |
70 | } |
71 | |
72 | // Schedule background check for payment. |
73 | $hook = Background_Jobs::CHECK_UNPAID_ORDER_HOOK; |
74 | $args = array( 'order_id' => $order_id ); |
75 | |
76 | if ( ! as_has_scheduled_action( $hook, $args ) ) { |
77 | $timestamp = time() + ( 10 * MINUTE_IN_SECONDS ); |
78 | $recurring_seconds = ( 10 * MINUTE_IN_SECONDS ); |
79 | $this->logger->debug( "New order created, `shop_order:{$order_id}`, scheduling background job to check for payments" ); |
80 | as_schedule_recurring_action( $timestamp, $recurring_seconds, $hook, $args ); |
81 | } |
82 | } |
83 | |
84 | /** |
85 | * When an order's status changes away from "pending" and "on-hold", cancel the scheduled background. |
86 | * |
87 | * E.g. when the order is paid or canceled. |
88 | * |
89 | * @hooked woocommerce_order_status_changed |
90 | * @see WC_Order::status_transition() |
91 | * |
92 | * @param int $order_id The id of the order whose status has changed. |
93 | * @param string $status_from The old status. |
94 | * @param string $status_to The new status. |
95 | */ |
96 | public function unschedule_check_for_transactions( int $order_id, string $status_from, string $status_to ): void { |
97 | |
98 | if ( in_array( $status_to, array( 'pending', 'on-hold' ), true ) ) { |
99 | return; |
100 | } |
101 | |
102 | if ( ! $this->api->is_order_has_bitcoin_gateway( $order_id ) ) { |
103 | return; |
104 | } |
105 | |
106 | if ( empty( $status_to ) ) { |
107 | $status_to = 'trash?'; |
108 | } |
109 | |
110 | $context = array( |
111 | 'order_id' => $order_id, |
112 | 'status_from' => $status_from, |
113 | 'status_to' => $status_to, |
114 | ); |
115 | |
116 | $hook = Background_Jobs::CHECK_UNPAID_ORDER_HOOK; |
117 | $args = array( 'order_id' => $order_id ); |
118 | $query = array( |
119 | 'hook' => $hook, |
120 | 'args' => $args, |
121 | ); |
122 | |
123 | $context['action_scheduler_query'] = $query; |
124 | |
125 | $actions = as_get_scheduled_actions( $query ); |
126 | if ( ! empty( $actions ) ) { |
127 | $action_id = array_key_first( $actions ); |
128 | $this->logger->debug( "`shop_order:{$order_id}` status changed from $status_from to $status_to, running `as_unschedule_all_actions` for check_unpaid_order job, action_id $action_id.", $context ); |
129 | as_unschedule_all_actions( $hook, $args ); |
130 | } else { |
131 | $this->logger->debug( "`shop_order:{$order_id}` status changed from $status_from to $status_to. No check_unpaid_order background job present to cancel.", $context ); |
132 | } |
133 | } |
134 | } |