Completed
Branch develop (a0a623)
by Romain
02:33
created

Messenger::isValidMessage()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.2
c 0
b 0
f 0
cc 4
eloc 6
nc 3
nop 1
1
<?php
2
namespace Kerox\Messenger;
3
4
use GuzzleHttp\Client;
5
use Kerox\Messenger\Message\Attachment;
6
use Kerox\Messenger\Message\Message;
7
use Kerox\Messenger\Request\MessageRequest;
8
use Kerox\Messenger\Request\UserProfileRequest;
9
use Kerox\Messenger\Response\MessageResponse;
10
use Kerox\Messenger\Response\UserProfileResponse;
11
12
class Messenger implements UserProfileInterface
13
{
14
15
    const API_URL = 'https://graph.facebook.com/';
16
    const API_VERSION = 'v2.6';
17
18
    const SENDER_ACTION_TYPING_ON = 'typing_on';
19
    const SENDER_ACTION_TYPING_OFF = 'typing_off';
20
    const SENDER_ACTION_MARK_SEEN = 'mark_seen';
21
22
    const NOTIFICATION_TYPE_REGULAR = 'REGULAR';
23
    const NOTIFICATION_TYPE_SILENT_PUSH = 'SILENT_PUSH';
24
    const NOTIFICATION_TYPE_NO_PUSH = 'NO_PUSH';
25
26
    /**
27
     * var string
28
     */
29
    protected $pageToken;
30
31
    /**
32
     * @var \GuzzleHttp\Client
33
     */
34
    protected $client;
35
36
    /**
37
     * @var Message
38
     */
39
    protected $message;
40
41
    /**
42
     * @var string
43
     */
44
    protected $senderAction;
45
46
    /**
47
     * @var string
48
     */
49
    protected $notificationType = self::NOTIFICATION_TYPE_REGULAR;
50
51
    /**
52
     * Messenger constructor.
53
     *
54
     * @param string $pageToken
55
     */
56
    public function __construct(string $pageToken)
57
    {
58
        $this->pageToken = $pageToken;
59
        $this->client = new Client([
60
            'base_uri' => self::API_URL . self::API_VERSION,
61
        ]);
62
    }
63
64
    /**
65
     * @param mixed $message
66
     * @return Messenger
67
     * @throws \Exception
68
     */
69
    public function setMessage($message): Messenger
70
    {
71
        if ($this->senderAction !== null) {
72
            throw new \Exception('sender_action is already defined');
73
        }
74
        $this->message = $this->isValidMessage($message);
75
76
        return $this;
77
    }
78
79
    /**
80
     * @param mixed $senderAction
81
     * @return Messenger
82
     * @throws \Exception
83
     */
84
    public function setSenderAction(string $senderAction): Messenger
85
    {
86
        if ($this->message !== null) {
87
            throw new \Exception('message is already defined');
88
        }
89
90
        $allowedSenderAction = $this->getAllowedSenderAction();
91
        if (!in_array($senderAction, $allowedSenderAction)) {
92
            throw new \InvalidArgumentException('$senderAction must be either ' . implode(',', $allowedSenderAction));
93
        }
94
        $this->senderAction = $senderAction;
95
96
        return $this;
97
    }
98
99
    /**
100
     * @return array
101
     */
102
    private function getAllowedSenderAction(): array
103
    {
104
        return [
105
            self::SENDER_ACTION_TYPING_ON,
106
            self::SENDER_ACTION_TYPING_OFF,
107
            self::SENDER_ACTION_MARK_SEEN,
108
        ];
109
    }
110
111
    /**
112
     * @param mixed $notificationType
113
     * @return Messenger
114
     */
115
    public function setNotificationType(string $notificationType): Messenger
116
    {
117
        $allowedNotificationType = $this->getAllowedNotificationType();
118
        if (!in_array($notificationType, $allowedNotificationType)) {
119
            throw new \InvalidArgumentException("\$notificationType must be either " . implode(',', $allowedNotificationType));
120
        }
121
        $this->notificationType = $notificationType;
122
123
        return $this;
124
    }
125
126
    /**
127
     * @return array
128
     */
129
    private function getAllowedNotificationType(): array
130
    {
131
        return [
132
            self::NOTIFICATION_TYPE_REGULAR,
133
            self::NOTIFICATION_TYPE_NO_PUSH,
134
            self::NOTIFICATION_TYPE_SILENT_PUSH,
135
        ];
136
    }
137
138
    /**
139
     * @param $message
140
     * @return mixed
141
     * @throws \InvalidArgumentException
142
     */
143
    private function isValidMessage($message)
144
    {
145
        if ($message instanceof Message) {
146
            return $message;
147
        }
148
149
        if (is_string($message) || $message instanceof Attachment) {
150
            return new Message($message);
151
        }
152
153
        throw new \InvalidArgumentException('$message must be a string or an instance of Message or Attachment');
154
    }
155
156
    /**
157
     * @param string $recipient
158
     * @return \Kerox\Messenger\Response\MessageResponse
159
     * @throws \Exception
160
     */
161
    public function sendTo(string $recipient): MessageResponse
162
    {
163
        if ($this->message === null && $this->senderAction === null) {
164
            throw new \Exception('message or sender_action must be defined');
165
        }
166
167
        $request = new MessageRequest($this->pageToken, $recipient, $this->message, $this->senderAction, $this->notificationType);
168
        $response = $this->client->post('/me/messages', $request->build());
169
170
        return new MessageResponse($response);
171
    }
172
173
    /**
174
     * @param string $userId
175
     * @param array|null $userProfileFields
176
     * @return \Kerox\Messenger\Response\UserProfileResponse
177
     */
178
    public function getUserProfile(string $userId, array $userProfileFields = null): UserProfileResponse
179
    {
180
        $allowedUserProfileFields = $this->getAllowedUserProfileFields();
181
        if ($userProfileFields !== null ) {
182
            foreach ($userProfileFields as $userProfileField) {
183
                if (!in_array($userProfileField, $allowedUserProfileFields)) {
184
                    throw new \InvalidArgumentException($userProfileField . ' is not a valid value. $userProfileFields must only contain ' . implode(',', $allowedUserProfileFields));
185
                }
186
            }
187
        } else {
188
            $userProfileFields = $allowedUserProfileFields;
189
        }
190
191
        $request = new UserProfileRequest($this->pageToken, $userProfileFields);
192
        $response = $this->client->get(sprintf('/%s', $userId), $request->build());
193
194
        return new UserProfileResponse($response);
195
    }
196
197
    /**
198
     * @return array
199
     */
200
    private function getAllowedUserProfileFields(): array
201
    {
202
        return [
203
            UserProfileInterface::FIRST_NAME,
204
            UserProfileInterface::LAST_NAME,
205
            UserProfileInterface::PROFILE_PIC,
206
            UserProfileInterface::LOCALE,
207
            UserProfileInterface::TIMEZONE,
208
            UserProfileInterface::GENDER,
209
            UserProfileInterface::IS_PAYMENT_ENABLED,
210
        ];
211
    }
212
}