PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.1
16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 All 504 releases
← All changes | vendor/composer/InstalledVersions.php +51 -7 12.2.3 → 16.3-a.1 View file →
@@ -26,8 +26,14 @@
26 26 */
27 27 class InstalledVersions
28 28 {
29 29 /**
30 + * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
31 + * @internal
32 + */
33 + private static $selfDir = null;
34 +
35 + /**
30 36 * @var mixed[]|null
31 37 * @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 38 */
33 39 private static $installed;
@@ -32,8 +38,13 @@
32 38 */
33 39 private static $installed;
34 40
35 41 /**
42 + * @var bool
43 + */
44 + private static $installedIsLocalDir;
45 +
46 + /**
36 47 * @var bool|null
37 48 */
38 49 private static $canGetVendors;
39 50
@@ -97,9 +108,9 @@
97 108 public static function isInstalled($packageName, $includeDevRequirements = true)
98 109 {
99 110 foreach (self::getInstalled() as $installed) {
100 111 if (isset($installed['versions'][$packageName])) {
101 - return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
112 + return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
102 113 }
103 114 }
104 115
105 116 return false;
@@ -118,9 +129,9 @@
118 129 * @return bool
119 130 */
120 131 public static function satisfies(VersionParser $parser, $packageName, $constraint)
121 132 {
122 - $constraint = $parser->parseConstraints($constraint);
133 + $constraint = $parser->parseConstraints((string) $constraint);
123 134 $provided = $parser->parseConstraints(self::getVersionRanges($packageName));
124 135
125 136 return $provided->matches($constraint);
126 137 }
@@ -308,11 +319,29 @@
308 319 public static function reload($data)
309 320 {
310 321 self::$installed = $data;
311 322 self::$installedByVendor = array();
323 +
324 + // when using reload, we disable the duplicate protection to ensure that self::$installed data is
325 + // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not,
326 + // so we have to assume it does not, and that may result in duplicate data being returned when listing
327 + // all installed packages for example
328 + self::$installedIsLocalDir = false;
312 329 }
313 330
314 331 /**
332 + * @return string
333 + */
334 + private static function getSelfDir()
335 + {
336 + if (self::$selfDir === null) {
337 + self::$selfDir = strtr(__DIR__, '\\', '/');
338 + }
339 +
340 + return self::$selfDir;
341 + }
342 +
343 + /**
315 344 * @return array[]
316 345 * @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 346 */
318 347 private static function getInstalled()
@@ -321,19 +350,29 @@
321 350 self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
322 351 }
323 352
324 353 $installed = array();
354 + $copiedLocalDir = false;
325 355
326 356 if (self::$canGetVendors) {
357 + $selfDir = self::getSelfDir();
327 358 foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
359 + $vendorDir = strtr($vendorDir, '\\', '/');
328 360 if (isset(self::$installedByVendor[$vendorDir])) {
329 361 $installed[] = self::$installedByVendor[$vendorDir];
330 362 } elseif (is_file($vendorDir.'/composer/installed.php')) {
331 - $installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
332 - if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
333 - self::$installed = $installed[count($installed) - 1];
363 + /** @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 */
364 + $required = require $vendorDir.'/composer/installed.php';
365 + self::$installedByVendor[$vendorDir] = $required;
366 + $installed[] = $required;
367 + if (self::$installed === null && $vendorDir.'/composer' === $selfDir) {
368 + self::$installed = $required;
369 + self::$installedIsLocalDir = true;
334 370 }
335 371 }
372 + if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) {
373 + $copiedLocalDir = true;
374 + }
336 375 }
337 376 }
338 377
339 378 if (null === self::$installed) {
@@ -339,14 +378,19 @@
339 378 if (null === self::$installed) {
340 379 // only require the installed.php file if this file is loaded from its dumped location,
341 380 // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
342 381 if (substr(__DIR__, -8, 1) !== 'C') {
343 - self::$installed = require __DIR__ . '/installed.php';
382 + /** @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 */
383 + $required = require __DIR__ . '/installed.php';
384 + self::$installed = $required;
344 385 } else {
345 386 self::$installed = array();
346 387 }
347 388 }
348 - $installed[] = self::$installed;
389 +
390 + if (self::$installed !== array() && !$copiedLocalDir) {
391 + $installed[] = self::$installed;
392 + }
349 393
350 394 return $installed;
351 395 }
352 396 }