Passed
Pull Request — master (#34)
by
unknown
04:57
created

DependencyFilter::getDependents()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 17
nc 4
nop 3
dl 0
loc 32
ccs 18
cts 18
cp 1
crap 4
rs 9.7
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright MediaCT. All rights reserved.
4
 * https://www.mediact.nl
5
 */
6
7
namespace Mediact\DependencyGuard\Violation\Filter;
8
9
use Composer\Composer;
10
use Composer\Package\PackageInterface;
11
use Composer\Repository\CompositeRepository;
12
use Composer\Repository\RepositoryInterface;
13
use Mediact\DependencyGuard\Candidate\Candidate;
14
use Mediact\DependencyGuard\Violation\Violation;
15
use Mediact\DependencyGuard\Violation\ViolationInterface;
16
17
class DependencyFilter implements ViolationFilterInterface
18
{
19
    /** @var ViolationFilterInterface */
20
    private $filter;
21
22
    /** @var CompositeRepository */
23
    private $repository;
24
25
    /**
26
     * Constructor.
27
     *
28
     * @param RepositoryInterface      $repository
29
     * @param ViolationFilterInterface $filter
30
     */
31 1
    public function __construct(
32
        RepositoryInterface $repository,
33
        ViolationFilterInterface $filter
34
    ) {
35 1
        $this->filter     = $filter;
36 1
        $this->repository = new CompositeRepository([$repository]);
37 1
    }
38
39
    /**
40
     * Filter violations.
41
     *
42
     * @param ViolationInterface $violation
43
     *
44
     * @return bool
45
     */
46 5
    public function __invoke(ViolationInterface $violation): bool
47
    {
48 5
        return array_reduce(
49 5
            array_map(
50
                function (
51
                    array $dependent
52
                ) use ($violation): ViolationInterface {
53
                    /** @var PackageInterface $package */
54 2
                    [$package] = $dependent;
55 2
                    return new Violation(
56 2
                        sprintf(
57 2
                            'Package "%s" provides violating package "%s".',
58 2
                            $package->getName(),
59 2
                            $violation->getPackage()->getName()
60
                        ),
61 2
                        new Candidate(
62 2
                            $package,
63 2
                            $violation->getSymbols()
64
                        )
65
                    );
66 5
                },
67 5
                $this->getDependents(
68 5
                    $violation->getPackage()->getName(),
69 5
                    false,
70 5
                    []
71
                )
72
            ),
73
            function (bool $carry, ViolationInterface $violation): bool {
74 2
                return $carry || $this->filter->__invoke($violation);
75 5
            },
76 5
            false
77
        );
78
    }
79
80
    /**
81
     * Retrieves the dependents of a package in a recursive way.
82
     *
83
     * @param string $packageName
84
     * @param bool   $returnContext
85
     * @param array  $context
86
     *
87
     * @return array
88
     */
89 5
    private function getDependents(
90
        string $packageName,
91
        bool $returnContext,
92
        array $context = []
93
    ): array {
94 5
        if (!isset($context[$packageName])) {
95 5
            $context[$packageName] = $this->repository->getDependents(
96 5
                $packageName,
97 5
                null,
98 5
                false,
99 5
                false
100
            );
101
102 5
            foreach ($context[$packageName] as $key => $dependent) {
103 2
                $dependentContext = $this->getDependents($key, true, $context);
104 2
                $context          = array_merge(
105 2
                    $context,
106 2
                    $dependentContext
107
                );
108
109 2
                $context[$packageName] = array_merge(
110 2
                    $context[$packageName],
111 2
                    $dependentContext[$key]
112
                );
113
            }
114
        }
115
116 5
        if (!$returnContext) {
117 5
            return $context[$packageName];
118
        }
119
120 2
        return $context;
121
    }
122
}
123