MergeRequestApprovalService::transform()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 28
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 17
c 2
b 0
f 0
nc 1
nop 2
dl 0
loc 28
ccs 0
cts 18
cp 0
crap 2
rs 9.7
1
<?php declare(strict_types=1);
2
3
namespace DanielPieper\MergeReminder\Service;
4
5
use DanielPieper\MergeReminder\Exception\MergeRequestApprovalNotFoundException;
6
use DanielPieper\MergeReminder\Filter\MergeRequestApprovalFilter;
7
use DanielPieper\MergeReminder\ValueObject\MergeRequest;
8
use DanielPieper\MergeReminder\ValueObject\MergeRequestApproval;
9
use DanielPieper\MergeReminder\ValueObject\User;
10
use DanielPieper\MergeReminder\ValueObject\Group;
11
12
class MergeRequestApprovalService
13
{
14
    /** @var \Gitlab\Client */
15
    private $gitlabClient;
16
17
    public function __construct(\Gitlab\Client $gitlabClient)
18
    {
19
        $this->gitlabClient = $gitlabClient;
20
    }
21
22
    /**
23
     * @param MergeRequest $mergeRequest
24
     * @return MergeRequestApproval|null
25
     * @throws \Exception
26
     */
27
    public function find(MergeRequest $mergeRequest): ?MergeRequestApproval
28
    {
29
        $mergeRequestApproval = $this->gitlabClient->mergeRequests()->approvals(
30
            $mergeRequest->getProject()->getId(),
31
            $mergeRequest->getIid()
32
        );
33
        if (!is_array($mergeRequestApproval)) {
34
            return null;
35
        }
36
        return $this->transform($mergeRequest, $mergeRequestApproval);
37
    }
38
39
    /**
40
     * @param MergeRequest $mergeRequest
41
     * @return MergeRequestApproval
42
     * @throws MergeRequestApprovalNotFoundException
43
     * @throws \Exception
44
     */
45
    public function get(MergeRequest $mergeRequest): MergeRequestApproval
46
    {
47
        $mergeRequestApproval = $this->find($mergeRequest);
48
        if (!$mergeRequestApproval) {
49
            throw new MergeRequestApprovalNotFoundException();
50
        }
51
        return $mergeRequestApproval;
52
    }
53
54
    /**
55
     * @param array $mergeRequests
56
     * @param MergeRequestApprovalFilter $filter
57
     * @return array
58
     * @throws \Exception
59
     */
60
    public function all(
61
        array $mergeRequests,
62
        MergeRequestApprovalFilter $filter
63
    ): array {
64
        $mergeRequestApprovals = [];
65
        foreach ($mergeRequests as $mergeRequest) {
66
            $approval = $this->find($mergeRequest);
67
            if ($approval) {
68
                $mergeRequestApprovals[] = $approval;
69
            }
70
        }
71
        $mergeRequestApprovals = array_filter($mergeRequestApprovals, $filter);
72
        $this->sortByCreatedAt($mergeRequestApprovals);
73
74
        return $mergeRequestApprovals;
75
    }
76
77
    /**
78
     * @param array $mergeRequests
79
     * @param MergeRequestApprovalFilter $filter
80
     * @return array
81
     * @throws MergeRequestApprovalNotFoundException
82
     * @throws \Exception
83
     */
84
    public function getAll(
85
        array $mergeRequests,
86
        MergeRequestApprovalFilter $filter
87
    ): array {
88
        $mergeRequestApprovals = $this->all($mergeRequests, $filter);
89
90
        if (count($mergeRequestApprovals) == 0) {
91
            throw new MergeRequestApprovalNotFoundException('No pending merge request approvals.');
92
        }
93
        return $mergeRequestApprovals;
94
    }
95
96
    /**
97
     * @param array $mergeRequestApprovals
98
     */
99
    private function sortByCreatedAt(array &$mergeRequestApprovals): void
100
    {
101
        usort($mergeRequestApprovals, function (MergeRequestApproval $approvalA, MergeRequestApproval $approvalB) {
102
            if ($approvalA->getCreatedAt()->equalTo($approvalB->getCreatedAt())) {
103
                return 0;
104
            }
105
            return ($approvalA->getCreatedAt()->lessThan($approvalB->getCreatedAt()) ? -1 : 1);
106
        });
107
    }
108
109
    /**
110
     * @param MergeRequest $mergeRequest
111
     * @param array $mergeRequestApproval
112
     * @return MergeRequestApproval
113
     * @throws \Exception
114
     */
115
    private function transform(MergeRequest $mergeRequest, array $mergeRequestApproval): MergeRequestApproval
116
    {
117
        $mergeRequestApproval['merge_request'] = $mergeRequest;
118
119
        $this->transformApprovers($mergeRequestApproval['approved_by']);
120
        $this->transformApprovers($mergeRequestApproval['approvers']);
121
        $this->transformApprovers($mergeRequestApproval['suggested_approvers']);
122
123
        $mergeRequestApproval['suggested_approvers'] = array_udiff(
124
            $mergeRequestApproval['suggested_approvers'],
125
            $mergeRequestApproval['approvers'],
126
            function (User $userA, User $userB) {
127
                return $userA->getId() <=> $userB->getId();
128
            }
129
        );
130
        $mergeRequestApproval['approvers'] = array_udiff(
131
            $mergeRequestApproval['approvers'],
132
            $mergeRequestApproval['approved_by'],
133
            function (User $userA, User $userB) {
134
                return $userA->getId() <=> $userB->getId();
135
            }
136
        );
137
138
        array_walk($mergeRequestApproval['approver_groups'], function (&$approverGroup) {
139
            $approverGroup = Group::fromArray($approverGroup['group']);
140
        });
141
142
        return MergeRequestApproval::fromArray($mergeRequestApproval);
143
    }
144
145
    /**
146
     * @param array $approvers
147
     * @return void
148
     */
149
    private function transformApprovers(array &$approvers): void
150
    {
151
        array_walk($approvers, function (&$approver) {
152
            // suggested_approvers are not encapsulated in 'user'...
153
            if (isset($approver['user'])) {
154
                $approver = $approver['user'];
155
            }
156
            $approver = User::fromArray($approver);
157
        });
158
    }
159
}
160