Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
21.62% |
8 / 37 |
|
42.86% |
3 / 7 |
CRAP | |
0.00% |
0 / 1 |
Order | |
21.62% |
8 / 37 |
|
42.86% |
3 / 7 |
139.26 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
check_address_on_single_order_processing | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
12 | |||
check_address_on_bulk_order_processing | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
12 | |||
add_admin_ui_order_action | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
check_address_on_admin_order_action | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
print_link_to_usps_tools_zip_lookup | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
12 | |||
add_previous_address_to_order | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
20 |
1 | <?php |
2 | /** |
3 | * When an order is paid, check its address. |
4 | * When an order is marked processing via the order list page bulk actions "Mark processing", check its address. |
5 | * Add a "Validate address" option on the order page's order actions |
6 | */ |
7 | |
8 | namespace BrianHenryIE\WC_Address_Validation\WooCommerce; |
9 | |
10 | use BrianHenryIE\WC_Address_Validation\API_Interface; |
11 | use BrianHenryIE\WC_Address_Validation\Settings_Interface; |
12 | use BrianHenryIE\WC_Address_Validation\WP_Includes\Cron; |
13 | use Psr\Log\LoggerAwareTrait; |
14 | use Psr\Log\LoggerInterface; |
15 | use WC_Order; |
16 | |
17 | /** |
18 | * Class Order |
19 | * |
20 | * @package BrianHenryIE\WC_Address_Validation\WooCommerce |
21 | */ |
22 | class Order { |
23 | |
24 | use LoggerAwareTrait; |
25 | |
26 | /** |
27 | * @var Settings_Interface |
28 | */ |
29 | protected Settings_Interface $settings; |
30 | |
31 | /** |
32 | * @var API_Interface |
33 | */ |
34 | protected API_Interface $api; |
35 | |
36 | /** |
37 | * Order constructor. |
38 | * |
39 | * @param API_Interface $api |
40 | * @param Settings_Interface $settings |
41 | * @param LoggerInterface $logger |
42 | */ |
43 | public function __construct( API_Interface $api, Settings_Interface $settings, LoggerInterface $logger ) { |
44 | |
45 | $this->setLogger( $logger ); |
46 | $this->settings = $settings; |
47 | $this->api = $api; |
48 | } |
49 | |
50 | /** |
51 | * When an order is paid, validate the address. |
52 | * |
53 | * Runs when the order status has changed from an unpaid to a paid status. |
54 | * |
55 | * TODO: Do not run on bulk updates. |
56 | * |
57 | * @hooked woocommerce_order_status_changed |
58 | * @see WC_Order::status_transition() |
59 | * |
60 | * @param int $order_id |
61 | * @param string $status_from |
62 | * @param string $status_to |
63 | */ |
64 | public function check_address_on_single_order_processing( $order_id, $status_from, $status_to ): void { |
65 | |
66 | // TODO: This is also running on the bulk update action... only one is needed. |
67 | // if ( isset( $_REQUEST['_wp_http_referer'] ) && '/wp-admin/edit.php?post_type=shop_order' === $_REQUEST['_wp_http_referer'] ) { |
68 | // return; |
69 | // } |
70 | |
71 | if ( ! in_array( $status_from, wc_get_is_paid_statuses(), true ) && in_array( $status_to, wc_get_is_paid_statuses(), true ) ) { |
72 | |
73 | $args = array( $order_id ); |
74 | |
75 | $this->logger->debug( 'Scheduling background process to check order ' . $order_id, array( 'order_id' => $order_id ) ); |
76 | |
77 | wp_schedule_single_event( time() - 60, Cron::CHECK_SINGLE_ADDRESS_CRON_JOB, $args ); |
78 | } |
79 | } |
80 | |
81 | /** |
82 | * |
83 | * This runs asynchronously. |
84 | * |
85 | * TODO: Maybe check nonce. |
86 | * |
87 | * @hooked admin_action_mark_processing |
88 | */ |
89 | public function check_address_on_bulk_order_processing(): void { |
90 | |
91 | // The bulk update should have an array of post (order) ids. |
92 | if ( ! isset( $_REQUEST['post'] ) || ! is_array( $_REQUEST['post'] ) ) { |
93 | return; |
94 | } |
95 | |
96 | $order_ids = array_map( 'intval', $_REQUEST['post'] ); |
97 | |
98 | $args = array( $order_ids ); |
99 | |
100 | $this->logger->debug( 'Scheduling background process to check orders ' . implode( ', ', $order_ids ), array( 'order_ids' => $order_ids ) ); |
101 | |
102 | wp_schedule_single_event( time() - 60, Cron::CHECK_MULTIPLE_ADDRESSES_CRON_JOB, $args ); |
103 | } |
104 | |
105 | /** |
106 | * Add "Validate address" to order actions in admin UI order edit page. |
107 | * |
108 | * TODO: Do not add if settings are not configured! |
109 | * |
110 | * @hooked woocommerce_order_actions |
111 | * @see class-wc-meta-box-order-actions.php |
112 | * |
113 | * @param string[] $actions |
114 | * @return string[] |
115 | */ |
116 | public function add_admin_ui_order_action( $actions ): array { |
117 | |
118 | // global $order? |
119 | |
120 | $actions['bh_wc_address_validate'] = __( 'Validate address', 'bh-wc-address-validation' ); |
121 | |
122 | return $actions; |
123 | } |
124 | |
125 | /** |
126 | * This runs synchronously. |
127 | * |
128 | * @hooked woocommerce_order_action_bh_wc_address_validate |
129 | * |
130 | * @param WC_Order $order |
131 | */ |
132 | public function check_address_on_admin_order_action( $order ): void { |
133 | |
134 | $this->logger->debug( $order->get_id() . ' check address started from edit order page.', array( 'order_id' => $order->get_id() ) ); |
135 | |
136 | $is_manual = true; |
137 | |
138 | $this->api->check_address_for_order( $order, $is_manual ); |
139 | |
140 | // TODO: Add admin notice. |
141 | } |
142 | |
143 | |
144 | /** |
145 | * On the single order admin UI screen, if the order status is bad-address, and it is a US order, show a link |
146 | * to the USPS Zip Code Lookup Tool. |
147 | * |
148 | * @see https://tools.usps.com/zip-code-lookup.htm?byaddress |
149 | * |
150 | * @hooked woocommerce_admin_order_data_after_shipping_address |
151 | * @see class-wc-meta-box-order-data.php |
152 | * |
153 | * @param WC_Order $order |
154 | */ |
155 | public function print_link_to_usps_tools_zip_lookup( WC_Order $order ): void { |
156 | |
157 | if ( Order_Status::BAD_ADDRESS_STATUS === $order->get_status() && 'US' === $order->get_shipping_country() ) { |
158 | |
159 | echo '<a target="_blank" href="https://tools.usps.com/zip-code-lookup.htm?byaddress">USPS Zip Code Lookup Tool</a>'; |
160 | } |
161 | } |
162 | |
163 | /** |
164 | * Show "previous customer address" when possible for bad-address orders. |
165 | * |
166 | * When viewing a bad-address order, using the customer's past orders is useful to find the correct address. |
167 | * |
168 | * @hooked woocommerce_admin_order_data_after_shipping_address |
169 | * @see class-wc-meta-box-order-data.php |
170 | * |
171 | * @param WC_Order $order |
172 | */ |
173 | public function add_previous_address_to_order( WC_Order $order ) { |
174 | |
175 | if ( Order_Status::BAD_ADDRESS_STATUS !== $order->get_status() ) { |
176 | return; |
177 | } |
178 | |
179 | // TODO: sort by most recent. |
180 | $customer_orders = wc_get_orders( |
181 | array( |
182 | 'status' => 'wc-completed', |
183 | 'billing_email' => $order->get_billing_email(), |
184 | 'limit' => 1, |
185 | ) |
186 | ); |
187 | |
188 | if ( 0 === count( $customer_orders ) ) { |
189 | echo '<p class="none_set" style="clear:both;"><strong>' . esc_html__( 'Previous Order\'s Address:', 'bh-wc-address-validation' ) . '</strong> ' . esc_html__( 'No previous order.', 'bh-wc-address-validation' ) . '</p>'; |
190 | return; |
191 | } |
192 | |
193 | $previous_order = array_pop( $customer_orders ); |
194 | |
195 | if ( $previous_order->get_formatted_shipping_address() ) { |
196 | |
197 | echo '<p class="none_set" style="clear:both;"><strong>' . esc_html__( 'Previous Order\'s Address:', 'bh-wc-address-validation' ) . '</strong> ' . '</p>'; |
198 | |
199 | echo '<p>' . wp_kses( $previous_order->get_formatted_shipping_address(), array( 'br' => array() ) ) . '</p>'; |
200 | |
201 | echo '<p class="none_set">Order <a href="' . $previous_order->get_edit_order_url() . '">#' . $previous_order->get_id() . '</a>.' . '</p>'; |
202 | } |
203 | } |
204 | } |