AbstractCommand::sendResponse()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.5

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 5
cts 10
cp 0.5
rs 9.8333
c 0
b 0
f 0
cc 2
nc 2
nop 3
crap 2.5
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\Payload;
16
use Slack\RealTimeClient;
17
use T3Bot\Slack\Message;
18
use T3Bot\Traits\ForgerTrait;
19
use T3Bot\Traits\GerritTrait;
20
use T3Bot\Traits\SlackTrait;
21
22
/**
23
 * Class AbstractCommand.
24
 *
25
 * @property string commandName
26
 * @property array helpCommands
27
 */
28
abstract class AbstractCommand
29
{
30
    use SlackTrait, ForgerTrait, GerritTrait;
31
32
    const PROJECT_PHASE_DEVELOPMENT = 'development';
33
    const PROJECT_PHASE_STABILISATION = 'stabilisation';
34
    const PROJECT_PHASE_SOFT_FREEZE = 'soft_freeze';
35
    const PROJECT_PHASE_CODE_FREEZE = 'code_freeze';
36
    const PROJECT_PHASE_FEATURE_FREEZE = 'feature_freeze';
37
38
    /**
39
     * @var string
40
     */
41
    protected $commandName;
42
43
    /**
44
     * @var array
45
     */
46
    protected $helpCommands = [];
47
48
    /**
49
     * @var array
50
     */
51
    protected $params = [];
52
53
    /**
54
     * @var Payload
55
     */
56
    protected $payload;
57
58
    /**
59
     * @var RealTimeClient
60
     */
61
    protected $client;
62
63
    /**
64
     * @var array|null
65
     */
66
    protected $configuration;
67
68
    /**
69
     * @var Connection
70
     */
71
    protected $databaseConnection;
72
73
    /**
74
     * @var array
75
     */
76
    protected $colors = [
77
        self::PROJECT_PHASE_STABILISATION => Message\Attachment::COLOR_WARNING,
78
        self::PROJECT_PHASE_SOFT_FREEZE => Message\Attachment::COLOR_DANGER,
79
        self::PROJECT_PHASE_CODE_FREEZE => Message\Attachment::COLOR_DANGER,
80
        self::PROJECT_PHASE_FEATURE_FREEZE => Message\Attachment::COLOR_DANGER,
81
    ];
82
83
    /**
84
     * @var array
85
     */
86
    protected $preTexts = [
87
        self::PROJECT_PHASE_STABILISATION => ':warning: *stabilisation phase*',
88
        self::PROJECT_PHASE_SOFT_FREEZE => ':no_entry: *soft merge freeze*',
89
        self::PROJECT_PHASE_CODE_FREEZE => ':no_entry: *merge freeze*',
90
        self::PROJECT_PHASE_FEATURE_FREEZE => ':no_entry: *FEATURE FREEZE*',
91
    ];
92
93
    /**
94
     * AbstractCommand constructor.
95
     *
96
     * @param Payload $payload
97
     * @param RealTimeClient $client
98
     * @param array|null $configuration
99
     */
100 105
    public function __construct(Payload $payload, RealTimeClient $client, array $configuration = null)
101
    {
102 105
        $this->payload = $payload;
103 105
        $this->client = $client;
104 105
        $this->configuration = $configuration;
105 105
    }
106
107
    /**
108
     *
109
     */
110 47
    public function process()
111
    {
112 47
        $commandParts = explode(':', $this->payload->getData()['text']);
113 47
        $params = [];
114 47
        if (!empty($commandParts[1])) {
115 47
            array_shift($commandParts);
116 47
            $params = explode(' ', preg_replace('/\s+/', ' ', implode(':', $commandParts)));
117
        }
118
119 47
        $command = !empty($params[0]) ? $params[0] : 'help';
120 47
        $this->params = $params;
121 47
        $method = 'process' . ucfirst(strtolower($command));
122 47
        if (method_exists($this, $method)) {
123 46
            return $this->{$method}();
124
        }
125
126 1
        return $this->getHelp();
127
    }
128
129
    /**
130
     * @param Message|string $messageToSent
131
     * @param string $user
132
     * @param string $channel the channel id
133
     */
134 2
    public function sendResponse($messageToSent, $user = null, $channel = null)
135
    {
136 2
        if ($user !== null) {
137
            $this->client->apiCall('im.open', ['user' => $user])
138
                ->then(function (Payload $response) use ($messageToSent) {
139
                    $channel = $response->getData()['channel']['id'];
140
                    $this->postMessage($messageToSent, $channel);
141
                });
142
        } else {
143 2
            $channel = $channel ?? $this->payload->getData()['channel'];
144 2
            $this->postMessage($messageToSent, $channel);
145
        }
146 2
    }
147
148
    /**
149
     * generate help.
150
     *
151
     * @return string
152
     */
153 1
    public function getHelp() : string
154
    {
155 1
        $result = '*HELP*' . chr(10);
156 1
        foreach ($this->helpCommands as $command => $helpText) {
157 1
            $result .= "*{$this->commandName}:{$command}*: {$helpText}" . chr(10);
158
        }
159
160 1
        return $result;
161
    }
162
163
    /**
164
     * build a review message.
165
     *
166
     * @param \stdClass $item the review item
167
     *
168
     * @return Message
169
     */
170 12
    protected function buildReviewMessage($item) : Message
171
    {
172 12
        $created = substr($item->created, 0, 19);
173 12
        $branch = $item->branch;
174
175 12
        $color = $this->colors[$this->configuration['projectPhase']] ?? Message\Attachment::COLOR_NOTICE;
176 12
        $preText = $this->preTexts[$this->configuration['projectPhase']] ?? '';
177
178 12
        $message = new Message();
179 12
        $attachment = new Message\Attachment();
180 12
        $attachment->setColor($color);
181 12
        $attachment->setPretext($preText);
182 12
        $attachment->setTitle($item->subject);
183 12
        $attachment->setTitleLink('https://review.typo3.org/' . $item->_number);
184
185 12
        $text = 'Branch: ' . $this->bold($branch) . ' | :calendar: ' . $this->bold($created)
186 12
            . ' | ID: ' . $this->bold($item->_number) . chr(10);
187 12
        $text .= '<https://review.typo3.org/' . $item->_number . '|:arrow_right: Goto Review>';
188
189 12
        $attachment->setText($text);
190 12
        $attachment->setFallback($text);
191 12
        $message->setText(' ');
192 12
        $message->addAttachment($attachment);
193
194 12
        return $message;
195
    }
196
197
    /**
198
     * @param Message|string $messageToSent
199
     * @param string $channel
200
     */
201 2
    protected function postMessage($messageToSent, string $channel)
202
    {
203 2
        if ($messageToSent instanceof Message) {
204 1
            $data = $this->getBaseDataArray($messageToSent->getText(), $channel);
205 1
            $attachments = $messageToSent->getAttachments();
206 1 View Code Duplication
            if (count($attachments)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
207 1
                $data['attachments'] = [];
208 1
                foreach ($attachments as $attachment) {
209 1
                    $data['attachments'][] = $this->buildAttachment($attachment);
210
                }
211
            }
212 1
            $message = new \Slack\Message\Message($this->client, $data);
213 1
            $this->client->postMessage($message);
214 1
        } elseif (is_string($messageToSent)) {
215 1
            $data = $this->getBaseDataArray($messageToSent, $channel);
216 1
            $data['as_user'] = true;
217 1
            $this->client->apiCall('chat.postMessage', $data);
218
        }
219 2
    }
220
221
    /**
222
     * @return Connection
223
     *
224
     * @throws \Doctrine\DBAL\DBALException
225
     */
226 11
    protected function getDatabaseConnection() : Connection
227
    {
228 11
        if ($this->databaseConnection === null) {
229 11
            $config = new Configuration();
230 11
            $this->databaseConnection = DriverManager::getConnection($this->configuration['db'], $config);
231
        }
232 11
        return $this->databaseConnection;
233
    }
234
}
235