Passed
Push — master ( d93ca9...1e6220 )
by Sullivan
02:35 queued 40s
created

Client::__construct()   B

Complexity

Conditions 2
Paths 1

Size

Total Lines 34
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 25
nc 1
nop 3
dl 0
loc 34
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Nexylan packages.
7
 *
8
 * (c) Nexylan SAS <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Nexy\Slack;
15
16
use Http\Client\Common\HttpMethodsClient;
17
use Http\Client\Common\Plugin\BaseUriPlugin;
18
use Http\Client\Common\PluginClient;
19
use Http\Client\Exception;
20
use Http\Client\HttpClient;
21
use Http\Discovery\HttpClientDiscovery;
22
use Http\Discovery\MessageFactoryDiscovery;
23
use Http\Discovery\UriFactoryDiscovery;
24
use Symfony\Component\OptionsResolver\OptionsResolver;
25
26
class Client
27
{
28
    /**
29
     * @var array
30
     */
31
    private $options;
32
33
    /**
34
     * @var HttpMethodsClient
35
     */
36
    private $httpClient;
37
38
    /**
39
     * Instantiate a new Client.
40
     *
41
     * @param string          $endpoint
42
     * @param array           $options
43
     * @param HttpClient|null $httpClient
44
     */
45
    public function __construct($endpoint, array $options = [], HttpClient $httpClient = null)
46
    {
47
        $resolver = (new OptionsResolver())
48
            ->setDefaults([
49
                'channel' => null,
50
                'username' => null,
51
                'icon' => null,
52
                'link_names' => false,
53
                'unfurl_links' => false,
54
                'unfurl_media' => true,
55
                'allow_markdown' => true,
56
                'markdown_in_attachments' => [],
57
            ])
58
            ->setAllowedTypes('channel', ['string', 'null'])
59
            ->setAllowedTypes('username', ['string', 'null'])
60
            ->setAllowedTypes('icon', ['string', 'null'])
61
            ->setAllowedTypes('link_names', 'bool')
62
            ->setAllowedTypes('unfurl_links', 'bool')
63
            ->setAllowedTypes('unfurl_media', 'bool')
64
            ->setAllowedTypes('allow_markdown', 'bool')
65
            ->setAllowedTypes('markdown_in_attachments', 'array')
66
        ;
67
        $this->options = $resolver->resolve($options);
68
69
        $this->httpClient = new HttpMethodsClient(
70
            new PluginClient(
71
                $httpClient ?: HttpClientDiscovery::find(),
72
                [
73
                    new BaseUriPlugin(
74
                        UriFactoryDiscovery::find()->createUri($endpoint)
75
                    ),
76
                ]
77
            ),
78
            MessageFactoryDiscovery::find()
79
        );
80
    }
81
82
    /**
83
     * Pass any unhandled methods through to a new Message
84
     * instance.
85
     *
86
     * @param string $name      The name of the method
87
     * @param array  $arguments The method arguments
88
     *
89
     * @return \Nexy\Slack\Message
90
     */
91
    public function __call($name, $arguments)
92
    {
93
        return \call_user_func_array([$this->createMessage(), $name], $arguments);
94
    }
95
96
    /**
97
     * Create a new message with defaults.
98
     *
99
     * @return \Nexy\Slack\Message
100
     */
101
    public function createMessage()
102
    {
103
        $message = new Message($this);
104
105
        $message->setChannel($this->options['channel']);
106
107
        $message->setUsername($this->options['username']);
108
109
        $message->setIcon($this->options['icon']);
110
111
        $message->setAllowMarkdown($this->options['allow_markdown']);
112
113
        $message->setMarkdownInAttachments($this->options['markdown_in_attachments']);
114
115
        return $message;
116
    }
117
118
    /**
119
     * Send a message.
120
     *
121
     * @param \Nexy\Slack\Message $message
122
     *
123
     * @throws Exception
124
     */
125
    public function sendMessage(Message $message): void
126
    {
127
        $payload = $this->preparePayload($message);
128
129
        $encoded = \json_encode($payload, JSON_UNESCAPED_UNICODE);
130
131
        if (false === $encoded) {
0 ignored issues
show
introduced by
The condition false === $encoded can never be true.
Loading history...
132
            throw new \RuntimeException(\sprintf('JSON encoding error %s: %s', \json_last_error(), \json_last_error_msg()));
133
        }
134
135
        $this->httpClient->post('', [], $encoded);
136
    }
137
138
    /**
139
     * Prepares the payload to be sent to the webhook.
140
     *
141
     * @param \Nexy\Slack\Message $message The message to send
142
     *
143
     * @return array
144
     */
145
    public function preparePayload(Message $message)
146
    {
147
        $payload = [
148
            'text' => $message->getText(),
149
            'channel' => $message->getChannel(),
150
            'username' => $message->getUsername(),
151
            'link_names' => $this->options['link_names'] ? 1 : 0,
152
            'unfurl_links' => $this->options['unfurl_links'],
153
            'unfurl_media' => $this->options['unfurl_media'],
154
            'mrkdwn' => $this->options['allow_markdown'],
155
        ];
156
157
        if ($icon = $message->getIcon()) {
158
            $payload[$message->getIconType()] = $icon;
159
        }
160
161
        $payload['attachments'] = $this->getAttachmentsAsArrays($message);
162
163
        return $payload;
164
    }
165
166
    /**
167
     * Get the attachments in array form.
168
     *
169
     * @param \Nexy\Slack\Message $message
170
     *
171
     * @return array
172
     */
173
    private function getAttachmentsAsArrays(Message $message)
174
    {
175
        $attachments = [];
176
177
        foreach ($message->getAttachments() as $attachment) {
178
            $attachments[] = $attachment->toArray();
179
        }
180
181
        return $attachments;
182
    }
183
}
184