Completed
Push — master ( 6b95b9...222e46 )
by Robbie
11s
created

ComposerLoaderExtension::getRepository()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 0
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
namespace BringYourOwnIdeas\UpdateChecker\Extensions;
4
5
use Composer\Composer;
6
use Composer\Factory;
7
use Composer\IO\NullIO;
8
use Composer\Package\Link;
9
use Composer\Repository\ArrayRepository;
10
use Composer\Repository\BaseRepository;
11
use Composer\Repository\CompositeRepository;
12
use Composer\Repository\RepositoryInterface;
13
use SilverStripe\Core\Extension;
14
15
class ComposerLoaderExtension extends Extension
16
{
17
    /**
18
     * @var Composer
19
     */
20
    protected $composer;
21
22
    /**
23
     * @param Composer $composer
24
     * @return $this
25
     */
26
    public function setComposer(Composer $composer)
27
    {
28
        $this->composer = $composer;
29
        return $this;
30
    }
31
32
    /**
33
     * @return Composer
34
     */
35
    public function getComposer()
36
    {
37
        return $this->composer;
38
    }
39
40
    /**
41
     * Retrieve an array of primary composer dependencies from composer.json.
42
     *
43
     * Packages are filtered by allowed type.
44
     *
45
     * @param array|null $allowedTypes An array of "allowed" package types. Dependencies in composer.json that do not
46
     *                                 match any of the given types are not returned.
47
     * @return array[]
48
     */
49
    public function getPackages(array $allowedTypes = null)
50
    {
51
        $packages = [];
52
        $repository = $this->getRepository();
53
        foreach ($repository->getPackages() as $package) {
54
            // Filter out packages that are not "allowed types"
55
            if (is_array($allowedTypes) && !in_array($package->getType(), $allowedTypes)) {
56
                continue;
57
            }
58
59
            // Find the constraint used for installation
60
            $constraint = $this->getInstalledConstraint($repository, $package->getName());
61
            $packages[$package->getName()] = [
62
                'constraint' => $constraint,
63
                'package' => $package,
64
            ];
65
        }
66
        return $packages;
67
    }
68
69
    /**
70
     * Provides access to the Composer repository
71
     *
72
     * @return RepositoryInterface
73
     */
74
    protected function getRepository()
75
    {
76
        /** @var Composer $composer */
77
        $composer = $this->getComposer();
78
79
        /** @var BaseRepository $repository */
80
        return new CompositeRepository([
81
            new ArrayRepository([$composer->getPackage()]),
82
            $composer->getRepositoryManager()->getLocalRepository(),
83
        ]);
84
    }
85
86
    /**
87
     * Find all dependency constraints for the given package in the current repository and return the strictest one
88
     *
89
     * @param BaseRepository $repository
90
     * @param string $packageName
91
     * @return string
92
     */
93
    protected function getInstalledConstraint(BaseRepository $repository, $packageName)
94
    {
95
        $constraints = [];
96
        foreach ($repository->getDependents($packageName) as $dependent) {
97
            /** @var Link $link */
98
            list (, $link) = $dependent;
99
            $constraints[] = $link->getPrettyConstraint();
100
        }
101
102
        usort($constraints, 'version_compare');
103
104
        return array_pop($constraints);
105
    }
106
107
    /**
108
     * Builds an instance of Composer
109
     */
110
    public function onAfterBuild()
111
    {
112
        $originalDir = getcwd();
113
        chdir(BASE_PATH);
114
        /** @var Composer $composer */
115
        $composer = Factory::create(new NullIO());
116
        $this->setComposer($composer);
117
        chdir($originalDir);
118
    }
119
}
120