ConstraintsComponent::process()   B
last analyzed

Complexity

Conditions 6
Paths 5

Size

Total Lines 41
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
eloc 22
c 0
b 0
f 0
nc 5
nop 2
dl 0
loc 41
rs 8.9457
1
<?php
2
/**
3
 * Copyright © Vaimo Group. All rights reserved.
4
 * See LICENSE_VAIMO.txt for license details.
5
 */
6
namespace Vaimo\ComposerPatches\Patch\DefinitionList\LoaderComponents;
7
8
use Vaimo\ComposerPatches\Patch\Definition as PatchDefinition;
9
10
class ConstraintsComponent implements \Vaimo\ComposerPatches\Interfaces\DefinitionListLoaderComponentInterface
11
{
12
    /**
13
     * @var \Vaimo\ComposerPatches\Interfaces\PackageConfigExtractorInterface
14
     */
15
    private $configExtractor;
16
17
    /**
18
     * @var \Composer\Package\Version\VersionParser
19
     */
20
    private $versionParser;
21
22
    /**
23
     * @var \Vaimo\ComposerPatches\Utils\ConstraintUtils
24
     */
25
    private $constraintUtils;
26
27
    /**
28
     * @var \Vaimo\ComposerPatches\Utils\PackageUtils
29
     */
30
    private $packageUtils;
31
32
    /**
33
     * @param \Vaimo\ComposerPatches\Interfaces\PackageConfigExtractorInterface $configExtractor
34
     */
35
    public function __construct(
36
        \Vaimo\ComposerPatches\Interfaces\PackageConfigExtractorInterface $configExtractor
37
    ) {
38
        $this->configExtractor = $configExtractor;
39
        $this->versionParser = new \Composer\Package\Version\VersionParser();
40
        $this->constraintUtils = new \Vaimo\ComposerPatches\Utils\ConstraintUtils();
41
        $this->packageUtils = new \Vaimo\ComposerPatches\Utils\PackageUtils();
42
    }
43
44
    /**
45
     * @param array $patches
46
     * @param \Composer\Package\PackageInterface[] $packagesByName
47
     * @return array
48
     */
49
    public function process(array $patches, array $packagesByName)
50
    {
51
        $rootPackages = array_filter(
52
            $packagesByName,
53
            function ($package) {
54
                return $package instanceof \Composer\Package\RootPackageInterface;
55
            }
56
        );
57
58
        /** @var \Composer\Package\CompletePackageInterface $rootPackage */
59
        $rootPackage = reset($rootPackages);
60
61
        $rootRequires = array_replace(
62
            $rootPackage->getRequires(),
63
            $rootPackage->getDevRequires()
64
        );
65
66
        foreach ($patches as $target => &$packagePatches) {
67
            foreach ($packagePatches as &$patchData) {
68
                if ($target !== PatchDefinition::BUNDLE_TARGET && !isset($packagesByName[$target])) {
69
                    $patchData = false;
70
                    continue;
71
                }
72
73
                $patchConstraints = $patchData[PatchDefinition::DEPENDS];
74
75
                $comparisonResults = $this->resolveComparisonResults(
76
                    $patchConstraints,
77
                    $packagesByName,
78
                    $rootRequires
79
                );
80
81
                if (count($patchConstraints) !== count(array_filter($comparisonResults))) {
82
                    $patchData = false;
83
                }
84
            }
85
86
            $packagePatches = array_filter($packagePatches);
87
        }
88
89
        return array_filter($patches);
90
    }
91
92
    private function resolveComparisonResults(array $patchConstraints, array $packages, array $rootRequires)
93
    {
94
        $comparisonResults = array();
95
96
        foreach ($patchConstraints as $constraintTarget => $version) {
97
            if (!isset($packages[$constraintTarget])) {
98
                continue;
99
            }
100
101
            $package = $packages[$constraintTarget];
102
103
            $packageVersion = $package->getVersion();
104
            $packageVersions = array($package->getVersion());
105
106
            if (isset($rootRequires[$constraintTarget])) {
107
                /** @var \Composer\Package\CompletePackageInterface $targetRootPackage */
108
                $targetRootPackage = $rootRequires[$constraintTarget];
109
110
                $prettyVersion = $this->packageUtils->getPrettyVersion($targetRootPackage);
111
112
                $matches = array();
113
                preg_match('/.* as (.*)$/', $prettyVersion, $matches);
114
115
                if (isset($matches[1])) {
116
                    $packageVersions[] = $matches[1];
117
                }
118
            }
119
120
            if ($this->constraintUtils->isDevConstraint($packageVersion)) {
121
                $definedVersion = $this->configExtractor->getConfig(
122
                    $package,
123
                    'version'
124
                );
125
126
                $packageVersions[] = $definedVersion;
127
            }
128
129
            $matchResult = false;
130
131
            foreach (array_filter($packageVersions) as $packageVersion) {
132
                $packageConstraint = $this->versionParser->parseConstraints($packageVersion);
133
                $patchConstraint = $this->versionParser->parseConstraints($version);
134
135
                $matchResult = $patchConstraint->matches($packageConstraint);
136
137
                if ($matchResult) {
138
                    break;
139
                }
140
            }
141
142
            $comparisonResults[] = $matchResult;
143
        }
144
145
        return $comparisonResults;
146
    }
147
}
148