Test Failed
Push — master ( bd1e8a...fed951 )
by Alexey
12:42 queued 12s
created

SlackMessageBuilder::getAttachment()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 25
rs 9.52
c 0
b 0
f 0
cc 4
nc 8
nop 1
1
<?php
2
3
/*
4
 * This file is part of the WoW-Apps/Symfony-Slack-Bot bundle for Symfony.
5
 * https://github.com/wow-apps/symfony-slack-bot
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 * https://github.com/wow-apps/symfony-slack-bot/blob/master/LICENSE
10
 *
11
 * For technical documentation.
12
 * https://wow-apps.github.io/symfony-slack-bot/docs/
13
 *
14
 * Author Alexey Samara <[email protected]>
15
 *
16
 * Copyright 2016 WoW-Apps.
17
 */
18
19
namespace WowApps\SlackBundle\Service;
20
21
use WowApps\SlackBundle\DTO\Attachment;
22
use WowApps\SlackBundle\DTO\AttachmentAction;
23
use WowApps\SlackBundle\DTO\AttachmentField;
24
use WowApps\SlackBundle\DTO\SlackMessage;
25
use WowApps\SlackBundle\Exception\SlackbotException;
26
27
/**
28
 * Class SlackAdapter.
29
 *
30
 * @author Alexey Samara <[email protected]>
31
 */
