Completed
Push — master ( c612e7...f3e1c8 )
by Christian
06:23
created

PackageConverter::convertPackageToArray()   D

Complexity

Conditions 9
Paths 132

Size

Total Lines 42
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 42
rs 4.6666
cc 9
eloc 27
nc 132
nop 2
1
<?php
2
3
/**
4
 * This file is part of tenside/core.
5
 *
6
 * (c) Christian Schiffler <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 *
11
 * This project is provided in good faith and hope to be usable by anyone.
12
 *
13
 * @package    tenside/core
14
 * @author     Christian Schiffler <[email protected]>
15
 * @copyright  2015 Christian Schiffler <[email protected]>
16
 * @license    https://github.com/tenside/core/blob/master/LICENSE MIT
17
 * @link       https://github.com/tenside/core
18
 * @filesource
19
 */
20
21
namespace Tenside\Core\Composer;
22
23
use Composer\Package\CompletePackageInterface;
24
use Composer\Package\Link;
25
use Composer\Package\PackageInterface;
26
use Composer\Package\RootPackageInterface;
27
use Composer\Repository\RepositoryInterface;
28
use Tenside\Core\Util\JsonArray;
29
30
/**
31
 * The main entry point.
32
 */
33
class PackageConverter
34
{
35
    /**
36
     * The root package of the installation.
37
     *
38
     * @var RootPackageInterface
39
     */
40
    private $rootPackage;
41
42
    /**
43
     * Create a new instance.
44
     *
45
     * @param RootPackageInterface $rootPackage The root package of the installation.
46
     */
47
    public function __construct(RootPackageInterface $rootPackage)
48
    {
49
        $this->rootPackage = $rootPackage;
50
    }
51
52
    /**
53
     * Create a new instance and return it.
54
     *
55
     * @param RootPackageInterface $rootPackage The root package of the installation.
56
     *
57
     * @return PackageConverter
58
     */
59
    public static function create(RootPackageInterface $rootPackage)
60
    {
61
        return new static($rootPackage);
62
    }
63
64
    /**
65
     * Convert a package version into string representation.
66
     *
67
     * @param PackageInterface $package       The package to extract the version from.
68
     *
69
     * @param bool             $fullReference Flag if the complete reference shall be added or an abbreviated form.
70
     *
71
     * @return string
72
     *
73
     * @throws \RuntimeException If the package is a dev package and does not have valid reference information.
74
     */
75
    public static function convertPackageVersion(PackageInterface $package, $fullReference = false)
76
    {
77
        $version = $package->getPrettyVersion();
78
79
        if ('dev' === $package->getStability()) {
80
            if (null === ($reference = $package->getDistReference())) {
81
                if (null === ($reference = $package->getSourceReference())) {
82
                    throw new \RuntimeException('Unable to determine reference for ' . $package->getPrettyName());
83
                }
84
            }
85
86
            $version .= '#' . (!$fullReference ? substr($reference, 0, 8) : $reference);
87
        }
88
89
        return $version;
90
    }
91
92
    /**
93
     * Convert a package to array information used by json API.
94
     *
95
     * @param PackageInterface $package        The package to convert.
96
     *
97
     * @param null|string      $upgradeVersion The package version to show as upgradable to.
98
     *
99
     * @return JsonArray
100
     */
101
    public function convertPackageToArray(PackageInterface $package, $upgradeVersion = null)
102
    {
103
        $name = $package->getPrettyName();
104
        $data = new JsonArray([
105
            'name'       => $name,
106
            'version'    => $this->convertPackageVersion($package),
107
            'constraint' => $this->getConstraint($name),
108
            'type'       => $package->getType(),
109
            'locked'     => $this->isLocked($name),
110
        ]);
111
112
        if (null !== ($releaseDate = $package->getReleaseDate())) {
113
            $data->set('time', $releaseDate->format(\DateTime::ATOM));
114
        }
115
116
        if (null !== $upgradeVersion) {
117
            $data->set('upgrade_version', $upgradeVersion);
118
        }
119
120
        if ($package instanceof CompletePackageInterface) {
121
            $data->set('description', $package->getDescription());
122
            $data->set('license', $package->getLicense());
123
            if ($keywords = $package->getKeywords()) {
124
                $data->set('keywords', $keywords);
125
            }
126
            if ($homepage = $package->getHomepage()) {
127
                $data->set('homepage', $homepage);
128
            }
129
            if ($authors = $package->getAuthors()) {
130
                $data->set('authors', $authors);
131
            }
132
            if ($support = $package->getSupport()) {
133
                $data->set('support', $support);
134
            }
135
            $data->set('abandoned', $package->isAbandoned());
136
            if ($package->isAbandoned()) {
137
                $data->set('replacement', $package->getReplacementPackage());
138
            }
139
        }
140
141
        return $data;
142
    }
143
144
    /**
145
     * Convert the information of all packages in a repository to an array used by json API.
146
     *
147
     * @param RepositoryInterface $repository   The repository holding the packages to convert.
148
     *
149
     * @param bool                $requiredOnly If true, return only the packages added to the root package as require.
150
     *
151
     * @param null|JsonArray      $upgradeList  The package version to show as upgradable to.
152
     *
153
     * @return JsonArray
154
     */
155
    public function convertRepositoryToArray(
156
        RepositoryInterface $repository,
157
        $requiredOnly = false,
158
        JsonArray $upgradeList = null
159
    ) {
160
        $requires = $requiredOnly ? $this->rootPackage->getRequires() : false;
161
        $packages = new JsonArray();
162
        /** @var \Composer\Package\PackageInterface $package */
163
        foreach ($repository->getPackages() as $package) {
164
            $name = $package->getPrettyName();
165
            $esc  = $packages->escape($name);
166
            if (false === $requires || (isset($requires[$name]))) {
167
                $upgradeVersion = null;
168
                if ($upgradeList && $upgradeList->has($esc)) {
169
                    $upgradeVersion = $upgradeList->get($esc);
170
                }
171
                $packages->set(
172
                    $esc,
173
                    $this->convertPackageToArray($package, $upgradeVersion)->getData()
174
                );
175
            }
176
        }
177
178
        return $packages;
179
    }
180
181
    /**
182
     * Compare two packages by their names.
183
     *
184
     * @param array $left  The first package for comparison.
185
     *
186
     * @param array $right The second package for comparison.
187
     *
188
     * @return int
189
     *
190
     * @internal
191
     */
192
    public function packageCompare($left, $right)
193
    {
194
        return strnatcasecmp($left['name'], $right['name']);
195
    }
196
197
    /**
198
     * Check if a package is locked.
199
     *
200
     * @param string $packageName The name of the package to test.
201
     *
202
     * @return bool
203
     *
204
     * @see ComposerJson::isLocked()
205
     */
206
    private function isLocked($packageName)
207
    {
208
        $extra = $this->rootPackage->getExtra();
209
        return isset($extra['tenside']['version-locks'][$packageName]);
210
    }
211
212
    /**
213
     * Determine the constraint defined for a given package (if required via root project).
214
     *
215
     * @param string $packageName The name of the package to retrieve the constraint for.
216
     *
217
     * @return string|null
218
     */
219
    private function getConstraint($packageName)
220
    {
221
        $requires = $this->rootPackage->getRequires();
222
        if (isset($requires[$packageName])) {
223
            /** @var Link $link */
224
            $link = $requires[$packageName];
225
            return $link->getConstraint()->getPrettyString();
226
        }
227
228
        foreach ($requires as $link) {
229
            /** @var Link $link */
230
            if ($link->getTarget() == $packageName) {
231
                return $link->getConstraint()->getPrettyString();
232
            }
233
        }
234
235
        return null;
236
    }
237
}
238