PackageController::canPass()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 8
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 16
ccs 9
cts 9
cp 1
crap 4
rs 10
1
<?php
2
3
namespace ag84ark\AwsSesBounceComplaintHandler\Http\Controllers;
4
5
use ag84ark\AwsSesBounceComplaintHandler\Models\WrongEmail;
6
use GuzzleHttp\Client;
7
use Illuminate\Http\JsonResponse;
8
use Illuminate\Http\Request;
9
use Illuminate\Support\Facades\Log;
10
use Illuminate\Support\Facades\Response;
11
12
class PackageController
13
{
14
    protected $data = [];
15
    protected $message = [];
16
    protected $client;
17
18 8
    public function __construct(Client $client)
19
    {
20 8
        $this->client = $client ?: new Client();
0 ignored issues
show
introduced by
$client is of type GuzzleHttp\Client, thus it always evaluated to true.
Loading history...
21 8
    }
22
23 8
    public function handleBounceOrComplaint(Request $request): JsonResponse
24
    {
25 8
        if (! $request->json()) {
26
            return Response::json(['status' => 422, 'message' => 'error'], 422);
27
        }
28
29 8
        if (! $this->canPass($request)) {
30 1
            return Response::json(['status' => 403, 'message' => 'error'], 403);
31
        }
32
33 7
        $this->data = $request->json()->all() ?? [];
34
35 7
        $this->handleLoggingData();
36
37 7
        if ($info = $this->handleSubscriptionConfirmation()) {
38 1
            return Response::json(['status' => 200, 'message' => $info]);
39
        }
40
41 6
        $this->getMessageData();
42
43 6
        if (! count($this->message)) {
44
            return Response::json(['status' => 422, 'data' => $this->data], 422);
45
        }
46
47 6
        if (! isset($this->message['notificationType'])) {
48 1
            return Response::json(['status' => 200, 'message' => 'no data']);
49
        }
50
51 5
        $this->storeEmailToDB();
52
53 5
        return Response::json(['status' => 200, 'message' => 'success']);
54
    }
55
56 8
    private function canPass(Request $request): bool
57
    {
58 8
        if (config('aws-ses-bounce-complaint-handler.via_sqs')) {
59 1
            return true;
60
        }
61
62 7
        $secret = config('aws-ses-bounce-complaint-handler.route_secret');
63 7
        if (! $secret) {
64 5
            return true;
65
        }
66
67 2
        if ($secret !== $request->get('secret')) {
68 1
            return false;
69
        }
70
71 1
        return true;
72
    }
73
74 7
    private function handleLoggingData(): void
75
    {
76 7
        if (config('aws-ses-bounce-complaint-handler.log_requests')) {
77 1
            $dataCollection = collect($this->data);
78 1
            Log::info('Logging AWS SES DATA');
79 1
            Log::info($dataCollection->toJson());
80
        }
81 7
    }
82
83 7
    private function handleSubscriptionConfirmation(): ?string
84
    {
85
        try {
86 7
            if (! isset($this->data['Type']) || 'SubscriptionConfirmation' !== $this->data['Type'] || ! config('aws-ses-bounce-complaint-handler.auto_subscribe')) {
87 6
                return null;
88
            }
89 1
            Log::info('SubscriptionConfirmation came at: '.$this->data['Timestamp']);
90
91 1
            $res = $this->client->get($this->data['SubscribeURL']);
92
93 1
            if (200 === $res->getStatusCode()) {
94 1
                $message = 'SubscriptionConfirmation was auto confirmed!';
95 1
                Log::info($message);
96
            } else {
97
                $message = 'SubscriptionConfirmation could not be auto confirmed!';
98
                Log::warning($message);
99
                Log::info($this->data['SubscribeURL']);
100
            }
101
102 1
            return $message;
103
        } catch (\Exception $exception) {
104
            return  $exception->getMessage();
105
        }
106
    }
107
108 6
    private function getMessageData(): void
109
    {
110 6
        if (config('aws-ses-bounce-complaint-handler.via_sqs')) {
111 1
            if ('Notification' === $this->data['Type']) {
112 1
                $this->message = $this->data['Message'];
113
            }
114
        } else {
115 5
            $this->message = $this->data;
116
        }
117 6
    }
118
119 5
    private function storeEmailToDB(): void
120
    {
121 5
        $message = $this->message;
122
123 5
        switch ($message['notificationType']) {
124 5
            case 'Bounce':
125 4
                $bounce = $message['bounce'];
126 4
                $this->saveBouncedEmailsToDB($bounce);
127
128 4
                break;
129
130 1
            case 'Complaint':
131 1
                $complaint = $message['complaint'];
132 1
                $this->saveComplainedEmailsToDB($complaint);
133
134 1
                break;
135
136
            default:
137
                // Do Nothing
138
                break;
139
        }
140 5
    }
141
142
    /**
143
     * @param $bounce
144
     */
145 4
    private function saveBouncedEmailsToDB($bounce): void
146
    {
147 4
        $subtype = $bounce['bounceType'];
148 4
        foreach ($bounce['bouncedRecipients'] as $bouncedRecipient) {
149 4
            $emailAddress = $bouncedRecipient['emailAddress'];
150
151 4
            $emailRecord = WrongEmail::firstOrCreate(['email' => $emailAddress, 'problem_type' => 'Bounce', 'problem_subtype' => $subtype]);
152 4
            if ($emailRecord) {
153 4
                $emailRecord->increment('repeated_attempts', 1);
154
            }
155
        }
156 4
    }
157
158
    /**
159
     * @param $complaint
160
     */
161 1
    private function saveComplainedEmailsToDB($complaint): void
162
    {
163 1
        $subtype = $complaint['complaintFeedbackType'] ?? '';
164 1
        foreach ($complaint['complainedRecipients'] as $complainedRecipient) {
165 1
            $emailAddress = $complainedRecipient['emailAddress'];
166 1
            $emailRecord = WrongEmail::firstOrCreate(['email' => $emailAddress, 'problem_type' => 'Complaint', 'problem_subtype' => $subtype]);
167 1
            if ($emailRecord) {
168 1
                $emailRecord->increment('repeated_attempts', 1);
169
            }
170
        }
171 1
    }
172
}
173