PluginProbe ʕ •ᴥ•ʔ
WP 2FA – Two-factor authentication for WordPress / 2.4.2
WP 2FA – Two-factor authentication for WordPress v2.4.2
4.0.0 1.7.1 2.0.0 2.0.1 2.1.0 2.2.0 2.2.1 2.3.0 2.4.0 2.4.1 2.4.2 2.5.0 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.8.0 2.9.0 2.9.1 2.9.2 2.9.3 3.0.0 3.0.1 3.1.0 3.1.1 3.1.1.2 trunk 1.2.0 1.3.0 1.4.0 1.4.1 1.4.2 1.5.0 1.5.1 1.5.2 1.6.0 1.6.1 1.6.2 1.7.0
wp-2fa / vendor / composer / InstalledVersions.php
wp-2fa / vendor / composer Last commit date
ClassLoader.php 3 years ago InstalledVersions.php 3 years ago LICENSE 5 years ago autoload_classmap.php 3 years ago autoload_files.php 3 years ago autoload_namespaces.php 3 years ago autoload_psr4.php 3 years ago autoload_real.php 3 years ago autoload_static.php 3 years ago installed.json 3 years ago installed.php 3 years ago platform_check.php 3 years ago
InstalledVersions.php
314 lines
1 <?php
2
3 /*
4 * This file is part of Composer.
5 *
6 * (c) Nils Adermann <naderman@naderman.de>
7 * Jordi Boggiano <j.boggiano@seld.be>
8 *
9 * For the full copyright and license information, please view the LICENSE
10 * file that was distributed with this source code.
11 */
12 namespace Composer;
13
14 use Composer\Autoload\ClassLoader;
15 use Composer\Semver\VersionParser;
16 /**
17 * This class is copied in every Composer installed project and available to all
18 *
19 * See also https://getcomposer.org/doc/07-runtime.md#installed-versions
20 *
21 * To require its presence, you can require `composer-runtime-api ^2.0`
22 *
23 * @final
24 */
25 class InstalledVersions
26 {
27 /**
28 * @var mixed[]|null
29 * @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
30 */
31 private static $installed;
32 /**
33 * @var bool|null
34 */
35 private static $canGetVendors;
36 /**
37 * @var array[]
38 * @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[]}>}>
39 */
40 private static $installedByVendor = array();
41 /**
42 * Returns a list of all package names which are present, either by being installed, replaced or provided
43 *
44 * @return string[]
45 * @psalm-return list<string>
46 */
47 public static function getInstalledPackages()
48 {
49 $packages = array();
50 foreach (self::getInstalled() as $installed) {
51 $packages[] = \array_keys($installed['versions']);
52 }
53 if (1 === \count($packages)) {
54 return $packages[0];
55 }
56 return \array_keys(\array_flip(\call_user_func_array('array_merge', $packages)));
57 }
58 /**
59 * Returns a list of all package names with a specific type e.g. 'library'
60 *
61 * @param string $type
62 * @return string[]
63 * @psalm-return list<string>
64 */
65 public static function getInstalledPackagesByType($type)
66 {
67 $packagesByType = array();
68 foreach (self::getInstalled() as $installed) {
69 foreach ($installed['versions'] as $name => $package) {
70 if (isset($package['type']) && $package['type'] === $type) {
71 $packagesByType[] = $name;
72 }
73 }
74 }
75 return $packagesByType;
76 }
77 /**
78 * Checks whether the given package is installed
79 *
80 * This also returns true if the package name is provided or replaced by another package
81 *
82 * @param string $packageName
83 * @param bool $includeDevRequirements
84 * @return bool
85 */
86 public static function isInstalled($packageName, $includeDevRequirements = \true)
87 {
88 foreach (self::getInstalled() as $installed) {
89 if (isset($installed['versions'][$packageName])) {
90 return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === \false;
91 }
92 }
93 return \false;
94 }
95 /**
96 * Checks whether the given package satisfies a version constraint
97 *
98 * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
99 *
100 * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
101 *
102 * @param VersionParser $parser Install composer/semver to have access to this class and functionality
103 * @param string $packageName
104 * @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
105 * @return bool
106 */
107 public static function satisfies(VersionParser $parser, $packageName, $constraint)
108 {
109 $constraint = $parser->parseConstraints((string) $constraint);
110 $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
111 return $provided->matches($constraint);
112 }
113 /**
114 * Returns a version constraint representing all the range(s) which are installed for a given package
115 *
116 * It is easier to use this via isInstalled() with the $constraint argument if you need to check
117 * whether a given version of a package is installed, and not just whether it exists
118 *
119 * @param string $packageName
120 * @return string Version constraint usable with composer/semver
121 */
122 public static function getVersionRanges($packageName)
123 {
124 foreach (self::getInstalled() as $installed) {
125 if (!isset($installed['versions'][$packageName])) {
126 continue;
127 }
128 $ranges = array();
129 if (isset($installed['versions'][$packageName]['pretty_version'])) {
130 $ranges[] = $installed['versions'][$packageName]['pretty_version'];
131 }
132 if (\array_key_exists('aliases', $installed['versions'][$packageName])) {
133 $ranges = \array_merge($ranges, $installed['versions'][$packageName]['aliases']);
134 }
135 if (\array_key_exists('replaced', $installed['versions'][$packageName])) {
136 $ranges = \array_merge($ranges, $installed['versions'][$packageName]['replaced']);
137 }
138 if (\array_key_exists('provided', $installed['versions'][$packageName])) {
139 $ranges = \array_merge($ranges, $installed['versions'][$packageName]['provided']);
140 }
141 return \implode(' || ', $ranges);
142 }
143 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
144 }
145 /**
146 * @param string $packageName
147 * @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
148 */
149 public static function getVersion($packageName)
150 {
151 foreach (self::getInstalled() as $installed) {
152 if (!isset($installed['versions'][$packageName])) {
153 continue;
154 }
155 if (!isset($installed['versions'][$packageName]['version'])) {
156 return null;
157 }
158 return $installed['versions'][$packageName]['version'];
159 }
160 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
161 }
162 /**
163 * @param string $packageName
164 * @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
165 */
166 public static function getPrettyVersion($packageName)
167 {
168 foreach (self::getInstalled() as $installed) {
169 if (!isset($installed['versions'][$packageName])) {
170 continue;
171 }
172 if (!isset($installed['versions'][$packageName]['pretty_version'])) {
173 return null;
174 }
175 return $installed['versions'][$packageName]['pretty_version'];
176 }
177 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
178 }
179 /**
180 * @param string $packageName
181 * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
182 */
183 public static function getReference($packageName)
184 {
185 foreach (self::getInstalled() as $installed) {
186 if (!isset($installed['versions'][$packageName])) {
187 continue;
188 }
189 if (!isset($installed['versions'][$packageName]['reference'])) {
190 return null;
191 }
192 return $installed['versions'][$packageName]['reference'];
193 }
194 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
195 }
196 /**
197 * @param string $packageName
198 * @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.
199 */
200 public static function getInstallPath($packageName)
201 {
202 foreach (self::getInstalled() as $installed) {
203 if (!isset($installed['versions'][$packageName])) {
204 continue;
205 }
206 return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
207 }
208 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
209 }
210 /**
211 * @return array
212 * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
213 */
214 public static function getRootPackage()
215 {
216 $installed = self::getInstalled();
217 return $installed[0]['root'];
218 }
219 /**
220 * Returns the raw installed.php data for custom implementations
221 *
222 * @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.
223 * @return array[]
224 * @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[]}>}
225 */
226 public static function getRawData()
227 {
228 @\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);
229 if (null === self::$installed) {
230 // only require the installed.php file if this file is loaded from its dumped location,
231 // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
232 if (\substr(__DIR__, -8, 1) !== 'C') {
233 self::$installed = (include __DIR__ . '/installed.php');
234 } else {
235 self::$installed = array();
236 }
237 }
238 return self::$installed;
239 }
240 /**
241 * Returns the raw data of all installed.php which are currently loaded for custom implementations
242 *
243 * @return array[]
244 * @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[]}>}>
245 */
246 public static function getAllRawData()
247 {
248 return self::getInstalled();
249 }
250 /**
251 * Lets you reload the static array from another file
252 *
253 * This is only useful for complex integrations in which a project needs to use
254 * this class but then also needs to execute another project's autoloader in process,
255 * and wants to ensure both projects have access to their version of installed.php.
256 *
257 * A typical case would be PHPUnit, where it would need to make sure it reads all
258 * the data it needs from this class, then call reload() with
259 * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
260 * the project in which it runs can then also use this class safely, without
261 * interference between PHPUnit's dependencies and the project's dependencies.
262 *
263 * @param array[] $data A vendor/composer/installed.php data set
264 * @return void
265 *
266 * @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
267 */
268 public static function reload($data)
269 {
270 self::$installed = $data;
271 self::$installedByVendor = array();
272 }
273 /**
274 * @return array[]
275 * @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[]}>}>
276 */
277 private static function getInstalled()
278 {
279 if (null === self::$canGetVendors) {
280 self::$canGetVendors = \method_exists('Composer\\Autoload\\ClassLoader', 'getRegisteredLoaders');
281 }
282 $installed = array();
283 if (self::$canGetVendors) {
284 foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
285 if (isset(self::$installedByVendor[$vendorDir])) {
286 $installed[] = self::$installedByVendor[$vendorDir];
287 } elseif (\is_file($vendorDir . '/composer/installed.php')) {
288 /** @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 */
289 $required = (require $vendorDir . '/composer/installed.php');
290 $installed[] = self::$installedByVendor[$vendorDir] = $required;
291 if (null === self::$installed && \strtr($vendorDir . '/composer', '\\', '/') === \strtr(__DIR__, '\\', '/')) {
292 self::$installed = $installed[\count($installed) - 1];
293 }
294 }
295 }
296 }
297 if (null === self::$installed) {
298 // only require the installed.php file if this file is loaded from its dumped location,
299 // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
300 if (\substr(__DIR__, -8, 1) !== 'C') {
301 /** @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 */
302 $required = (require __DIR__ . '/installed.php');
303 self::$installed = $required;
304 } else {
305 self::$installed = array();
306 }
307 }
308 if (self::$installed !== array()) {
309 $installed[] = self::$installed;
310 }
311 return $installed;
312 }
313 }
314