PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.15.0
Independent Analytics – WordPress Analytics Plugin v2.15.0
2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / vendor / composer / InstalledVersions.php
independent-analytics / vendor / composer Last commit date
ClassLoader.php 2 years ago InstalledVersions.php 1 year ago LICENSE 3 years ago autoload_classmap.php 3 days ago autoload_files.php 3 days ago autoload_namespaces.php 3 years ago autoload_psr4.php 3 days ago autoload_real.php 3 days ago autoload_static.php 3 days ago installed.json 3 days ago installed.php 3 days ago platform_check.php 3 days ago
InstalledVersions.php
347 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 IAWPSCOPED\Composer;
13
14 use IAWPSCOPED\Composer\Autoload\ClassLoader;
15 use IAWPSCOPED\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 * @internal
25 */
26 class InstalledVersions
27 {
28 /**
29 * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
30 * @internal
31 */
32 private static $selfDir = null;
33 /**
34 * @var mixed[]|null
35 * @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
36 */
37 private static $installed;
38 /**
39 * @var bool
40 */
41 private static $installedIsLocalDir;
42 /**
43 * @var bool|null
44 */
45 private static $canGetVendors;
46 /**
47 * @var array[]
48 * @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[]}>}>
49 */
50 private static $installedByVendor = array();
51 /**
52 * Returns a list of all package names which are present, either by being installed, replaced or provided
53 *
54 * @return string[]
55 * @psalm-return list<string>
56 */
57 public static function getInstalledPackages()
58 {
59 $packages = array();
60 foreach (self::getInstalled() as $installed) {
61 $packages[] = \array_keys($installed['versions']);
62 }
63 if (1 === \count($packages)) {
64 return $packages[0];
65 }
66 return \array_keys(\array_flip(\call_user_func_array('IAWPSCOPED\\array_merge', $packages)));
67 }
68 /**
69 * Returns a list of all package names with a specific type e.g. 'library'
70 *
71 * @param string $type
72 * @return string[]
73 * @psalm-return list<string>
74 */
75 public static function getInstalledPackagesByType($type)
76 {
77 $packagesByType = array();
78 foreach (self::getInstalled() as $installed) {
79 foreach ($installed['versions'] as $name => $package) {
80 if (isset($package['type']) && $package['type'] === $type) {
81 $packagesByType[] = $name;
82 }
83 }
84 }
85 return $packagesByType;
86 }
87 /**
88 * Checks whether the given package is installed
89 *
90 * This also returns true if the package name is provided or replaced by another package
91 *
92 * @param string $packageName
93 * @param bool $includeDevRequirements
94 * @return bool
95 */
96 public static function isInstalled($packageName, $includeDevRequirements = \true)
97 {
98 foreach (self::getInstalled() as $installed) {
99 if (isset($installed['versions'][$packageName])) {
100 return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === \false;
101 }
102 }
103 return \false;
104 }
105 /**
106 * Checks whether the given package satisfies a version constraint
107 *
108 * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
109 *
110 * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
111 *
112 * @param VersionParser $parser Install composer/semver to have access to this class and functionality
113 * @param string $packageName
114 * @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
115 * @return bool
116 */
117 public static function satisfies(VersionParser $parser, $packageName, $constraint)
118 {
119 $constraint = $parser->parseConstraints((string) $constraint);
120 $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
121 return $provided->matches($constraint);
122 }
123 /**
124 * Returns a version constraint representing all the range(s) which are installed for a given package
125 *
126 * It is easier to use this via isInstalled() with the $constraint argument if you need to check
127 * whether a given version of a package is installed, and not just whether it exists
128 *
129 * @param string $packageName
130 * @return string Version constraint usable with composer/semver
131 */
132 public static function getVersionRanges($packageName)
133 {
134 foreach (self::getInstalled() as $installed) {
135 if (!isset($installed['versions'][$packageName])) {
136 continue;
137 }
138 $ranges = array();
139 if (isset($installed['versions'][$packageName]['pretty_version'])) {
140 $ranges[] = $installed['versions'][$packageName]['pretty_version'];
141 }
142 if (\array_key_exists('aliases', $installed['versions'][$packageName])) {
143 $ranges = \array_merge($ranges, $installed['versions'][$packageName]['aliases']);
144 }
145 if (\array_key_exists('replaced', $installed['versions'][$packageName])) {
146 $ranges = \array_merge($ranges, $installed['versions'][$packageName]['replaced']);
147 }
148 if (\array_key_exists('provided', $installed['versions'][$packageName])) {
149 $ranges = \array_merge($ranges, $installed['versions'][$packageName]['provided']);
150 }
151 return \implode(' || ', $ranges);
152 }
153 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
154 }
155 /**
156 * @param string $packageName
157 * @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
158 */
159 public static function getVersion($packageName)
160 {
161 foreach (self::getInstalled() as $installed) {
162 if (!isset($installed['versions'][$packageName])) {
163 continue;
164 }
165 if (!isset($installed['versions'][$packageName]['version'])) {
166 return null;
167 }
168 return $installed['versions'][$packageName]['version'];
169 }
170 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
171 }
172 /**
173 * @param string $packageName
174 * @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
175 */
176 public static function getPrettyVersion($packageName)
177 {
178 foreach (self::getInstalled() as $installed) {
179 if (!isset($installed['versions'][$packageName])) {
180 continue;
181 }
182 if (!isset($installed['versions'][$packageName]['pretty_version'])) {
183 return null;
184 }
185 return $installed['versions'][$packageName]['pretty_version'];
186 }
187 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
188 }
189 /**
190 * @param string $packageName
191 * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
192 */
193 public static function getReference($packageName)
194 {
195 foreach (self::getInstalled() as $installed) {
196 if (!isset($installed['versions'][$packageName])) {
197 continue;
198 }
199 if (!isset($installed['versions'][$packageName]['reference'])) {
200 return null;
201 }
202 return $installed['versions'][$packageName]['reference'];
203 }
204 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
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 install path. Packages of type metapackages also have a null install path.
209 */
210 public static function getInstallPath($packageName)
211 {
212 foreach (self::getInstalled() as $installed) {
213 if (!isset($installed['versions'][$packageName])) {
214 continue;
215 }
216 return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
217 }
218 throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
219 }
220 /**
221 * @return array
222 * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
223 */
224 public static function getRootPackage()
225 {
226 $installed = self::getInstalled();
227 return $installed[0]['root'];
228 }
229 /**
230 * Returns the raw installed.php data for custom implementations
231 *
232 * @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.
233 * @return array[]
234 * @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[]}>}
235 */
236 public static function getRawData()
237 {
238 @\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);
239 if (null === self::$installed) {
240 // only require the installed.php file if this file is loaded from its dumped location,
241 // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
242 if (\substr(__DIR__, -8, 1) !== 'C') {
243 self::$installed = (include __DIR__ . '/installed.php');
244 } else {
245 self::$installed = array();
246 }
247 }
248 return self::$installed;
249 }
250 /**
251 * Returns the raw data of all installed.php which are currently loaded for custom implementations
252 *
253 * @return array[]
254 * @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[]}>}>
255 */
256 public static function getAllRawData()
257 {
258 return self::getInstalled();
259 }
260 /**
261 * Lets you reload the static array from another file
262 *
263 * This is only useful for complex integrations in which a project needs to use
264 * this class but then also needs to execute another project's autoloader in process,
265 * and wants to ensure both projects have access to their version of installed.php.
266 *
267 * A typical case would be PHPUnit, where it would need to make sure it reads all
268 * the data it needs from this class, then call reload() with
269 * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
270 * the project in which it runs can then also use this class safely, without
271 * interference between PHPUnit's dependencies and the project's dependencies.
272 *
273 * @param array[] $data A vendor/composer/installed.php data set
274 * @return void
275 *
276 * @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
277 */
278 public static function reload($data)
279 {
280 self::$installed = $data;
281 self::$installedByVendor = array();
282 // when using reload, we disable the duplicate protection to ensure that self::$installed data is
283 // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
284 // so we have to assume it does not, and that may result in duplicate data being returned when listing
285 // all installed packages for example
286 self::$installedIsLocalDir = \false;
287 }
288 /**
289 * @return string
290 */
291 private static function getSelfDir()
292 {
293 if (self::$selfDir === null) {
294 self::$selfDir = \strtr(__DIR__, '\\', '/');
295 }
296 return self::$selfDir;
297 }
298 /**
299 * @return array[]
300 * @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[]}>}>
301 */
302 private static function getInstalled()
303 {
304 if (null === self::$canGetVendors) {
305 self::$canGetVendors = \method_exists('IAWPSCOPED\\Composer\\Autoload\\ClassLoader', 'getRegisteredLoaders');
306 }
307 $installed = array();
308 $copiedLocalDir = \false;
309 if (self::$canGetVendors) {
310 $selfDir = self::getSelfDir();
311 foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
312 $vendorDir = \strtr($vendorDir, '\\', '/');
313 if (isset(self::$installedByVendor[$vendorDir])) {
314 $installed[] = self::$installedByVendor[$vendorDir];
315 } elseif (\is_file($vendorDir . '/composer/installed.php')) {
316 /** @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 */
317 $required = (require $vendorDir . '/composer/installed.php');
318 self::$installedByVendor[$vendorDir] = $required;
319 $installed[] = $required;
320 if (self::$installed === null && $vendorDir . '/composer' === $selfDir) {
321 self::$installed = $required;
322 self::$installedIsLocalDir = \true;
323 }
324 }
325 if (self::$installedIsLocalDir && $vendorDir . '/composer' === $selfDir) {
326 $copiedLocalDir = \true;
327 }
328 }
329 }
330 if (null === self::$installed) {
331 // only require the installed.php file if this file is loaded from its dumped location,
332 // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
333 if (\substr(__DIR__, -8, 1) !== 'C') {
334 /** @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 */
335 $required = (require __DIR__ . '/installed.php');
336 self::$installed = $required;
337 } else {
338 self::$installed = array();
339 }
340 }
341 if (self::$installed !== array() && !$copiedLocalDir) {
342 $installed[] = self::$installed;
343 }
344 return $installed;
345 }
346 }
347