32
class SlackMessageBuilder
33
{
34
    /** @var array */
35
    private $config;
36
37
    /** @var SlackColor */
38
    private $color;
39
40
    /** @var SlackMessage */
41
    private $slackMessage;
42
43
    /** @var array */
44
    private $requestBody;
45
46
    /**
47
     * SlackAdapter constructor.
48
     *
49
     * @param array      $config
50
     * @param SlackColor $slackColor
51
     */
52
    public function __construct(array $config, SlackColor $slackColor)
53
    {
54
        $this->config = $config;
55
        $this->color = $slackColor;
56
    }
57
58
    /**
59
     * @param SlackMessage $slackMessage
60
     *
61
     * @return string
62
     *
63
     * @throws SlackbotException
64
     */
65
    public function buildRequestBody(SlackMessage $slackMessage): string
66
    {
67
        $this->requestBody = [];
68
69
        $this->slackMessage = $slackMessage;
70
71
        $this->setDefaults();
72
73
        SlackMessageValidator::validateMessage($this->slackMessage);
74
75
        $json = json_encode(
76
            $this->buildJsonFromDto(),
77
            JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES
78
        );
79
80
        if (!$json) {
81
            throw new SlackbotException(SlackbotException::E_CONVERT_MESSAGE_TO_JSON);
82
        }
83
84
        return $json;
85
    }
86
87
    private function setDefaults()
88
    {
89
        if (empty($this->slackMessage->getUsername())) {
90
            $this->slackMessage->setUsername($this->config['default_username']);
91
        }
92
93
        if (empty($this->slackMessage->getChannel())) {
94
            $this->slackMessage->setChannel($this->config['default_channel']);
95
        }
96
97
        if (empty($this->slackMessage->getIconUrl()) && empty($this->slackMessage->getIconEmoji())) {
98
            $this->slackMessage->setIconUrl($this->config['default_icon_url']);
99
        }
100
    }
101
102
    /**
103
     * @return array
104
     */
105
    private function buildJsonFromDto(): array
106
    {
107
        $this->getSimpleMessage();
108
109
        $this->getMessageIcon();
110
111
        if (!empty($this->slackMessage->getAttachments())) {
112
            foreach ($this->slackMessage->getAttachments() as $attachment) {
113
                $this->getAttachment(
114
                    $this->setAttachmentDefaults($attachment)
115
                );
116
            }
117
        }
118
119
        return $this->requestBody;
120
    }
121
122
    private function getSimpleMessage()
123
    {
124
        $this->requestBody = [
125
            'username' => $this->slackMessage->getUsername(),
126
            'channel' => $this->slackMessage->getChannel(),
127
            'mrkdwn' => $this->slackMessage->isMarkdown(),
128
            'text' => $this->slackMessage->getText(),
129
        ];
130
    }
131
132
    private function getMessageIcon()
133
    {
134
        if (!empty($this->slackMessage->getIconUrl())) {
135
            $this->requestBody['icon_url'] = $this->slackMessage->getIconUrl();
136
137
            return;
138
        }
139
140
        if (!empty($this->slackMessage->getIconEmoji())) {
141
            $this->requestBody['icon_emoji'] = $this->slackMessage->getIconEmoji();
142
        }
143
    }
144
145
    /**
146
     * @param Attachment $attachment
147
     *
148
     * @return Attachment
149
     */
150
    private function setAttachmentDefaults(Attachment $attachment): Attachment
151
    {
152
        if (empty($attachment->getColor())) {
153
            $attachment->setColor(SlackColor::COLOR_DEFAULT);
154
        }
155
156
        if (empty($attachment->getFallback())) {
157
            $attachment->setFallback($this->config['default_fallback']);
158
        }
159
160
        return $attachment;
161
    }
162
163
    /**
164
     * @param Attachment $attachment
165
     */
166
    private function getAttachment(Attachment $attachment)
167
    {
168
        $attachmentArray = [
169
            'color' => $this->color->getHex($attachment->getColor()),
170
            'fallback' => $attachment->getFallback(),
171
            'pretext' => $attachment->getPretext(),
172
            'author_name' => $attachment->getAuthorName(),
173
            'author_link' => $attachment->getAuthorLink(),
174
            'author_icon' => $attachment->getAuthorIconUrl(),
175
            'title' => $attachment->getTitle(),
176
            'title_link' => $attachment->getTitleLink(),
177
            'text' => $attachment->getText(),
178
            'image_url' => $attachment->getImageUrl(),
179
            'thumb_url' => $attachment->getThumbUrl(),
180
            'footer' => $attachment->getFooter(),
181
            'footer_icon' => $attachment->getFooterIconUrl(),
182
            'ts' => $attachment->getTimestamp(),
183
            'fields' => empty($attachment->getFields()) ? [] : $this->getFields($attachment->getFields()),
184
            'actions' => empty($attachment->getActions()) ? [] : $this->getActions($attachment->getActions()),
185
        ];
186
187
        if (!empty($attachmentArray)) {
188
            $this->requestBody['attachments'][] = $this->removeEmptyItems($attachmentArray);
189
        }
190
    }
191
192
    /**
193
     * @param AttachmentAction[] $actions
194
     *
195
     * @return array
196
     */
197
    private function getActions(array $actions): array
198
    {
199
        $actionsArray = [];
200
        foreach ($actions as $action) {
201
            $actionArray = [
202
                'name' => $action->getName(),
203
                'text' => $action->getText(),
204
                'url' => $action->getUrl(),
205
                'style' => $action->getStyle(),
206
                'type' => $action->getType(),
207
                'value' => $action->getValue(),
208
            ];
209
210
            if ($action->getConfirm()->isActive()) {
211
                $confirm = [
212
                    'title' => $action->getConfirm()->getTitle(),
213
                    'text' => $action->getConfirm()->getText(),
214
                    'ok_text' => $action->getConfirm()->getButtonOkText(),
215
                    'dismiss_text' => $action->getConfirm()->getButtonDismissText(),
216
                ];
217
218
                $actionArray['confirm'] = $this->removeEmptyItems($confirm);
219
            }
220
221
            $actionsArray[] = $this->removeEmptyItems($actionArray);
222
        }
223
224
        return $actionsArray;
225
    }
226
227
    /**
228
     * @param AttachmentField[] $fields
229
     *
230
     * @return array
231
     */
232
    private function getFields(array $fields): array
233
    {
234
        $fieldsArray = [];
235
        foreach ($fields as $field) {
236
            $fieldArray = [
237
                'title' => $field->getTitle(),
238
                'value' => $field->getValue(),
239
                'short' => $field->isShort(),
240
            ];
241
242
            $fieldsArray[] = $this->removeEmptyItems($fieldArray);
243
        }
244
245
        return $fieldsArray;
246
    }
247
248
    /**
249
     * @param array $array
250
     *
251
     * @return array
252
     */
253
    private function removeEmptyItems(array $array): array
254
    {
255
        foreach ($array as $key => $value) {
256
            if (!is_bool($value) && empty($value)) {
257
                unset($array[$key]);
258
            }
259
        }
260
261
        return $array;
262
    }
263
}
264