Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

Installer.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 8.94 KiB


001  <?php
002   
003  declare(strict_types=1);
004   
005  namespace PackageVersions;
006   
007  use Composer\Composer;
008  use Composer\Config;
009  use Composer\EventDispatcher\EventSubscriberInterface;
010  use Composer\IO\IOInterface;
011  use Composer\Package\AliasPackage;
012  use Composer\Package\Locker;
013  use Composer\Package\PackageInterface;
014  use Composer\Package\RootPackageInterface;
015  use Composer\Plugin\PluginInterface;
016  use Composer\Script\Event;
017  use Composer\Script\ScriptEvents;
018  use Generator;
019  use RuntimeException;
020   
021  use function array_key_exists;
022  use function array_merge;
023  use function chmod;
024  use function dirname;
025  use function file_exists;
026  use function file_put_contents;
027  use function is_writable;
028  use function iterator_to_array;
029  use function rename;
030  use function sprintf;
031  use function uniqid;
032  use function var_export;
033   
034  final class Installer implements PluginInterface, EventSubscriberInterface
035  {
036      private static $generatedClassTemplate = <<<'PHP'
037  <?php
038   
039  declare(strict_types=1);
040   
041  namespace PackageVersions;
042   
043  use Composer\InstalledVersions;
044  use OutOfBoundsException;
045   
046  class_exists(InstalledVersions::class);
047   
048  /**
049   * This class is generated by composer/package-versions-deprecated, specifically by
050   * @see \PackageVersions\Installer
051   *
052   * This file is overwritten at every run of `composer install` or `composer update`.
053   *
054   * @deprecated in favor of the Composer\InstalledVersions class provided by Composer 2. Require composer-runtime-api:^2 to ensure it is present.
055   */
056  %s
057  {
058      /**
059       * @deprecated please use {@see self::rootPackageName()} instead.
060       *             This constant will be removed in version 2.0.0.
061       */
062      const ROOT_PACKAGE_NAME = '%s';
063   
064      /**
065       * Array of all available composer packages.
066       * Dont read this array from your calling code, but use the \PackageVersions\Versions::getVersion() method instead.
067       *
068       * @var array<string, string>
069       * @internal
070       */
071      const VERSIONS          = %s;
072   
073      private function __construct()
074      {
075      }
076   
077      /**
078       * @psalm-pure
079       *
080       * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
081       *                                  cause any side effects here.
082       */
083      public static function rootPackageName() : string
084      {
085          if (!self::composer2ApiUsable()) {
086              return self::ROOT_PACKAGE_NAME;
087          }
088   
089          return InstalledVersions::getRootPackage()['name'];
090      }
091   
092      /**
093       * @throws OutOfBoundsException If a version cannot be located.
094       *
095       * @psalm-param key-of<self::VERSIONS> $packageName
096       * @psalm-pure
097       *
098       * @psalm-suppress ImpureMethodCall we know that {@see InstalledVersions} interaction does not
099       *                                  cause any side effects here.
100       */
101      public static function getVersion(string $packageName): string
102      {
103          if (self::composer2ApiUsable()) {
104              return InstalledVersions::getPrettyVersion($packageName)
105                  . '@' . InstalledVersions::getReference($packageName);
106          }
107   
108          if (isset(self::VERSIONS[$packageName])) {
109              return self::VERSIONS[$packageName];
110          }
111   
112          throw new OutOfBoundsException(
113              'Required package "' . $packageName . '" is not installed: check your ./vendor/composer/installed.json and/or ./composer.lock files'
114          );
115      }
116   
117      private static function composer2ApiUsable(): bool
118      {
119          if (!class_exists(InstalledVersions::class, false)) {
120              return false;
121          }
122   
123          if (method_exists(InstalledVersions::class, 'getAllRawData')) {
124              $rawData = InstalledVersions::getAllRawData();
125              if (count($rawData) === 1 && count($rawData[0]) === 0) {
126                  return false;
127              }
128          } else {
129              $rawData = InstalledVersions::getRawData();
130              if ($rawData === null || $rawData === []) {
131                  return false;
132              }
133          }
134   
135          return true;
136      }
137  }
138   
139  PHP;
140   
141   
142      public function activate(Composer $composer, IOInterface $io)
143      {
144          // Nothing to do here, as all features are provided through event listeners
145      }
146   
147      public function deactivate(Composer $composer, IOInterface $io)
148      {
149          // Nothing to do here, as all features are provided through event listeners
150      }
151   
152      public function uninstall(Composer $composer, IOInterface $io)
153      {
154          // Nothing to do here, as all features are provided through event listeners
155      }
156   
157      /**
158       * {@inheritDoc}
159       */
160      public static function getSubscribedEvents(): array
161      {
162          return [ScriptEvents::POST_AUTOLOAD_DUMP => 'dumpVersionsClass'];
163      }
164   
165      /**
166       * @throws RuntimeException
167       */
168      public static function dumpVersionsClass(Event $composerEvent)
169      {
170          $composer    = $composerEvent->getComposer();
171          $rootPackage = $composer->getPackage();
172          $versions    = iterator_to_array(self::getVersions($composer->getLocker(), $rootPackage));
173   
174          if (! array_key_exists('composer/package-versions-deprecated', $versions)) {
175              //plugin must be globally installed - we only want to generate versions for projects which specifically
176              //require composer/package-versions-deprecated
177              return;
178          }
179   
180          $versionClass = self::generateVersionsClass($rootPackage->getName(), $versions);
181   
182          self::writeVersionClassToFile($versionClass, $composer, $composerEvent->getIO());
183      }
184   
185      /**
186       * @param string[] $versions
187       */
188      private static function generateVersionsClass(string $rootPackageName, array $versions): string
189      {
190          return sprintf(
191              self::$generatedClassTemplate,
192              'fin' . 'al ' . 'cla' . 'ss ' . 'Versions', // note: workaround for regex-based code parsers :-(
193              $rootPackageName,
194              var_export($versions, true)
195          );
196      }
197   
198      /**
199       * @throws RuntimeException
200       */
201      private static function writeVersionClassToFile(string $versionClassSource, Composer $composer, IOInterface $io)
202      {
203          $installPath = self::locateRootPackageInstallPath($composer->getConfig(), $composer->getPackage())
204              . '/src/PackageVersions/Versions.php';
205   
206          $installDir = dirname($installPath);
207          if (! file_exists($installDir)) {
208              $io->write('<info>composer/package-versions-deprecated:</info> Package not found (probably scheduled for removal); generation of version class skipped.');
209   
210              return;
211          }
212   
213          if (! is_writable($installDir)) {
214              $io->write(
215                  sprintf(
216                      '<info>composer/package-versions-deprecated:</info> %s is not writable; generation of version class skipped.',
217                      $installDir
218                  )
219              );
220   
221              return;
222          }
223   
224          $io->write('<info>composer/package-versions-deprecated:</info> Generating version class...');
225   
226          $installPathTmp = $installPath . '_' . uniqid('tmp', true);
227          file_put_contents($installPathTmp, $versionClassSource);
228          chmod($installPathTmp, 0664);
229          rename($installPathTmp, $installPath);
230   
231          $io->write('<info>composer/package-versions-deprecated:</info> ...done generating version class');
232      }
233   
234      /**
235       * @throws RuntimeException
236       */
237      private static function locateRootPackageInstallPath(
238          Config $composerConfig,
239          RootPackageInterface $rootPackage
240      ): string {
241          if (self::getRootPackageAlias($rootPackage)->getName() === 'composer/package-versions-deprecated') {
242              return dirname($composerConfig->get('vendor-dir'));
243          }
244   
245          return $composerConfig->get('vendor-dir') . '/composer/package-versions-deprecated';
246      }
247   
248      private static function getRootPackageAlias(RootPackageInterface $rootPackage): PackageInterface
249      {
250          $package = $rootPackage;
251   
252          while ($package instanceof AliasPackage) {
253              $package = $package->getAliasOf();
254          }
255   
256          return $package;
257      }
258   
259      /**
260       * @return Generator&string[]
261       *
262       * @psalm-return Generator<string, string>
263       */
264      private static function getVersions(Locker $locker, RootPackageInterface $rootPackage): Generator
265      {
266          $lockData = $locker->getLockData();
267   
268          $lockData['packages-dev'] = $lockData['packages-dev'] ?? [];
269   
270          $packages = $lockData['packages'];
271          if (getenv('COMPOSER_DEV_MODE') !== '0') {
272              $packages = array_merge($packages, $lockData['packages-dev']);
273          }
274          foreach ($packages as $package) {
275              yield $package['name'] => $package['version'] . '@' . (
276                  $package['source']['reference'] ?? $package['dist']['reference'] ?? ''
277              );
278          }
279   
280          foreach ($rootPackage->getReplaces() as $replace) {
281              $version = $replace->getPrettyConstraint();
282              if ($version === 'self.version') {
283                  $version = $rootPackage->getPrettyVersion();
284              }
285   
286              yield $replace->getTarget() => $version . '@' . $rootPackage->getSourceReference();
287          }
288   
289          yield $rootPackage->getName() => $rootPackage->getPrettyVersion() . '@' . $rootPackage->getSourceReference();
290      }
291  }
292