src/EventListener/BuildVersionListener.php line 22

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\EventListener;
  4. use Symfony\Component\HttpFoundation\Response;
  5. use Symfony\Component\HttpKernel\Event\RequestEvent;
  6. final class BuildVersionListener
  7. {
  8.     private const MESSAGE_TEMPLATE_INVALID_VERSION 'Version conflict: version >= %s expected.';
  9.     private const MESSAGE_TEMPLATE_INVALID_BUILD   'Version conflict: build >= %s expected.';
  10.     public function __construct(
  11.         private readonly string $minVersion,
  12.         private readonly string $headerName,
  13.         private readonly array $paths
  14.     ) {
  15.     }
  16.     public function onKernelRequest(RequestEvent $event): void
  17.     {
  18.         if (!$event->isMainRequest()) {
  19.             return;
  20.         }
  21.         $request $event->getRequest();
  22.         if (
  23.             !$request->headers->has($this->headerName)
  24.             || !$this->matchPath($request->getPathInfo())
  25.         ) {
  26.             return;
  27.         }
  28.         $currentVersion $this->parseVersion($request->headers->get($this->headerName));
  29.         $minVersion     $this->parseVersion($this->minVersion);
  30.         switch (true) {
  31.             case version_compare($currentVersion['version'], $minVersion['version'], '<'):
  32.                 $message sprintf(self::MESSAGE_TEMPLATE_INVALID_VERSION$minVersion['version']);
  33.                 break;
  34.             case $currentVersion['build'] < $minVersion['build']:
  35.                 $message sprintf(self::MESSAGE_TEMPLATE_INVALID_BUILD$minVersion['build']);
  36.                 break;
  37.             default:
  38.                 return;
  39.         }
  40.         $response = new Response($messageResponse::HTTP_CONFLICT);
  41.         $event->setResponse($response);
  42.     }
  43.     private function matchPath(string $pathInfo): bool
  44.     {
  45.         foreach ($this->paths as $path) {
  46.             $pattern sprintf('#%s#ui'$path);
  47.             if (preg_match($pattern$pathInfo)) {
  48.                 return true;
  49.             }
  50.         }
  51.         return false;
  52.     }
  53.     private function parseVersion(string $version): array
  54.     {
  55.         $data = [
  56.             'version' => $version,
  57.             'build'   => 0,
  58.         ];
  59.         if (preg_match('/^(.*)-(\d+)$/ui'$version$matches)) {
  60.             $data = [
  61.                 'version' => $matches[1],
  62.                 'build'   => (int)$matches[2],
  63.             ];
  64.         }
  65.         return $data;
  66.     }
  67. }