SlackHandler::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 13
nc 2
nop 10
dl 0
loc 20
rs 9.8333
c 0
b 0
f 0

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/*
4
 * This file is part of the Monolog package.
5
 *
6
 * (c) Jordi Boggiano <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Monolog\Handler;
13
14
use Monolog\Formatter\FormatterInterface;
15
use Monolog\Logger;
16
use Monolog\Handler\Slack\SlackRecord;
17
18
/**
19
 * Sends notifications through Slack API
20
 *
21
 * @author Greg Kedzierski <[email protected]>
22
 * @see    https://api.slack.com/
23
 */
24
class SlackHandler extends SocketHandler
25
{
26
    /**
27
     * Slack API token
28
     * @var string
29
     */
30
    private $token;
31
32
    /**
33
     * Instance of the SlackRecord util class preparing data for Slack API.
34
     * @var SlackRecord
35
     */
36
    private $slackRecord;
37
38
    /**
39
     * @param  string                    $token                  Slack API token
40
     * @param  string                    $channel                Slack channel (encoded ID or name)
41
     * @param  string|null               $username               Name of a bot
42
     * @param  bool                      $useAttachment          Whether the message should be added to Slack as attachment (plain text otherwise)
43
     * @param  string|null               $iconEmoji              The emoji name to use (or null)
44
     * @param  int                       $level                  The minimum logging level at which this handler will be triggered
45
     * @param  bool                      $bubble                 Whether the messages that are handled can bubble up the stack or not
46
     * @param  bool                      $useShortAttachment     Whether the the context/extra messages added to Slack as attachments are in a short style
47
     * @param  bool                      $includeContextAndExtra Whether the attachment should include context and extra data
48
     * @param  array                     $excludeFields          Dot separated list of fields to exclude from slack message. E.g. ['context.field1', 'extra.field2']
49
     * @throws MissingExtensionException If no OpenSSL PHP extension configured
50
     */
51
    public function __construct($token, $channel, $username = null, $useAttachment = true, $iconEmoji = null, $level = Logger::CRITICAL, $bubble = true, $useShortAttachment = false, $includeContextAndExtra = false, array $excludeFields = array())
52
    {
53
        if (!extension_loaded('openssl')) {
54
            throw new MissingExtensionException('The OpenSSL PHP extension is required to use the SlackHandler');
55
        }
56
57
        parent::__construct('ssl://slack.com:443', $level, $bubble);
58
59
        $this->slackRecord = new SlackRecord(
60
            $channel,
61
            $username,
62
            $useAttachment,
63
            $iconEmoji,
64
            $useShortAttachment,
65
            $includeContextAndExtra,
66
            $excludeFields,
67
            $this->formatter
68
        );
69
70
        $this->token = $token;
71
    }
72
73
    public function getSlackRecord()
74
    {
75
        return $this->slackRecord;
76
    }
77
78
    /**
79
     * {@inheritdoc}
80
     *
81
     * @param  array  $record
82
     * @return string
83
     */
84
    protected function generateDataStream($record)
85
    {
86
        $content = $this->buildContent($record);
87
88
        return $this->buildHeader($content) . $content;
89
    }
90
91
    /**
92
     * Builds the body of API call
93
     *
94
     * @param  array  $record
95
     * @return string
96
     */
97
    private function buildContent($record)
98
    {
99
        $dataArray = $this->prepareContentData($record);
100
101
        return http_build_query($dataArray);
102
    }
103
104
    /**
105
     * Prepares content data
106
     *
107
     * @param  array $record
108
     * @return array
109
     */
110
    protected function prepareContentData($record)
111
    {
112
        $dataArray = $this->slackRecord->getSlackData($record);
113
        $dataArray['token'] = $this->token;
114
115
        if (!empty($dataArray['attachments'])) {
116
            $dataArray['attachments'] = json_encode($dataArray['attachments']);
117
        }
118
119
        return $dataArray;
120
    }
121
122
    /**
123
     * Builds the header of the API Call
124
     *
125
     * @param  string $content
126
     * @return string
127
     */
128
    private function buildHeader($content)
129
    {
130
        $header = "POST /api/chat.postMessage HTTP/1.1\r\n";
131
        $header .= "Host: slack.com\r\n";
132
        $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
133
        $header .= "Content-Length: " . strlen($content) . "\r\n";
134
        $header .= "\r\n";
135
136
        return $header;
137
    }
138
139
    /**
140
     * {@inheritdoc}
141
     *
142
     * @param array $record
143
     */
144
    protected function write(array $record)
145
    {
146
        parent::write($record);
147
        $this->finalizeWrite();
148
    }
149
150
    /**
151
     * Finalizes the request by reading some bytes and then closing the socket
152
     *
153
     * If we do not read some but close the socket too early, slack sometimes
154
     * drops the request entirely.
155
     */
156
    protected function finalizeWrite()
157
    {
158
        $res = $this->getResource();
159
        if (is_resource($res)) {
160
            @fread($res, 2048);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition for fread(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

160
            /** @scrutinizer ignore-unhandled */ @fread($res, 2048);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
161
        }
162
        $this->closeSocket();
163
    }
164
165
    /**
166
     * Returned a Slack message attachment color associated with
167
     * provided level.
168
     *
169
     * @param  int    $level
170
     * @return string
171
     * @deprecated Use underlying SlackRecord instead
172
     */
173
    protected function getAttachmentColor($level)
174
    {
175
        trigger_error(
176
            'SlackHandler::getAttachmentColor() is deprecated. Use underlying SlackRecord instead.',
177
            E_USER_DEPRECATED
178
        );
179
180
        return $this->slackRecord->getAttachmentColor($level);
181
    }
182
183
    /**
184
     * Stringifies an array of key/value pairs to be used in attachment fields
185
     *
186
     * @param  array  $fields
187
     * @return string
188
     * @deprecated Use underlying SlackRecord instead
189
     */
190
    protected function stringify($fields)
191
    {
192
        trigger_error(
193
            'SlackHandler::stringify() is deprecated. Use underlying SlackRecord instead.',
194
            E_USER_DEPRECATED
195
        );
196
197
        return $this->slackRecord->stringify($fields);
198
    }
199
200
    public function setFormatter(FormatterInterface $formatter)
201
    {
202
        parent::setFormatter($formatter);
203
        $this->slackRecord->setFormatter($formatter);
204
205
        return $this;
206
    }
207
208
    public function getFormatter()
209
    {
210
        $formatter = parent::getFormatter();
211
        $this->slackRecord->setFormatter($formatter);
212
213
        return $formatter;
214
    }
215
}
216