Passed
Push — master ( 9f08e1...9b4776 )
by Patrick
01:29
created

JiraHandler::__construct()   A

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
150 1
        $body = json_encode([
151
            'fields' => [
152
                'project' => [
153 1
                    'id' => $projectId,
154
                ],
155 1
                'issuetype' => ['id' => $issueTypeId],
156 1
                'summary' => sprintf('%s: %s', $highestRecord['level_name'], $highestRecord['message']),
157 1
                'description' => $content,
158 1
                $hashFieldId => $hash,
159 1
                $countFieldId => 1,
160
            ],
161
        ]);
162 1
        $uri = $this->urlFactory->createUri(sprintf('https://%s/rest/api/2/issue', $this->hostname));
163 1
        $request = $this->requestFactory->createRequest('POST', $uri)->withBody($this->streamFactory->createStream($body));
164 1
        $response = $this->httpClient->sendRequest($request);
165 1
        $data = json_decode($response->getBody()->getContents(), true);
166 1
        $this->createdIssueId = $data['id'];
167 1
    }
168
169 1
    protected function parseProjectId(array $data): int
170
    {
171 1
        return (int) $data['projects'][0]['id'];
172
    }
173
174 1
    protected function parseIssueType(array $data, string $issueTypeName): array
175
    {
176
        return array_values(array_filter($data['projects'][0]['issuetypes'], function ($data) use ($issueTypeName) {
177 1
            return $data['name'] === $issueTypeName;
178 1
        }))[0];
179
    }
180
181 2
    protected function parseCustomFieldId(array $data, string $part, string $fieldName): string
182
    {
183
        return array_values(array_filter($data[$part], function ($item) use ($fieldName) {
184 2
            return $item['name'] === $fieldName;
185 2
        }))[0]['id'];
186
    }
187
188 1
    public function getCreatedIssueId()
189
    {
190 1
        return $this->createdIssueId;
191
    }
192
}
193