JiraHandler::__construct()   A
last analyzed

Complexity

Conditions 2
Paths 1

Size

Total Lines 27
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 20
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 19
nc 1
nop 12
dl 0
loc 27
ccs 20
cts 20
cp 1
crap 2
rs 9.6333
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
declare(strict_types=1);
4
5
namespace Artack\Monolog\JiraHandler;
6
7
use Http\Client\Common\Plugin\AuthenticationPlugin;
8
use Http\Client\Common\Plugin\ContentLengthPlugin;
9
use Http\Client\Common\Plugin\HeaderDefaultsPlugin;
10
use Http\Client\Common\PluginClient;
11
use Http\Client\HttpClient;
12
use Http\Discovery\HttpClientDiscovery;
13
use Http\Discovery\Psr17FactoryDiscovery;
14
use Http\Message\Authentication\BasicAuth;
15
use Monolog\Logger;
16
17
class JiraHandler extends BatchHandler
18
{
19
    private $hostname;
20
    private $jql;
21
    private $hashFieldName;
22
    private $projectKey;
23
    private $issueTypeName;
24
    private $withComments;
25
    private $counterFieldName;
26
27
    private $requestFactory;
28
    private $urlFactory;
29
    private $streamFactory;
30
    private $httpClient;
31
32
    private $createdIssueId;
33
34 2
    public function __construct(string $hostname, string $username, string $password, string $jql, string $hashFieldName, string $projectKey, string $issueTypeName, bool $withComments = false, string $counterFieldName = null, HttpClient $httpClient = null, $level = Logger::DEBUG, $bubble = true)
35
    {
36 2
        parent::__construct($level, $bubble);
37
38 2
        $this->hostname = $hostname;
39 2
        $this->jql = $jql;
40 2
        $this->hashFieldName = $hashFieldName;
41 2
        $this->projectKey = $projectKey;
42 2
        $this->issueTypeName = $issueTypeName;
43 2
        $this->withComments = $withComments;
44 2
        $this->counterFieldName = $counterFieldName;
45
46 2
        $authentication = new BasicAuth($username, $password);
47 2
        $authenticationPlugin = new AuthenticationPlugin($authentication);
48
49 2
        $contentLengthPlugin = new ContentLengthPlugin();
50 2
        $headerDefaultsPlugin = new HeaderDefaultsPlugin([
51 2
            'Content-Type' => 'application/json',
52
        ]);
53
54 2
        $this->requestFactory = Psr17FactoryDiscovery::findRequestFactory();
55 2
        $this->urlFactory = Psr17FactoryDiscovery::findUrlFactory();
56 2
        $this->streamFactory = Psr17FactoryDiscovery::findStreamFactory();
57
58 2
        $this->httpClient = new PluginClient(
59 2
            $httpClient ?: HttpClientDiscovery::find(),
60 2
            [$authenticationPlugin, $headerDefaultsPlugin, $contentLengthPlugin]
61
        );
62 2
    }
63
64 2
    protected function send($content, array $records): void
65
    {
66 2
        $countFieldId = null;
67 2
        $highestRecord = $this->getHighestRecord($records);
68
69 2
        $recordForHash = $highestRecord;
70 2
        unset($recordForHash['datetime'], $recordForHash['formatted'], $recordForHash['context']);
71 2
        $hash = md5(serialize($recordForHash));
72
73 2
        $uri = $this->urlFactory->createUri(sprintf('https://%s/rest/api/2/customFields', $this->hostname));
74 2
        $request = $this->requestFactory->createRequest('GET', $uri);
75 2
        $response = $this->httpClient->sendRequest($request);
76 2
        $data = json_decode($response->getBody()->getContents(), true);
77 2
        $hashFieldId = $this->parseCustomFieldId($data, 'values', $this->hashFieldName);
78
79 2
        if ($this->counterFieldName) {
80 2
            $countFieldId = $this->parseCustomFieldId($data, 'values', $this->counterFieldName);
81
        }
82
83 2
        $jql = sprintf('%s AND %s ~ \'%s\'', $this->jql, $this->hashFieldName, $hash);
84
85
        $fields = [
86 2
            'issuetype',
87 2
            'status',
88 2
            'summary',
89 2
            $hashFieldId,
90 2
            $this->counterFieldName,
91
        ];
92
93 2
        if ($countFieldId) {
94 2
            $fields[] = $countFieldId;
95
        }
96
97 2
        $body = json_encode([
98 2
            'jql' => $jql,
99 2
            'fields' => $fields,
100
        ]);
101
102 2
        $uri = $this->urlFactory->createUri(sprintf('https://%s/rest/api/2/search', $this->hostname));
103 2
        $request = $this->requestFactory->createRequest('POST', $uri)->withBody($this->streamFactory->createStream($body));
104 2
        $response = $this->httpClient->sendRequest($request);
105 2
        $data = json_decode($response->getBody()->getContents(), true);
106
107 2
        if ($data['total'] > 0) {
108 1
            $issueId = $data['issues'][0]['id'];
109
110 1
            if ($this->counterFieldName) {
111 1
                $countFieldValue = $data['issues'][0]['fields'][$countFieldId];
112
113 1
                $uri = $this->urlFactory->createUri(sprintf('https://%s/rest/api/2/issue/%d', $this->hostname, $issueId).'?'.http_build_query([
114 1
                    'notifyUsers' => false,
115
                ]));
116
                $rawBody = [
117
                    'fields' => [
118 1
                        $countFieldId => ++$countFieldValue,
119
                    ],
120
                ];
121 1
                $body = json_encode($rawBody);
122 1
                $request = $this->requestFactory->createRequest('PUT', $uri)->withBody($this->streamFactory->createStream($body));
123 1
                $this->httpClient->sendRequest($request);
124
            }
125
126 1
            if ($this->withComments) {
127 1
                $uri = $this->urlFactory->createUri(sprintf('https://%s/rest/api/2/issue/%d/comment', $this->hostname, $issueId));
128 1
                $body = json_encode([
129 1
                    'body' => $content,
130
                ]);
131 1
                $request = $this->requestFactory->createRequest('POST', $uri)->withBody($this->streamFactory->createStream($body));
132 1
                $this->httpClient->sendRequest($request);
133
            }
134
135 1
            return;
136
        }
137
138 1
        $uri = $this->urlFactory->createUri(sprintf('https://%s/rest/api/2/issue/createmeta', $this->hostname).'?'.http_build_query([
139 1
            'projectKeys' => $this->projectKey,
140 1
            'expand' => 'projects.issuetypes.fields',
141
        ]));
142 1
        $request = $this->requestFactory->createRequest('GET', $uri);
143 1
        $response = $this->httpClient->sendRequest($request);
144 1
        $data = json_decode($response->getBody()->getContents(), true);
145
146 1
        $projectId = $this->parseProjectId($data);
147 1
        $issueType = $this->parseIssueType($data, $this->issueTypeName);
148 1
        $issueTypeId = (int) $issueType['id'];
149 1
        $summary = sprintf('%s: %s', $highestRecord['level_name'], $highestRecord['message']);
150
151 1
        $body = json_encode([
152
            'fields' => [
153
                'project' => [
154 1
                    'id' => $projectId,
155
                ],
156 1
                'issuetype' => ['id' => $issueTypeId],
157 1
                'summary' => strlen($summary) > 255 ? substr($summary, 0, 252).'...' : $summary,
158 1
                'description' => $content,
159 1
                $hashFieldId => $hash,
160 1
                $countFieldId => 1,
161
            ],
162
        ]);
163 1
        $uri = $this->urlFactory->createUri(sprintf('https://%s/rest/api/2/issue', $this->hostname));
164 1
        $request = $this->requestFactory->createRequest('POST', $uri)->withBody($this->streamFactory->createStream($body));
165 1
        $response = $this->httpClient->sendRequest($request);
166 1
        $data = json_decode($response->getBody()->getContents(), true);
167 1
        $this->createdIssueId = $data['id'];
168 1
    }
169
170 1
    protected function parseProjectId(array $data): int
171
    {
172 1
        return (int) $data['projects'][0]['id'];
173
    }
174
175 1
    protected function parseIssueType(array $data, string $issueTypeName): array
176
    {
177
        return array_values(array_filter($data['projects'][0]['issuetypes'], function ($data) use ($issueTypeName) {
178 1
            return $data['name'] === $issueTypeName;
179 1
        }))[0];
180
    }
181
182 2
    protected function parseCustomFieldId(array $data, string $part, string $fieldName): string
183
    {
184
        return array_values(array_filter($data[$part], function ($item) use ($fieldName) {
185 2
            return $item['name'] === $fieldName;
186 2
        }))[0]['id'];
187
    }
188
189 1
    public function getCreatedIssueId()
190
    {
191 1
        return $this->createdIssueId;
192
    }
193
}
194