Completed
Push — master ( 36581b...e31d04 )
by Ehsan
02:47
created

EventListener::getKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
nc 1
cc 1
eloc 2
nop 0
crap 2
1
<?php
2
3
namespace Botonomous\listener;
4
5
use Botonomous\BotonomousException;
6
use Botonomous\Event;
7
use Botonomous\utility\StringUtility;
8
9
/**
10
 * Class EventListener.
11
 */
12
class EventListener extends AbstractBaseListener
13
{
14
    const KEY = 'event';
15
    const MISSING_TOKEN_OR_APP_ID_MESSAGE = 'Token or api_app_id is not provided';
16
    const MISSING_APP_ID_MESSAGE  = 'Api app id must be provided';
17
    const MISSING_VERIFICATION_TOKEN_MESSAGE = 'Verification token must be provided';
18
    const MISSING_EVENT_TYPE_MESSAGE = 'Event type must be specified';
19
20
    private $token;
21
    private $teamId;
22
    private $appId;
23
    private $event;
24
    private $requestEventMaps = [
25
        'ts'       => 'timestamp',
26
        'event_ts' => 'eventTimestamp',
27
    ];
28
29
    /**
30
     * @return mixed
31
     */
32 12
    public function extractRequest()
33
    {
34 12
        return $this->getRequestUtility()->getPostedBody();
35
    }
36
37
    /**
38
     * @return string
39
     */
40 1
    public function getToken(): string
41
    {
42 1
        return $this->token;
43
    }
44
45
    /**
46
     * @param string $token
47
     */
48 1
    public function setToken(string $token)
49
    {
50 1
        $this->token = $token;
51 1
    }
52
53
    /**
54
     * @return string
55
     */
56 1
    public function getTeamId(): string
57
    {
58 1
        return $this->teamId;
59
    }
60
61
    /**
62
     * @param string $teamId
63
     */
64 1
    public function setTeamId(string $teamId)
65
    {
66 1
        $this->teamId = $teamId;
67 1
    }
68
69
    /**
70
     * @return string
71
     */
72 1
    public function getAppId(): string
73
    {
74 1
        return $this->appId;
75
    }
76
77
    /**
78
     * @param string $appId
79
     */
80 1
    public function setAppId(string $appId)
81
    {
82 1
        $this->appId = $appId;
83 1
    }
84
85
    /**
86
     * @return Event
87
     */
88 12
    public function getEvent()
89
    {
90 12
        if (!isset($this->event)) {
91 11
            $this->loadEvent();
92
        }
93
94 11
        return $this->event;
95
    }
96
97
    /**
98
     * @param Event $event
99
     */
100 8
    public function setEvent(Event $event)
101
    {
102 8
        $this->event = $event;
103 8
    }
104
105
    /**
106
     * @throws \Exception
107
     */
108 11
    private function loadEvent()
109
    {
110 11
        $request = $this->getRequest();
111 11
        if (!isset($request['event'])) {
112 3
            return;
113
        }
114
115 8
        $request = $request['event'];
116 8
        if (!isset($request['type'])) {
117 1
            throw new BotonomousException(self::MISSING_EVENT_TYPE_MESSAGE);
118
        }
119
120
        // create the event
121 7
        $eventObject = new Event($request['type']);
122
123
        // exclude type from the args since it's already passed
124 7
        unset($request['type']);
125
126 7
        $stringUtility = new StringUtility();
127 7
        foreach ($request as $argKey => $argValue) {
128 7
            if (array_key_exists($argKey, $this->requestEventMaps)) {
129 6
                $argKey = $this->requestEventMaps[$argKey];
130
            }
131
132 7
            $setterName = 'set'.$stringUtility->snakeCaseToCamelCase($argKey);
133
134
            // ignore calling the method if setter does not exist
135 7
            if (!method_exists($eventObject, $setterName)) {
136 6
                continue;
137
            }
138
139 7
            $eventObject->$setterName($argValue);
140
        }
141
142
        // set it
143 7
        $this->setEvent($eventObject);
144 7
    }
145
146
    /**
147
     * @throws \Exception
148
     *
149
     * @return array<string,boolean|string>
150
     */
151 3
    public function verifyOrigin()
152
    {
153 3
        $request = $this->getRequest();
154
155 3
        if (!isset($request['token']) || !isset($request['api_app_id'])) {
156
            return [
157 1
                'success' => false,
158 1
                'message' => self::MISSING_TOKEN_OR_APP_ID_MESSAGE,
159
            ];
160
        }
161
162 3
        $verificationToken = $this->getConfig()->get('verificationToken');
163
164 3
        if (empty($verificationToken)) {
165 1
            throw new BotonomousException('Verification token must be provided');
166
        }
167
168 2
        $expectedAppId = $this->getConfig()->get('appId');
169
170 2
        if (empty($expectedAppId)) {
171 1
            throw new BotonomousException(self::MISSING_APP_ID_MESSAGE);
172
        }
173
174 1
        if ($verificationToken === $request['token'] &&
175 1
            $expectedAppId === $request['api_app_id']) {
176
            return [
177 1
                'success' => true,
178
                'message' => 'O La la!',
179
            ];
180
        }
181
182
        return [
183 1
            'success' => false,
184
            'message' => 'Token or api_app_id mismatch',
185
        ];
186
    }
187
188
    /**
189
     * Check if the request belongs to the bot itself.
190
     *
191
     * @throws \Exception
192
     *
193
     * @return bool
194
     */
195 4
    public function isThisBot(): bool
196
    {
197 4
        $subType = $this->getRequest('subtype');
198
199 4
        if ($subType === 'bot_message') {
200 1
            return true;
201
        }
202
203 4
        $event = $this->getEvent();
204
205 4
        return $event instanceof Event && !empty($event->getBotId());
206
    }
207
208
    /**
209
     * @return string
210
     */
211 1
    public function getChannelId(): string
212
    {
213 1
        return $this->getEvent()->getChannel();
214
    }
215
216
    /**
217
     * @return string
218
     */
219
    public function getKey(): string
220
    {
221
        return self::KEY;
222
    }
223
}
224