Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
16.13% covered (danger)
16.13%
10 / 62
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
MailPoet
16.13% covered (danger)
16.13%
10 / 62
0.00% covered (danger)
0.00%
0 / 9
255.99
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 init
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 is_enabled
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 get_description
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 handle_ses_bounce
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 handle_ses_complaint
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
30
 setup_test
66.67% covered (warning)
66.67%
10 / 15
0.00% covered (danger)
0.00%
0 / 1
3.33
 verify_test
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
20
 delete_test_data
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * @see https://wordpress.org/plugins/mailpoet/
4 */
5
6namespace BrianHenryIE\AWS_SES_Bounce_Handler\API\Integrations;
7
8use BrianHenryIE\AWS_SES_Bounce_Handler\Admin\Bounce_Handler_Test;
9use BrianHenryIE\AWS_SES_Bounce_Handler\API\SES_Bounce_Handler_Integration_Interface;
10use Psr\Log\LoggerAwareTrait;
11use Psr\Log\LoggerInterface;
12use MailPoet\API\MP\v1\APIException;
13use MailPoet\Models\Subscriber;
14use stdClass;
15
16/**
17 * @see https://github.com/mailpoet/mailpoet/blob/master/doc/api_methods/GetSubscriber.md
18 */
19class MailPoet implements SES_Bounce_Handler_Integration_Interface {
20
21    use LoggerAwareTrait;
22
23    public function __construct( LoggerInterface $logger ) {
24        $this->setLogger( $logger );
25    }
26
27    public function init(): void {
28        // Create lists AWS Complaints, AWS Bounces?
29        // Or just unsubscribe users?
30    }
31
32    public function is_enabled(): bool {
33        return class_exists( \MailPoet\API\API::class );
34    }
35
36    public function get_description(): string {
37        if ( $this->is_enabled() ) {
38
39            $bounced_list_url      = admin_url( 'admin.php?page=mailpoet-subscribers#/page[1]/sort_by[created_at]/sort_order[desc]/group[bounced]' );
40            $unsubscribed_list_url = admin_url( 'admin.php?page=mailpoet-subscribers#/page[1]/sort_by[created_at]/sort_order[desc]/group[unsubscribed]' );
41
42            return 'Marks users as <a href="' . esc_url( $bounced_list_url ) . '">bounced</a> or <a href="' . esc_url( $unsubscribed_list_url ) . '">unsubscribed</a>';
43        } else {
44            return 'Marks users as bounced and unsubscribes complaints';
45        }
46    }
47
48    /**
49     *
50     * Set the MailPoet's subscriber status as 'bounced'
51     *
52     * @param string   $email_address
53     * @param stdClass $bounced_recipient
54     * @param stdClass $message
55     */
56    public function handle_ses_bounce( string $email_address, stdClass $bounced_recipient, stdClass $message ): void {
57
58        $subscriber = Subscriber::findOne( $email_address );
59
60        if ( false === $subscriber ) {
61            $this->logger->warning( "Bounced email address {$email_address} not found as Mailpoet Subscriber. Unable to unsubscribe", array( 'email_address' => $email_address ) );
62            return;
63        }
64        $subscriber->status = Subscriber::STATUS_BOUNCED;
65
66        $result = $subscriber->save();
67    }
68
69    /**
70     * Since it's a complaint, it makes sense to unsubscribe from all lists.
71     *
72     * @param string   $email_address
73     * @param stdClass $complained_recipient
74     * @param stdClass $message
75     */
76    public function handle_ses_complaint( string $email_address, stdClass $complained_recipient, stdClass $message ): void {
77
78        try {
79            $mailpoet_api = \MailPoet\API\API::MP( 'v1' );
80        } catch ( \Exception $e ) {
81            // TODO.
82            return;
83        }
84
85        try {
86            $subscriber = $mailpoet_api->getSubscriber( $email_address );
87        } catch ( \MailPoet\API\MP\v1\APIException $e ) {
88            // Subscriber probably does not exist
89            return;
90        }
91
92        $subscriber_id = $subscriber['id'];
93        $list_ids      = array();
94        foreach ( $subscriber['subscriptions'] as $subscription ) {
95            $list_ids[] = $subscription['segment_id'];
96        }
97
98        try {
99            $mailpoet_api->unsubscribeFromLists( $subscriber_id, $list_ids );
100        } catch ( \MailPoet\API\MP\v1\APIException $e ) {
101
102        }
103    }
104
105    /**
106     * @param Bounce_Handler_Test $test
107     * @return array|null
108     */
109    public function setup_test( Bounce_Handler_Test $test ): ?array {
110
111        $email_address = $test->get_email();
112
113        try {
114            $mailpoet_api = \MailPoet\API\API::MP( 'v1' );
115        } catch ( \Exception $e ) {
116            // TODO.
117            return array(
118                'error' => $e->getMessage(),
119            );
120        }
121
122        // Create a subscriber
123        $subscriber_array = array(
124            'email' => $test->get_email(),
125        );
126
127        try {
128            $new_subscriber = $mailpoet_api->addSubscriber( $subscriber_array );
129        } catch ( APIException $e ) {
130            return array(
131                'error' => $e->getMessage(),
132            );
133        }
134
135        // Save the subscriber reference for checking later.
136
137        $test_data                  = array();
138        $test_data['email_address'] = $email_address;
139        $test_data['subscriber_id'] = $new_subscriber['id'];
140
141        $mailpoet_user_url = admin_url( "admin.php?page=mailpoet-subscribers#/edit/{$new_subscriber['id']}" );
142        $html              = '<p>MailPoet <a href="' . $mailpoet_user_url . '">subscriber ' . $new_subscriber['id'] . '</a> created with status ' . $new_subscriber['status'] . '</p>';
143
144        return array(
145            'data' => $test_data,
146            'html' => $html,
147        );
148    }
149
150    /**
151     * @param array{email_address: string, subscriber_id: int} $test_data
152     *
153     * @return array|null
154     */
155    public function verify_test( array $test_data ): ?array {
156
157        try {
158            $mailpoet_api = \MailPoet\API\API::MP( 'v1' );
159        } catch ( \Exception $e ) {
160            // Probably MailPoet "Invalid API version".
161            return array(
162                'success' => false,
163                'html'    => $e->getMessage(),
164            );
165        }
166
167        $email_address = $test_data['email_address'];
168
169        try {
170            $subscriber = $mailpoet_api->getSubscriber( $email_address );
171        } catch ( \MailPoet\API\MP\v1\APIException $e ) {
172            // Weird.
173            return array(
174                'success' => false,
175                'html'    => $e->getMessage(),
176            );
177        }
178
179        $subscriber_status = $subscriber['status'];
180
181        $success = 'bounced' === $subscriber_status;
182
183        $subscriber_id = $subscriber['status'];
184
185        $user_profile_url = admin_url( 'admin.php?page=mailpoet-subscribers#/edit/' . $subscriber_id );
186
187        if ( $success ) {
188            $html = '<p>MailPoet <a href="' . $user_profile_url . '">subscriber ' . $subscriber_id . '</a> found with new status ' . $subscriber_status . '</p>';
189        } else {
190            $html = '<p>MailPoet user status not changed</p>';
191        }
192
193        return array(
194            'success' => $success,
195            'html'    => $html,
196        );
197    }
198
199    /**
200     * Move the newly created subscriber to trash.
201     *
202     * @param array{email_address: string, subscriber_id: int} $test_data
203     *
204     * @return bool
205     */
206    public function delete_test_data( array $test_data ): bool {
207
208        $subscriber_id = $test_data['subscriber_id'];
209        $email_address = $test_data['email_address'];
210
211        $subscriber = Subscriber::findOne( $subscriber_id );
212
213        $subscriber->trash();
214
215        $result = $subscriber->save();
216
217        return true;
218
219    }
220}