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