vendor/shopware/core/Framework/Api/EventListener/ExpectationSubscriber.php line 59

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Shopware\Core\Framework\Api\EventListener;
  3. use Composer\InstalledVersions;
  4. use Composer\Semver\Semver;
  5. use Shopware\Core\Framework\Api\Exception\ExceptionFailedException;
  6. use Shopware\Core\Framework\Log\Package;
  7. use Shopware\Core\Framework\Routing\Annotation\RouteScope;
  8. use Shopware\Core\Framework\Routing\ApiRouteScope;
  9. use Shopware\Core\Framework\Routing\KernelListenerPriorities;
  10. use Shopware\Core\PlatformRequest;
  11. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpKernel\Event\ControllerEvent;
  14. use Symfony\Component\HttpKernel\KernelEvents;
  15. /**
  16.  * @deprecated tag:v6.5.0 - reason:becomes-internal - EventSubscribers will become internal in v6.5.0
  17.  *
  18.  * @phpstan-type PluginData array{'composerName': string, 'active': bool, 'version': string}
  19.  */
  20. #[Package('core')]
  21. class ExpectationSubscriber implements EventSubscriberInterface
  22. {
  23.     private const SHOPWARE_CORE_PACKAGES = [
  24.         'shopware/platform',
  25.         'shopware/core',
  26.         'shopware/administration',
  27.         'shopware/elasticsearch',
  28.         'shopware/storefront',
  29.     ];
  30.     private string $shopwareVersion;
  31.     /**
  32.      * @var list<PluginData>
  33.      */
  34.     private array $plugins;
  35.     /**
  36.      * @internal
  37.      *
  38.      * @param list<PluginData> $plugins
  39.      */
  40.     public function __construct(string $shopwareVersion, array $plugins)
  41.     {
  42.         $this->shopwareVersion $shopwareVersion;
  43.         $this->plugins $plugins;
  44.     }
  45.     public static function getSubscribedEvents(): array
  46.     {
  47.         return [
  48.             KernelEvents::CONTROLLER => ['checkExpectations'KernelListenerPriorities::KERNEL_CONTROLLER_EVENT_SCOPE_VALIDATE_POST],
  49.         ];
  50.     }
  51.     public function checkExpectations(ControllerEvent $event): void
  52.     {
  53.         $request $event->getRequest();
  54.         if (!$request->attributes->has(PlatformRequest::ATTRIBUTE_ROUTE_SCOPE)) {
  55.             return;
  56.         }
  57.         /** @var RouteScope|list<string> $scope */
  58.         $scope $request->attributes->get(PlatformRequest::ATTRIBUTE_ROUTE_SCOPE, []);
  59.         if ($scope instanceof RouteScope) {
  60.             $scope $scope->getScopes();
  61.         }
  62.         if (!\in_array(ApiRouteScope::ID$scopetrue)) {
  63.             return;
  64.         }
  65.         $expectations $this->checkPackages($request);
  66.         if (\count($expectations)) {
  67.             throw new ExceptionFailedException($expectations);
  68.         }
  69.     }
  70.     /**
  71.      * @return list<string>
  72.      */
  73.     private function checkPackages(Request $request): array
  74.     {
  75.         // swag/plugin1:~6.1,swag/plugin2:~6.1
  76.         $extensionConstraints array_filter(explode(',', (string) $request->headers->get(PlatformRequest::HEADER_EXPECT_PACKAGES)));
  77.         if ($extensionConstraints === []) {
  78.             return [];
  79.         }
  80.         $plugins $this->getIndexedPackages();
  81.         $fails = [];
  82.         foreach ($extensionConstraints as $extension) {
  83.             $explode explode(':'$extension);
  84.             if (\count($explode) !== 2) {
  85.                 $fails[] = sprintf('Got invalid string: "%s"'$extension);
  86.                 continue;
  87.             }
  88.             $name $explode[0];
  89.             $constraint $explode[1];
  90.             if (isset($plugins[$name])) {
  91.                 $installedVersion $plugins[$name];
  92.             } else {
  93.                 try {
  94.                     $installedVersion InstalledVersions::getPrettyVersion($name);
  95.                 } catch (\OutOfBoundsException $e) {
  96.                     $fails[] = sprintf('Requested package: %s is not available'$name);
  97.                     continue;
  98.                 }
  99.                 if (\in_array($nameself::SHOPWARE_CORE_PACKAGEStrue)) {
  100.                     $installedVersion $this->shopwareVersion;
  101.                 }
  102.             }
  103.             if ($installedVersion === null) {
  104.                 // should never happen, but phpstan would complain otherwise
  105.                 continue;
  106.             }
  107.             if (Semver::satisfies($installedVersion$constraint)) {
  108.                 continue;
  109.             }
  110.             $fails[] = sprintf('Version constraint for %s is failed. Installed is: %s'$name$installedVersion);
  111.         }
  112.         return $fails;
  113.     }
  114.     /**
  115.      * Plugins are not in the InstalledPackages file until now
  116.      *
  117.      * @return array<string, string>
  118.      */
  119.     private function getIndexedPackages(): array
  120.     {
  121.         $versions = [];
  122.         foreach ($this->plugins as $plugin) {
  123.             if (!$plugin['active']) {
  124.                 continue;
  125.             }
  126.             $versions[$plugin['composerName']] = $plugin['version'];
  127.         }
  128.         return $versions;
  129.     }
  130. }