Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
5.45% |
3 / 55 |
|
10.00% |
1 / 10 |
CRAP | |
0.00% |
0 / 1 |
| WooCommerce | |
5.45% |
3 / 55 |
|
10.00% |
1 / 10 |
470.07 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| get_description | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| init | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| is_enabled | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| handle_ses_bounce | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
12 | |||
| handle_ses_complaint | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| setup_test | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
20 | |||
| verify_test | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
12 | |||
| delete_test_data | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
3 | |||
| display_bounce_notification | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
30 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * Functionality for WooCommerce to highlight in orders when the user's email address is incorrect. |
| 4 | * |
| 5 | * @see https://wordpress.org/plugins/woocommerce |
| 6 | * |
| 7 | * @link https://BrianHenry.ie |
| 8 | * @since 1.1.0 |
| 9 | * |
| 10 | * @package brianhenryie/bh-wp-aws-ses-bounce-handler |
| 11 | */ |
| 12 | |
| 13 | namespace BrianHenryIE\AWS_SES_Bounce_Handler\API\Integrations; |
| 14 | |
| 15 | use BrianHenryIE\AWS_SES_Bounce_Handler\Admin\Bounce_Handler_Test; |
| 16 | |
| 17 | use BrianHenryIE\AWS_SES_Bounce_Handler\API\SES_Bounce_Handler_Integration_Interface; |
| 18 | use Psr\Log\LoggerAwareTrait; |
| 19 | use Psr\Log\LoggerInterface; |
| 20 | use stdClass; |
| 21 | use WC_Order; |
| 22 | |
| 23 | /** |
| 24 | * Hook onto `handle_ses_bounce` to add order note and meta key, hook onto `admin_notices` to display notice on orders. |
| 25 | */ |
| 26 | class WooCommerce implements SES_Bounce_Handler_Integration_Interface { |
| 27 | |
| 28 | use LoggerAwareTrait; |
| 29 | |
| 30 | public function __construct( LoggerInterface $logger ) { |
| 31 | $this->setLogger( $logger ); |
| 32 | } |
| 33 | |
| 34 | const BOUNCED_META_KEY = 'bh_wp_aws_ses_bounce_hander_bounced'; |
| 35 | |
| 36 | /** |
| 37 | * Return a description for the admin UI, explaining a note and notice will be added to orders. |
| 38 | * |
| 39 | * @return string |
| 40 | */ |
| 41 | public function get_description(): string { |
| 42 | return 'Adds a note and notice on orders whose email address bounced'; |
| 43 | } |
| 44 | |
| 45 | /** |
| 46 | * Add the hook for displaying the order notice. |
| 47 | */ |
| 48 | public function init(): void { |
| 49 | add_action( 'admin_notices', array( $this, 'display_bounce_notification' ) ); |
| 50 | } |
| 51 | |
| 52 | /** |
| 53 | * Check is WooCommerce installed. |
| 54 | * |
| 55 | * @return bool |
| 56 | */ |
| 57 | public function is_enabled(): bool { |
| 58 | return class_exists( \WooCommerce::class ); |
| 59 | } |
| 60 | |
| 61 | /** |
| 62 | * Add a note to orders whose email addresses are invalid. |
| 63 | * |
| 64 | * @hooked handle_ses_bounce |
| 65 | * |
| 66 | * @param string $email_address The email address that has bounced. |
| 67 | * @param stdClass $bounced_recipient Parent object with emailAddress, status, action, diagnosticCode. |
| 68 | * @param stdClass $message Parent object of complete notification. |
| 69 | */ |
| 70 | public function handle_ses_bounce( string $email_address, stdClass $bounced_recipient, stdClass $message ): void { |
| 71 | |
| 72 | if ( ! $this->is_enabled() ) { |
| 73 | return; |
| 74 | } |
| 75 | |
| 76 | /** |
| 77 | * Find any orders made with this email address. |
| 78 | * |
| 79 | * @var WC_Order[] $customer_orders |
| 80 | */ |
| 81 | $customer_orders = wc_get_orders( array( 'customer' => $email_address ) ); |
| 82 | |
| 83 | foreach ( $customer_orders as $order ) { |
| 84 | |
| 85 | $order->add_order_note( 'Email address bounced' ); |
| 86 | |
| 87 | $order->add_meta_data( self::BOUNCED_META_KEY, $email_address, true ); |
| 88 | |
| 89 | $order->save(); |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | /** |
| 94 | * Do nothing. |
| 95 | * |
| 96 | * @hooked handle_ses_complaint |
| 97 | * |
| 98 | * @param string $email_address The email address which complained about our email. |
| 99 | * @param stdClass $complained_recipient The SES notification the email address was received in. |
| 100 | * @param stdClass $message The SNS notification the SES notification was received in. |
| 101 | */ |
| 102 | public function handle_ses_complaint( string $email_address, stdClass $complained_recipient, stdClass $message ): void {} |
| 103 | |
| 104 | /** |
| 105 | * Create an order with the bounce simulator email address. |
| 106 | * |
| 107 | * @param Bounce_Handler_Test $test The test orchestrator and configuration. |
| 108 | * |
| 109 | * @return ?array<string, array<string,mixed>|string> |
| 110 | */ |
| 111 | public function setup_test( Bounce_Handler_Test $test ): ?array { |
| 112 | |
| 113 | if ( ! $this->is_enabled() ) { |
| 114 | return null; |
| 115 | } |
| 116 | |
| 117 | $order = wc_create_order(); |
| 118 | |
| 119 | if ( ! ( $order instanceof WC_Order ) ) { |
| 120 | // TODO. |
| 121 | return null; |
| 122 | } |
| 123 | |
| 124 | $address = array( |
| 125 | 'email' => $test->get_email(), |
| 126 | ); |
| 127 | $order->set_address( $address, 'billing' ); |
| 128 | $order_bounced_meta_value = $order->get_meta( self::BOUNCED_META_KEY ); |
| 129 | $order_bounced_meta_value = empty( $order_bounced_meta_value ) ? 'empty' : $order_bounced_meta_value; |
| 130 | |
| 131 | $order_url = admin_url( 'post.php?post=' . $order->get_id() . '&action=edit' ); |
| 132 | |
| 133 | $data['wc_order_id'] = $order->get_id(); |
| 134 | $data['wc_order_bounced_meta_value'] = $order_bounced_meta_value; |
| 135 | |
| 136 | $html = '<p>WooCommerce <a href="' . $order_url . '">order ' . $order->get_id() . '</a> created with meta key <em>' . self::BOUNCED_META_KEY . '</em> value: <em>' . $order_bounced_meta_value . '</em></p>'; |
| 137 | |
| 138 | return array( |
| 139 | 'data' => $data, |
| 140 | 'html' => $html, |
| 141 | ); |
| 142 | } |
| 143 | |
| 144 | /** |
| 145 | * Verify the order has metadata added. |
| 146 | * |
| 147 | * @param array $test_data {int: wc_order_id}. |
| 148 | * |
| 149 | * @return array |
| 150 | */ |
| 151 | public function verify_test( array $test_data ): ?array { |
| 152 | |
| 153 | $order = wc_get_order( intval( $test_data['wc_order_id'] ) ); |
| 154 | |
| 155 | if ( ! $order instanceof \WC_Order ) { |
| 156 | |
| 157 | return array( |
| 158 | 'success' => false, |
| 159 | 'html' => '<p>WooCommerce order not found</p>', |
| 160 | ); |
| 161 | } |
| 162 | |
| 163 | $order_bounced_meta_value = $order->get_meta( self::BOUNCED_META_KEY ); |
| 164 | |
| 165 | if ( empty( $order_bounced_meta_value ) ) { |
| 166 | |
| 167 | return array( |
| 168 | 'success' => false, |
| 169 | 'html' => '<p>WooCommerce order meta key not found</p>', |
| 170 | ); |
| 171 | } |
| 172 | |
| 173 | $success = true; |
| 174 | |
| 175 | $order_url = admin_url( 'post.php?post=' . $order->get_id() . '&action=edit' ); |
| 176 | |
| 177 | $html = '<p>WooCommerce <a href="' . $order_url . '">order ' . $order->get_id() . '</a> found with meta key <em>' . self::BOUNCED_META_KEY . '</em> value: <em>' . $order_bounced_meta_value . '</em></p>'; |
| 178 | |
| 179 | return array( |
| 180 | 'success' => $success, |
| 181 | 'html' => $html, |
| 182 | ); |
| 183 | |
| 184 | } |
| 185 | |
| 186 | /** |
| 187 | * Delete the order created for the test. |
| 188 | * |
| 189 | * @param array{'wc_order_id': int} $test_data The data created and saved during setup_test(). |
| 190 | */ |
| 191 | public function delete_test_data( array $test_data ): bool { |
| 192 | |
| 193 | if ( isset( $test_data['wc_order_id'] ) && class_exists( \WooCommerce::class ) ) { |
| 194 | wp_delete_post( intval( $test_data['wc_order_id'] ) ); |
| 195 | } |
| 196 | |
| 197 | return true; |
| 198 | } |
| 199 | |
| 200 | /** |
| 201 | * Display an admin notice if this order's customer email has bounced. |
| 202 | * |
| 203 | * @hooked admin_notices |
| 204 | * |
| 205 | * @see https://stackoverflow.com/questions/56971501/how-to-add-admin-notices-on-woocommerce-order-edit-page |
| 206 | */ |
| 207 | public function display_bounce_notification(): void { |
| 208 | |
| 209 | if ( ! $this->is_enabled() ) { |
| 210 | return; |
| 211 | } |
| 212 | |
| 213 | $id = get_the_ID(); |
| 214 | |
| 215 | if ( false === $id ) { |
| 216 | return; |
| 217 | } |
| 218 | |
| 219 | $order = wc_get_order( $id ); |
| 220 | |
| 221 | if ( ! $order instanceof WC_Order ) { |
| 222 | return; |
| 223 | } |
| 224 | |
| 225 | $bounced_email = $order->get_meta( self::BOUNCED_META_KEY ); |
| 226 | |
| 227 | if ( ! empty( $bounced_email ) ) { |
| 228 | |
| 229 | $notice = sprintf( |
| 230 | "<div class='notice notice-warning'><p>%s <em>%s</em> %s.</p></div>", |
| 231 | __( "The customer's email address", 'bh-wp-aws-ses-bounce-handler' ), |
| 232 | $bounced_email, |
| 233 | __( 'is invalid', 'bh-wp-aws-ses-bounce-handler' ) |
| 234 | ); |
| 235 | |
| 236 | $allowed_html = array( |
| 237 | 'div' => array( |
| 238 | 'class' => array(), |
| 239 | ), |
| 240 | 'p' => array(), |
| 241 | 'em' => array(), |
| 242 | ); |
| 243 | |
| 244 | echo wp_kses( $notice, $allowed_html ); |
| 245 | } |
| 246 | } |
| 247 | |
| 248 | } |