Passed
Push — master ( 812a3e...51b807 )
by Frank
02:09
created

AbstractCommand::postMessage()   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 14
nc 6
nop 2
dl 0
loc 19
ccs 15
cts 15
cp 1
crap 5
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * T3Bot.
4
 *
5
 * @author Frank Nägler <[email protected]>
6
 *
7
 * @link http://www.t3bot.de
8
 * @link http://wiki.typo3.org/T3Bot
9
 */
10
namespace T3Bot\Commands;
11
12
use /* @noinspection PhpInternalEntityUsedInspection */ Doctrine\DBAL\Configuration;
13
use Doctrine\DBAL\Connection;
14
use Doctrine\DBAL\DriverManager;
15
use Slack\DataObject;
16
use Slack\Message\Attachment;
17
use Slack\Payload;
18
use Slack\RealTimeClient;
19
use T3Bot\Slack\Message;
20
use T3Bot\Traits\ForgerTrait;
21
use T3Bot\Traits\GerritTrait;
22
use T3Bot\Traits\SlackTrait;
23
24
/**
25
 * Class AbstractCommand.
26
 *
27
 * @property string commandName
28
 * @property array helpCommands
29
 */
30
abstract class AbstractCommand
31
{
32
    use SlackTrait, ForgerTrait, GerritTrait;
33
34
    const PROJECT_PHASE_DEVELOPMENT = 'development';
35
    const PROJECT_PHASE_STABILISATION = 'stabilisation';
36
    const PROJECT_PHASE_SOFT_FREEZE = 'soft_freeze';
37
    const PROJECT_PHASE_CODE_FREEZE = 'code_freeze';
38
    const PROJECT_PHASE_FEATURE_FREEZE = 'feature_freeze';
39
40
    /**
41
     * @var string
42
     */
43
    protected $commandName;
44
45
    /**
46
     * @var array
47
     */
48
    protected $helpCommands = [];
49
50
    /**
51
     * @var array
52
     */
53
    protected $params = [];
54
55
    /**
56
     * @var Payload
57
     */
58
    protected $payload;
59
60
    /**
61
     * @var RealTimeClient
62
     */
63
    protected $client;
64
65
    /**
66
     * AbstractCommand constructor.
67
     *
68
     * @param Payload        $payload
69
     * @param RealTimeClient $client
70
     */
71 102
    public function __construct(Payload $payload, RealTimeClient $client)
72
    {
73 102
        $this->payload = $payload;
74 102
        $this->client = $client;
75 102
    }
76
77
    /**
78
     *
79
     */
80 46
    public function process()
81
    {
82 46
        $commandParts = explode(':', $this->payload->getData()['text']);
83 46
        $params = [];
84 46
        if (!empty($commandParts[1])) {
85 46
            array_shift($commandParts);
86 46
            $params = explode(' ', preg_replace('/\s+/', ' ', implode(':', $commandParts)));
87
        }
88
89 46
        $command = !empty($params[0]) ? $params[0] : 'help';
90 46
        $this->params = $params;
91 46
        $method = 'process' . ucfirst(strtolower($command));
92 46
        if (method_exists($this, $method)) {
93 45
            return $this->{$method}();
94
        }
95
96 1
        return $this->getHelp();
97
    }
98
99
    /**
100
     * @param Message|string $messageToSent
101
     * @param string $user
102
     * @param string $channel the channel id
103
     */
104 2
    public function sendResponse($messageToSent, $user = null, $channel = null)
105
    {
106 2
        if ($user !== null) {
107
            $this->client->apiCall('im.open', ['user' => $user])
108
                ->then(function (Payload $response) use ($messageToSent) {
109
                    $channel = $response->getData()['channel']['id'];
110
                    $this->postMessage($messageToSent, $channel);
111
                });
112
        } else {
113 2
            $channel = $channel ?? $this->payload->getData()['channel'];
114 2
            $this->postMessage($messageToSent, $channel);
115
        }
116 2
    }
117
118
    /**
119
     * generate help.
120
     *
121
     * @return string
122
     */
123 1
    public function getHelp() : string
124
    {
125 1
        $result = "*HELP*\n";
126 1
        foreach ($this->helpCommands as $command => $helpText) {
127 1
            $result .= "*{$this->commandName}:{$command}*: {$helpText} \n";
128
        }
129
130 1
        return $result;
131
    }
132
133
    /**
134
     * build a review message.
135
     *
136
     * @param \stdClass $item the review item
137
     *
138
     * @return Message
139
     */
140 12
    protected function buildReviewMessage($item) : Message
141
    {
142 12
        $created = substr($item->created, 0, 19);
143 12
        $branch = $item->branch;
144 12
        $text = '';
145
146 12
        $message = new Message();
147 12
        $attachment = new Message\Attachment();
148 12
        switch ($GLOBALS['config']['projectPhase']) {
149 12
            case self::PROJECT_PHASE_STABILISATION:
150 1
                $attachment->setColor(Message\Attachment::COLOR_WARNING);
151 1
                $attachment->setPretext(':warning: *stabilisation phase*');
152 1
                break;
153 11
            case self::PROJECT_PHASE_SOFT_FREEZE:
154 1
                $attachment->setColor(Message\Attachment::COLOR_DANGER);
155 1
                $attachment->setPretext(':no_entry: *soft merge freeze*');
156 1
                break;
157 10
            case self::PROJECT_PHASE_CODE_FREEZE:
158 1
                $attachment->setColor(Message\Attachment::COLOR_DANGER);
159 1
                $attachment->setPretext(':no_entry: *merge freeze*');
160 1
                break;
161 9
            case self::PROJECT_PHASE_FEATURE_FREEZE:
162 1
                $attachment->setColor(Message\Attachment::COLOR_DANGER);
163 1
                $attachment->setPretext(':no_entry: *FEATURE FREEZE*');
164 1
                break;
165 8
            case self::PROJECT_PHASE_DEVELOPMENT:
166
            default:
167 8
                $attachment->setColor(Message\Attachment::COLOR_NOTICE);
168 8
                break;
169
        }
170 12
        $attachment->setTitle($item->subject);
171 12
        $attachment->setTitleLink('https://review.typo3.org/' . $item->_number);
172
173 12
        $text .= 'Branch: ' . $this->bold($branch) . ' | :calendar: ' . $this->bold($created)
174 12
            . ' | ID: ' . $this->bold($item->_number) . "\n";
175 12
        $text .= '<https://review.typo3.org/' . $item->_number . '|:arrow_right: Goto Review>';
176
177 12
        $attachment->setText($text);
178 12
        $attachment->setFallback($text);
179 12
        $message->setText(' ');
180 12
        $message->addAttachment($attachment);
181
182 12
        return $message;
183
    }
184
185
    /**
186
     * @param string $text
187
     * @param string $channel
188
     *
189
     * @return array
190
     */
191 2
    protected function getBaseDataArray(string $text, string $channel) : array
192
    {
193 2
        $data = [];
194 2
        $data['unfurl_links'] = false;
195 2
        $data['unfurl_media'] = false;
196 2
        $data['parse'] = 'none';
197 2
        $data['text'] = $text;
198 2
        $data['channel'] = $channel;
199 2
        return $data;
200
    }
201
202
    /**
203
     * @param Message\Attachment $attachment
204
     *
205
     * @return DataObject
206
     */
207 1
    protected function buildAttachment(Message\Attachment $attachment) : DataObject
208
    {
209 1
        return Attachment::fromData([
210 1
            'title' => $attachment->getTitle(),
211 1
            'title_link' => $attachment->getTitleLink(),
212 1
            'text' => $attachment->getText(),
213 1
            'fallback' => $attachment->getFallback(),
214 1
            'color' => $attachment->getColor(),
215 1
            'pretext' => $attachment->getPretext(),
216 1
            'author_name' => $attachment->getAuthorName(),
217 1
            'author_icon' => $attachment->getAuthorIcon(),
218 1
            'author_link' => $attachment->getAuthorLink(),
219 1
            'image_url' => $attachment->getImageUrl(),
220 1
            'thumb_url' => $attachment->getThumbUrl(),
221
        ]);
222
    }
223
224
    /**
225
     * @param Message|string $messageToSent
226
     * @param string $channel
227
     */
228 2
    protected function postMessage($messageToSent, string $channel)
229
    {
230 2
        if ($messageToSent instanceof Message) {
231 1
            $data = $this->getBaseDataArray($messageToSent->getText(), $channel);
232 1
            $attachments = $messageToSent->getAttachments();
233 1
            if (count($attachments)) {
234 1
                $data['attachments'] = [];
235
            }
236 1
            foreach ($attachments as $attachment) {
237 1
                $data['attachments'][] = $this->buildAttachment($attachment);
238
            }
239 1
            $message = new \Slack\Message\Message($this->client, $data);
240 1
            $this->client->postMessage($message);
241 1
        } elseif (is_string($messageToSent)) {
242 1
            $data = $this->getBaseDataArray($messageToSent, $channel);
243 1
            $data['as_user'] = true;
244 1
            $this->client->apiCall('chat.postMessage', $data);
245
        }
246 2
    }
247
248
    /**
249
     * @return Connection
250
     *
251
     * @throws \Doctrine\DBAL\DBALException
252
     */
253 11
    protected function getDatabaseConnection() : Connection
254
    {
255 11
        if (empty($GLOBALS['DB'])) {
256 11
            $config = new Configuration();
257 11
            $GLOBALS['DB'] = DriverManager::getConnection($GLOBALS['config']['db'], $config);
258
        }
259
260 11
        return $GLOBALS['DB'];
261
    }
262
}
263