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 | } |