Passed
Push — master ( 51b807...3f897c )
by Frank
02:13
created

AbstractCommand::sendResponse()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2.5

Importance

Changes 0
Metric Value
cc 2
eloc 9
nc 2
nop 3
dl 0
loc 13
ccs 5
cts 10
cp 0.5
crap 2.5
rs 9.4285
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
     * @var array
67
     */
68
    protected $configuration;
69
70
    /**
71
     * @var Connection
72
     */
73
    protected $databaseConnection;
74
75
    /**
76
     * AbstractCommand constructor.
77
     *
78
     * @param Payload $payload
79
     * @param RealTimeClient $client
80
     * @param array $configuration
81
     */
82 102
    public function __construct(Payload $payload, RealTimeClient $client, array $configuration = null)
83
    {
84 102
        $this->payload = $payload;
85 102
        $this->client = $client;
86 102
        $this->configuration = $configuration;
0 ignored issues
show
Documentation Bug introduced by
It seems like $configuration can be null. However, the property $configuration is declared as array. Maybe change the type of the property to array|null or add a type check?

Our type inference engine has found an assignment of a scalar value (like a string, an integer or null) to a property which is an array.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.

To type hint that a parameter can be either an array or null, you can set a type hint of array and a default value of null. The PHP interpreter will then accept both an array or null for that parameter.

function aContainsB(array $needle = null, array  $haystack) {
    if (!$needle) {
        return false;
    }

    return array_intersect($haystack, $needle) == $haystack;
}

The function can be called with either null or an array for the parameter $needle but will only accept an array as $haystack.

Loading history...
87 102
    }
88
89
    /**
90
     *
91
     */
92 46
    public function process()
93
    {
94 46
        $commandParts = explode(':', $this->payload->getData()['text']);
95 46
        $params = [];
96 46
        if (!empty($commandParts[1])) {
97 46
            array_shift($commandParts);
98 46
            $params = explode(' ', preg_replace('/\s+/', ' ', implode(':', $commandParts)));
99
        }
100
101 46
        $command = !empty($params[0]) ? $params[0] : 'help';
102 46
        $this->params = $params;
103 46
        $method = 'process' . ucfirst(strtolower($command));
104 46
        if (method_exists($this, $method)) {
105 45
            return $this->{$method}();
106
        }
107
108 1
        return $this->getHelp();
109
    }
110
111
    /**
112
     * @param Message|string $messageToSent
113
     * @param string $user
114
     * @param string $channel the channel id
115
     */
116 2
    public function sendResponse($messageToSent, $user = null, $channel = null)
117
    {
118 2
        if ($user !== null) {
119
            $this->client->apiCall('im.open', ['user' => $user])
120
                ->then(function (Payload $response) use ($messageToSent) {
121
                    $channel = $response->getData()['channel']['id'];
122
                    $this->postMessage($messageToSent, $channel);
123
                });
124
        } else {
125 2
            $channel = $channel ?? $this->payload->getData()['channel'];
126 2
            $this->postMessage($messageToSent, $channel);
127
        }
128 2
    }
129
130
    /**
131
     * generate help.
132
     *
133
     * @return string
134
     */
135 1
    public function getHelp() : string
136
    {
137 1
        $result = "*HELP*\n";
138 1
        foreach ($this->helpCommands as $command => $helpText) {
139 1
            $result .= "*{$this->commandName}:{$command}*: {$helpText} \n";
140
        }
141
142 1
        return $result;
143
    }
144
145
    /**
146
     * build a review message.
147
     *
148
     * @param \stdClass $item the review item
149
     *
150
     * @return Message
151
     */
152 12
    protected function buildReviewMessage($item) : Message
