xref: /plugin/pureldap/vendor/composer/InstalledVersions.php (revision dad993c57a70866aa1db59c43f043769c2eb7ed0)
1fd0855ecSAndreas Gohr<?php
2fd0855ecSAndreas Gohr
3fd0855ecSAndreas Gohr/*
4fd0855ecSAndreas Gohr * This file is part of Composer.
5fd0855ecSAndreas Gohr *
6fd0855ecSAndreas Gohr * (c) Nils Adermann <naderman@naderman.de>
7fd0855ecSAndreas Gohr *     Jordi Boggiano <j.boggiano@seld.be>
8fd0855ecSAndreas Gohr *
9fd0855ecSAndreas Gohr * For the full copyright and license information, please view the LICENSE
10fd0855ecSAndreas Gohr * file that was distributed with this source code.
11fd0855ecSAndreas Gohr */
12fd0855ecSAndreas Gohr
13fd0855ecSAndreas Gohrnamespace Composer;
14fd0855ecSAndreas Gohr
15fd0855ecSAndreas Gohruse Composer\Autoload\ClassLoader;
16fd0855ecSAndreas Gohruse Composer\Semver\VersionParser;
17fd0855ecSAndreas Gohr
18fd0855ecSAndreas Gohr/**
19fd0855ecSAndreas Gohr * This class is copied in every Composer installed project and available to all
20fd0855ecSAndreas Gohr *
21fd0855ecSAndreas Gohr * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
22fd0855ecSAndreas Gohr *
23*dad993c5SAndreas Gohr * To require its presence, you can require `composer-runtime-api ^2.0`
24*dad993c5SAndreas Gohr *
25*dad993c5SAndreas Gohr * @final
26fd0855ecSAndreas Gohr */
27fd0855ecSAndreas Gohrclass InstalledVersions
28fd0855ecSAndreas Gohr{
29*dad993c5SAndreas Gohr    /**
30*dad993c5SAndreas Gohr     * @var mixed[]|null
31*dad993c5SAndreas Gohr     * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
32*dad993c5SAndreas Gohr     */
33fd0855ecSAndreas Gohr    private static $installed;
34*dad993c5SAndreas Gohr
35*dad993c5SAndreas Gohr    /**
36*dad993c5SAndreas Gohr     * @var bool|null
37*dad993c5SAndreas Gohr     */
38fd0855ecSAndreas Gohr    private static $canGetVendors;
39*dad993c5SAndreas Gohr
40*dad993c5SAndreas Gohr    /**
41*dad993c5SAndreas Gohr     * @var array[]
42*dad993c5SAndreas Gohr     * @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
43*dad993c5SAndreas Gohr     */
44fd0855ecSAndreas Gohr    private static $installedByVendor = array();
45fd0855ecSAndreas Gohr
46fd0855ecSAndreas Gohr    /**
47fd0855ecSAndreas Gohr     * Returns a list of all package names which are present, either by being installed, replaced or provided
48fd0855ecSAndreas Gohr     *
49fd0855ecSAndreas Gohr     * @return string[]
50fd0855ecSAndreas Gohr     * @psalm-return list<string>
51fd0855ecSAndreas Gohr     */
52fd0855ecSAndreas Gohr    public static function getInstalledPackages()
53fd0855ecSAndreas Gohr    {
54fd0855ecSAndreas Gohr        $packages = array();
55fd0855ecSAndreas Gohr        foreach (self::getInstalled() as $installed) {
56fd0855ecSAndreas Gohr            $packages[] = array_keys($installed['versions']);
57fd0855ecSAndreas Gohr        }
58fd0855ecSAndreas Gohr
59fd0855ecSAndreas Gohr        if (1 === \count($packages)) {
60fd0855ecSAndreas Gohr            return $packages[0];
61fd0855ecSAndreas Gohr        }
62fd0855ecSAndreas Gohr
63fd0855ecSAndreas Gohr        return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
64fd0855ecSAndreas Gohr    }
65fd0855ecSAndreas Gohr
66fd0855ecSAndreas Gohr    /**
67fd0855ecSAndreas Gohr     * Returns a list of all package names with a specific type e.g. 'library'
68fd0855ecSAndreas Gohr     *
69fd0855ecSAndreas Gohr     * @param  string   $type
70fd0855ecSAndreas Gohr     * @return string[]
71fd0855ecSAndreas Gohr     * @psalm-return list<string>
72fd0855ecSAndreas Gohr     */
73fd0855ecSAndreas Gohr    public static function getInstalledPackagesByType($type)
74fd0855ecSAndreas Gohr    {
75fd0855ecSAndreas Gohr        $packagesByType = array();
76fd0855ecSAndreas Gohr
77fd0855ecSAndreas Gohr        foreach (self::getInstalled() as $installed) {
78fd0855ecSAndreas Gohr            foreach ($installed['versions'] as $name => $package) {
79fd0855ecSAndreas Gohr                if (isset($package['type']) && $package['type'] === $type) {
80fd0855ecSAndreas Gohr                    $packagesByType[] = $name;
81fd0855ecSAndreas Gohr                }
82fd0855ecSAndreas Gohr            }
83fd0855ecSAndreas Gohr        }
84fd0855ecSAndreas Gohr
85fd0855ecSAndreas Gohr        return $packagesByType;
86fd0855ecSAndreas Gohr    }
87fd0855ecSAndreas Gohr
88fd0855ecSAndreas Gohr    /**
89fd0855ecSAndreas Gohr     * Checks whether the given package is installed
90fd0855ecSAndreas Gohr     *
91fd0855ecSAndreas Gohr     * This also returns true if the package name is provided or replaced by another package
92fd0855ecSAndreas Gohr     *
93fd0855ecSAndreas Gohr     * @param  string $packageName
94fd0855ecSAndreas Gohr     * @param  bool   $includeDevRequirements
95fd0855ecSAndreas Gohr     * @return bool
96fd0855ecSAndreas Gohr     */
97fd0855ecSAndreas Gohr    public static function isInstalled($packageName, $includeDevRequirements = true)
98fd0855ecSAndreas Gohr    {
99fd0855ecSAndreas Gohr        foreach (self::getInstalled() as $installed) {
100fd0855ecSAndreas Gohr            if (isset($installed['versions'][$packageName])) {
101*dad993c5SAndreas Gohr                return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
102fd0855ecSAndreas Gohr            }
103fd0855ecSAndreas Gohr        }
104fd0855ecSAndreas Gohr
105fd0855ecSAndreas Gohr        return false;
106fd0855ecSAndreas Gohr    }
107fd0855ecSAndreas Gohr
108fd0855ecSAndreas Gohr    /**
109fd0855ecSAndreas Gohr     * Checks whether the given package satisfies a version constraint
110fd0855ecSAndreas Gohr     *
111fd0855ecSAndreas Gohr     * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
112fd0855ecSAndreas Gohr     *
113fd0855ecSAndreas Gohr     *   Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
114fd0855ecSAndreas Gohr     *
115fd0855ecSAndreas Gohr     * @param  VersionParser $parser      Install composer/semver to have access to this class and functionality
116fd0855ecSAndreas Gohr     * @param  string        $packageName
117fd0855ecSAndreas Gohr     * @param  string|null   $constraint  A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
118fd0855ecSAndreas Gohr     * @return bool
119fd0855ecSAndreas Gohr     */
120fd0855ecSAndreas Gohr    public static function satisfies(VersionParser $parser, $packageName, $constraint)
121fd0855ecSAndreas Gohr    {
122*dad993c5SAndreas Gohr        $constraint = $parser->parseConstraints((string) $constraint);
123fd0855ecSAndreas Gohr        $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
124fd0855ecSAndreas Gohr
125fd0855ecSAndreas Gohr        return $provided->matches($constraint);
126fd0855ecSAndreas Gohr    }
127fd0855ecSAndreas Gohr
128fd0855ecSAndreas Gohr    /**
129fd0855ecSAndreas Gohr     * Returns a version constraint representing all the range(s) which are installed for a given package
130fd0855ecSAndreas Gohr     *
131fd0855ecSAndreas Gohr     * It is easier to use this via isInstalled() with the $constraint argument if you need to check
132fd0855ecSAndreas Gohr     * whether a given version of a package is installed, and not just whether it exists
133fd0855ecSAndreas Gohr     *
134fd0855ecSAndreas Gohr     * @param  string $packageName
135fd0855ecSAndreas Gohr     * @return string Version constraint usable with composer/semver
136fd0855ecSAndreas Gohr     */
137fd0855ecSAndreas Gohr    public static function getVersionRanges($packageName)
138fd0855ecSAndreas Gohr    {
139fd0855ecSAndreas Gohr        foreach (self::getInstalled() as $installed) {
140fd0855ecSAndreas Gohr            if (!isset($installed['versions'][$packageName])) {
141fd0855ecSAndreas Gohr                continue;
142fd0855ecSAndreas Gohr            }
143fd0855ecSAndreas Gohr
144fd0855ecSAndreas Gohr            $ranges = array();
145fd0855ecSAndreas Gohr            if (isset($installed['versions'][$packageName]['pretty_version'])) {
146fd0855ecSAndreas Gohr                $ranges[] = $installed['versions'][$packageName]['pretty_version'];
147fd0855ecSAndreas Gohr            }
148fd0855ecSAndreas Gohr            if (array_key_exists('aliases', $installed['versions'][$packageName])) {
149fd0855ecSAndreas Gohr                $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
150fd0855ecSAndreas Gohr            }
151fd0855ecSAndreas Gohr            if (array_key_exists('replaced', $installed['versions'][$packageName])) {
152fd0855ecSAndreas Gohr                $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
153fd0855ecSAndreas Gohr            }
154fd0855ecSAndreas Gohr            if (array_key_exists('provided', $installed['versions'][$packageName])) {
155fd0855ecSAndreas Gohr                $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
156fd0855ecSAndreas Gohr            }
157fd0855ecSAndreas Gohr
158fd0855ecSAndreas Gohr            return implode(' || ', $ranges);
159fd0855ecSAndreas Gohr        }
160fd0855ecSAndreas Gohr
161fd0855ecSAndreas Gohr        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
162fd0855ecSAndreas Gohr    }
163fd0855ecSAndreas Gohr
164fd0855ecSAndreas Gohr    /**
165fd0855ecSAndreas Gohr     * @param  string      $packageName
166fd0855ecSAndreas Gohr     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
167fd0855ecSAndreas Gohr     */
168fd0855ecSAndreas Gohr    public static function getVersion($packageName)
169fd0855ecSAndreas Gohr    {
170fd0855ecSAndreas Gohr        foreach (self::getInstalled() as $installed) {
171fd0855ecSAndreas Gohr            if (!isset($installed['versions'][$packageName])) {
172fd0855ecSAndreas Gohr                continue;
173fd0855ecSAndreas Gohr            }
174fd0855ecSAndreas Gohr
175fd0855ecSAndreas Gohr            if (!isset($installed['versions'][$packageName]['version'])) {
176fd0855ecSAndreas Gohr                return null;
177fd0855ecSAndreas Gohr            }
178fd0855ecSAndreas Gohr
179fd0855ecSAndreas Gohr            return $installed['versions'][$packageName]['version'];
180fd0855ecSAndreas Gohr        }
181fd0855ecSAndreas Gohr
182fd0855ecSAndreas Gohr        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
183fd0855ecSAndreas Gohr    }
184fd0855ecSAndreas Gohr
185fd0855ecSAndreas Gohr    /**
186fd0855ecSAndreas Gohr     * @param  string      $packageName
187fd0855ecSAndreas Gohr     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
188fd0855ecSAndreas Gohr     */
189fd0855ecSAndreas Gohr    public static function getPrettyVersion($packageName)
190fd0855ecSAndreas Gohr    {
191fd0855ecSAndreas Gohr        foreach (self::getInstalled() as $installed) {
192fd0855ecSAndreas Gohr            if (!isset($installed['versions'][$packageName])) {
193fd0855ecSAndreas Gohr                continue;
194fd0855ecSAndreas Gohr            }
195fd0855ecSAndreas Gohr
196fd0855ecSAndreas Gohr            if (!isset($installed['versions'][$packageName]['pretty_version'])) {
197fd0855ecSAndreas Gohr                return null;
198fd0855ecSAndreas Gohr            }
199fd0855ecSAndreas Gohr
200fd0855ecSAndreas Gohr            return $installed['versions'][$packageName]['pretty_version'];
201fd0855ecSAndreas Gohr        }
202fd0855ecSAndreas Gohr
203fd0855ecSAndreas Gohr        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
204fd0855ecSAndreas Gohr    }
205fd0855ecSAndreas Gohr
206fd0855ecSAndreas Gohr    /**
207fd0855ecSAndreas Gohr     * @param  string      $packageName
208fd0855ecSAndreas Gohr     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
209fd0855ecSAndreas Gohr     */
210fd0855ecSAndreas Gohr    public static function getReference($packageName)
211fd0855ecSAndreas Gohr    {
212fd0855ecSAndreas Gohr        foreach (self::getInstalled() as $installed) {
213fd0855ecSAndreas Gohr            if (!isset($installed['versions'][$packageName])) {
214fd0855ecSAndreas Gohr                continue;
215fd0855ecSAndreas Gohr            }
216fd0855ecSAndreas Gohr
217fd0855ecSAndreas Gohr            if (!isset($installed['versions'][$packageName]['reference'])) {
218fd0855ecSAndreas Gohr                return null;
219fd0855ecSAndreas Gohr            }
220fd0855ecSAndreas Gohr
221fd0855ecSAndreas Gohr            return $installed['versions'][$packageName]['reference'];
222fd0855ecSAndreas Gohr        }
223fd0855ecSAndreas Gohr
224fd0855ecSAndreas Gohr        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
225fd0855ecSAndreas Gohr    }
226fd0855ecSAndreas Gohr
227fd0855ecSAndreas Gohr    /**
228fd0855ecSAndreas Gohr     * @param  string      $packageName
229fd0855ecSAndreas Gohr     * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
230fd0855ecSAndreas Gohr     */
231fd0855ecSAndreas Gohr    public static function getInstallPath($packageName)
232fd0855ecSAndreas Gohr    {
233fd0855ecSAndreas Gohr        foreach (self::getInstalled() as $installed) {
234fd0855ecSAndreas Gohr            if (!isset($installed['versions'][$packageName])) {
235fd0855ecSAndreas Gohr                continue;
236fd0855ecSAndreas Gohr            }
237fd0855ecSAndreas Gohr
238fd0855ecSAndreas Gohr            return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
239fd0855ecSAndreas Gohr        }
240fd0855ecSAndreas Gohr
241fd0855ecSAndreas Gohr        throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
242fd0855ecSAndreas Gohr    }
243fd0855ecSAndreas Gohr
244fd0855ecSAndreas Gohr    /**
245fd0855ecSAndreas Gohr     * @return array
246*dad993c5SAndreas Gohr     * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
247fd0855ecSAndreas Gohr     */
248fd0855ecSAndreas Gohr    public static function getRootPackage()
249fd0855ecSAndreas Gohr    {
250fd0855ecSAndreas Gohr        $installed = self::getInstalled();
251fd0855ecSAndreas Gohr
252fd0855ecSAndreas Gohr        return $installed[0]['root'];
253fd0855ecSAndreas Gohr    }
254fd0855ecSAndreas Gohr
255fd0855ecSAndreas Gohr    /**
256fd0855ecSAndreas Gohr     * Returns the raw installed.php data for custom implementations
257fd0855ecSAndreas Gohr     *
258fd0855ecSAndreas Gohr     * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
259fd0855ecSAndreas Gohr     * @return array[]
260*dad993c5SAndreas Gohr     * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
261fd0855ecSAndreas Gohr     */
262fd0855ecSAndreas Gohr    public static function getRawData()
263fd0855ecSAndreas Gohr    {
264fd0855ecSAndreas Gohr        @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
265fd0855ecSAndreas Gohr
266fd0855ecSAndreas Gohr        if (null === self::$installed) {
267fd0855ecSAndreas Gohr            // only require the installed.php file if this file is loaded from its dumped location,
268fd0855ecSAndreas Gohr            // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
269fd0855ecSAndreas Gohr            if (substr(__DIR__, -8, 1) !== 'C') {
270fd0855ecSAndreas Gohr                self::$installed = include __DIR__ . '/installed.php';
271fd0855ecSAndreas Gohr            } else {
272fd0855ecSAndreas Gohr                self::$installed = array();
273fd0855ecSAndreas Gohr            }
274fd0855ecSAndreas Gohr        }
275fd0855ecSAndreas Gohr
276fd0855ecSAndreas Gohr        return self::$installed;
277fd0855ecSAndreas Gohr    }
278fd0855ecSAndreas Gohr
279fd0855ecSAndreas Gohr    /**
280fd0855ecSAndreas Gohr     * Returns the raw data of all installed.php which are currently loaded for custom implementations
281fd0855ecSAndreas Gohr     *
282fd0855ecSAndreas Gohr     * @return array[]
283*dad993c5SAndreas Gohr     * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
284fd0855ecSAndreas Gohr     */
285fd0855ecSAndreas Gohr    public static function getAllRawData()
286fd0855ecSAndreas Gohr    {
287fd0855ecSAndreas Gohr        return self::getInstalled();
288fd0855ecSAndreas Gohr    }
289fd0855ecSAndreas Gohr
290fd0855ecSAndreas Gohr    /**
291fd0855ecSAndreas Gohr     * Lets you reload the static array from another file
292fd0855ecSAndreas Gohr     *
293fd0855ecSAndreas Gohr     * This is only useful for complex integrations in which a project needs to use
294fd0855ecSAndreas Gohr     * this class but then also needs to execute another project's autoloader in process,
295fd0855ecSAndreas Gohr     * and wants to ensure both projects have access to their version of installed.php.
296fd0855ecSAndreas Gohr     *
297fd0855ecSAndreas Gohr     * A typical case would be PHPUnit, where it would need to make sure it reads all
298fd0855ecSAndreas Gohr     * the data it needs from this class, then call reload() with
299fd0855ecSAndreas Gohr     * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
300fd0855ecSAndreas Gohr     * the project in which it runs can then also use this class safely, without
301fd0855ecSAndreas Gohr     * interference between PHPUnit's dependencies and the project's dependencies.
302fd0855ecSAndreas Gohr     *
303fd0855ecSAndreas Gohr     * @param  array[] $data A vendor/composer/installed.php data set
304fd0855ecSAndreas Gohr     * @return void
305fd0855ecSAndreas Gohr     *
306*dad993c5SAndreas Gohr     * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
307fd0855ecSAndreas Gohr     */
308fd0855ecSAndreas Gohr    public static function reload($data)
309fd0855ecSAndreas Gohr    {
310fd0855ecSAndreas Gohr        self::$installed = $data;
311fd0855ecSAndreas Gohr        self::$installedByVendor = array();
312fd0855ecSAndreas Gohr    }
313fd0855ecSAndreas Gohr
314fd0855ecSAndreas Gohr    /**
315fd0855ecSAndreas Gohr     * @return array[]
316*dad993c5SAndreas Gohr     * @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
317fd0855ecSAndreas Gohr     */
318fd0855ecSAndreas Gohr    private static function getInstalled()
319fd0855ecSAndreas Gohr    {
320fd0855ecSAndreas Gohr        if (null === self::$canGetVendors) {
321fd0855ecSAndreas Gohr            self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
322fd0855ecSAndreas Gohr        }
323fd0855ecSAndreas Gohr
324fd0855ecSAndreas Gohr        $installed = array();
325fd0855ecSAndreas Gohr
326fd0855ecSAndreas Gohr        if (self::$canGetVendors) {
327fd0855ecSAndreas Gohr            foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
328fd0855ecSAndreas Gohr                if (isset(self::$installedByVendor[$vendorDir])) {
329fd0855ecSAndreas Gohr                    $installed[] = self::$installedByVendor[$vendorDir];
330fd0855ecSAndreas Gohr                } elseif (is_file($vendorDir.'/composer/installed.php')) {
331*dad993c5SAndreas Gohr                    /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
332*dad993c5SAndreas Gohr                    $required = require $vendorDir.'/composer/installed.php';
333*dad993c5SAndreas Gohr                    $installed[] = self::$installedByVendor[$vendorDir] = $required;
334fd0855ecSAndreas Gohr                    if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
335fd0855ecSAndreas Gohr                        self::$installed = $installed[count($installed) - 1];
336fd0855ecSAndreas Gohr                    }
337fd0855ecSAndreas Gohr                }
338fd0855ecSAndreas Gohr            }
339fd0855ecSAndreas Gohr        }
340fd0855ecSAndreas Gohr
341fd0855ecSAndreas Gohr        if (null === self::$installed) {
342fd0855ecSAndreas Gohr            // only require the installed.php file if this file is loaded from its dumped location,
343fd0855ecSAndreas Gohr            // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
344fd0855ecSAndreas Gohr            if (substr(__DIR__, -8, 1) !== 'C') {
345*dad993c5SAndreas Gohr                /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
346*dad993c5SAndreas Gohr                $required = require __DIR__ . '/installed.php';
347*dad993c5SAndreas Gohr                self::$installed = $required;
348fd0855ecSAndreas Gohr            } else {
349fd0855ecSAndreas Gohr                self::$installed = array();
350fd0855ecSAndreas Gohr            }
351fd0855ecSAndreas Gohr        }
352*dad993c5SAndreas Gohr
353*dad993c5SAndreas Gohr        if (self::$installed !== array()) {
354fd0855ecSAndreas Gohr            $installed[] = self::$installed;
355*dad993c5SAndreas Gohr        }
356fd0855ecSAndreas Gohr
357fd0855ecSAndreas Gohr        return $installed;
358fd0855ecSAndreas Gohr    }
359fd0855ecSAndreas Gohr}
360