PackageCollection::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
namespace Composed;
3
4
class PackageCollection implements \IteratorAggregate
5
{
6
    private $packages;
7
8
    /**
9
     * @param Package[] $packages
10
     */
11
    public function __construct(array $packages)
12
    {
13
        $this->packages = $packages;
14
    }
15
16
    /**
17
     * @return \Iterator
18
     */
19
    public function getIterator()
20
    {
21
        return new \ArrayIterator($this->packages);
22
    }
23
24
    /**
25
     * @return null|Package
26
     */
27
    public function getPackage(string $name)
28
    {
29
        return isset($this->packages[$name]) ? $this->packages[$name] : null;
30
    }
31
32
    /**
33
     * Get a config value from all packages
34
     *
35
     * @param string|array $keys Either a string, e.g. 'required' to get the dependencies by a package, or an array,
36
     * e.g. ['required', 'php'] to get the version of PHP required by a package
37
     *
38
     * @param mixed $default If this is not explicitly specified, packages which do not provide any config value will be
39
     * omitted from the result. Explicitly setting this to NULL is not the same as omitting it and will result in
40
     * packages which do not provide config being returned with a value of NULL
41
     *
42
     * @return array Keys are package names, values are the retrieved config as an array or scalar
43
     */
44
    public function getConfig($keys = [], $default = null) : array
45
    {
46
        if (2 > func_num_args()) {
47
            $default = new \stdClass;
48
        }
49
50
        $config = @array_map(
51
            function (AbstractPackage $package) use ($keys, $default) {
52
                return $package->getConfig($keys, $default);
0 ignored issues
show
Bug introduced by
It seems like $keys defined by parameter $keys on line 44 can also be of type string; however, Composed\AbstractPackage::getConfig() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
53
            },
54
            $this->packages
55
        );
56
57
        if (2 > func_num_args()) {
58
            $config = array_filter($config, function ($value) use ($default) {
59
                return $value !== $default;
60
            });
61
        }
62
63
        return $config;
64
    }
65
66
    public function toArray() : array
67
    {
68
        return $this->packages;
69
    }
70
71
    public function getPackageNames() : array
72
    {
73
        return array_keys($this->packages);
74
    }
75
76
    /**
77
     * Returns all packages sorted based on their dependencies. Each package is guaranteed to appear after all of its
78
     * dependencies in the collection
79
     */
80
    public function sortByDependencies() : self
81
    {
82
        /** @var $packages Package[] */
83
        $packages = $this->packages;
84
        $sortedPackages = [];
85
86
        while (!empty($packages)) {
87
            foreach ($packages as $packageName => $package) {
88
                $dependentPackages = $package->getDependencies()->toArray();
89
                if (empty(array_diff_key($dependentPackages, $sortedPackages))) {
90
                    // all of this packages dependencies are already in the sorted array, so it can be appended
91
                    $sortedPackages[$packageName] = $package;
92
                    unset($packages[$packageName]);
93
                    continue(2);
94
                }
95
            }
96
            throw new \LogicException('Packages have circular dependencies');
97
        }
98
99
        return new static($sortedPackages);
100
    }
101
}
102