153
    {
154 12
        $created = substr($item->created, 0, 19);
155 12
        $branch = $item->branch;
156 12
        $text = '';
157
158 12
        $message = new Message();
159 12
        $attachment = new Message\Attachment();
160 12
        switch ($this->configuration['projectPhase']) {
161 12
            case self::PROJECT_PHASE_STABILISATION:
162 1
                $attachment->setColor(Message\Attachment::COLOR_WARNING);
163 1
                $attachment->setPretext(':warning: *stabilisation phase*');
164 1
                break;
165 11
            case self::PROJECT_PHASE_SOFT_FREEZE:
166 1
                $attachment->setColor(Message\Attachment::COLOR_DANGER);
167 1
                $attachment->setPretext(':no_entry: *soft merge freeze*');
168 1
                break;
169 10
            case self::PROJECT_PHASE_CODE_FREEZE:
170 1
                $attachment->setColor(Message\Attachment::COLOR_DANGER);
171 1
                $attachment->setPretext(':no_entry: *merge freeze*');
172 1
                break;
173 9
            case self::PROJECT_PHASE_FEATURE_FREEZE:
174 1
                $attachment->setColor(Message\Attachment::COLOR_DANGER);
175 1
                $attachment->setPretext(':no_entry: *FEATURE FREEZE*');
176 1
                break;
177 8
            case self::PROJECT_PHASE_DEVELOPMENT:
178
            default:
179 8
                $attachment->setColor(Message\Attachment::COLOR_NOTICE);
180 8
                break;
181
        }
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) . "\n";
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 string $text
199
     * @param string $channel
200
     *
201
     * @return array
202
     */
203 2
    protected function getBaseDataArray(string $text, string $channel) : array
204
    {
205 2
        $data = [];
206 2
        $data['unfurl_links'] = false;
207 2
        $data['unfurl_media'] = false;
208 2
        $data['parse'] = 'none';
209 2
        $data['text'] = $text;
210 2
        $data['channel'] = $channel;
211 2
        return $data;
212
    }
213
214
    /**
215
     * @param Message\Attachment $attachment
216
     *
217
     * @return DataObject
218
     */
219 1
    protected function buildAttachment(Message\Attachment $attachment) : DataObject
220
    {
221 1
        return Attachment::fromData([
222 1
            'title' => $attachment->getTitle(),
223 1
            'title_link' => $attachment->getTitleLink(),
224 1
            'text' => $attachment->getText(),
225 1
            'fallback' => $attachment->getFallback(),
226 1
            'color' => $attachment->getColor(),
227 1
            'pretext' => $attachment->getPretext(),
228 1
            'author_name' => $attachment->getAuthorName(),
229 1
            'author_icon' => $attachment->getAuthorIcon(),
230 1
            'author_link' => $attachment->getAuthorLink(),
231 1
            'image_url' => $attachment->getImageUrl(),
232 1
            'thumb_url' => $attachment->getThumbUrl(),
233
        ]);
234
    }
235
236
    /**
237
     * @param Message|string $messageToSent
238
     * @param string $channel
239
     */
240 2
    protected function postMessage($messageToSent, string $channel)
241
    {
242 2
        if ($messageToSent instanceof Message) {
243 1
            $data = $this->getBaseDataArray($messageToSent->getText(), $channel);
244 1
            $attachments = $messageToSent->getAttachments();
245 1
            if (count($attachments)) {
246 1
                $data['attachments'] = [];
247
            }
248 1
            foreach ($attachments as $attachment) {
249 1
                $data['attachments'][] = $this->buildAttachment($attachment);
250
            }
251 1
            $message = new \Slack\Message\Message($this->client, $data);
252 1
            $this->client->postMessage($message);
253 1
        } elseif (is_string($messageToSent)) {
254 1
            $data = $this->getBaseDataArray($messageToSent, $channel);
255 1
            $data['as_user'] = true;
256 1
            $this->client->apiCall('chat.postMessage', $data);
257
        }
258 2
    }
259
260
    /**
261
     * @return Connection
262
     *
263
     * @throws \Doctrine\DBAL\DBALException
264
     */
265 11
    protected function getDatabaseConnection() : Connection
266
    {
267 11
        if ($this->databaseConnection === null) {
268 11
            $config = new Configuration();
269 11
            $this->databaseConnection = DriverManager::getConnection($this->configuration['db'], $config);
270
        }
271 11
        return $this->databaseConnection;
272
    }
273
}
274