src/Elements/Bundle/DemiFrontendBundle/EventListener/DeviceDependentTemplateListener.php line 59

Open in your IDE?
  1. <?php
  2. /**
  3.  * Elements DeMI
  4.  *
  5.  * This source file is available under the elements DeMI license version 1
  6.  *
  7.  *  @copyright  Copyright (c) elements.at New Media Solutions GmbH (https://www.elements.at/)
  8.  *  @license    elements DeMI Lizenz Version 1 (https://www.elements.at/de/demi-lizenz)
  9.  */
  10. namespace Elements\Bundle\DemiFrontendBundle\EventListener;
  11. use Doctrine\Common\Persistence\Proxy;
  12. use JetBrains\PhpStorm\ArrayShape;
  13. use Pimcore\Tool\DeviceDetector;
  14. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
  15. use Symfony\Bundle\FrameworkBundle\Templating\TemplateReference;
  16. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  17. use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
  18. use Symfony\Component\HttpKernel\Event\ViewEvent;
  19. use Symfony\Component\HttpKernel\KernelEvents;
  20. use Symfony\Component\HttpKernel\KernelInterface;
  21. class DeviceDependentTemplateListener implements EventSubscriberInterface
  22. {
  23.     public function __construct(protected KernelInterface $kernel)
  24.     {
  25.     }
  26.     /**
  27.      * @inheritDoc
  28.      */
  29.     #[ArrayShape([KernelEvents::VIEW => "array"])] public static function getSubscribedEvents()
  30.     {
  31.         return [
  32.             KernelEvents::VIEW => ['onKernelView'20]
  33.         ];
  34.     }
  35.     public static function getTemplateName($path$templateName$view$forceTemplateType '')
  36.     {
  37.         if (empty($forceTemplateType)) {
  38.             $deviceType 'desktop';
  39.             if (DeviceDetector::getInstance()->isPhone()) {
  40.                 $deviceType 'mobile';
  41.             }
  42.         } else {
  43.             $deviceType $forceTemplateType;
  44.         }
  45.         if ($view->exists($path $templateName .'.'$deviceType .'.html.php')) {
  46.             return $path $templateName .'.'$deviceType '.html.php';
  47.         }
  48.         return $path $templateName '.html.php';
  49.     }
  50.     public function onKernelView(ViewEvent $event)
  51.     {
  52.         $request $event->getRequest();
  53.         if (!$request->get('_demi_frontend_request')) {
  54.             return;
  55.         }
  56.         if ($request->attributes->has('_template')) {
  57.             $deviceType 'desktop';
  58.             if (DeviceDetector::getInstance()->isPhone()) {
  59.                 $deviceType 'mobile';
  60.             }
  61.             $template $request->attributes->get('_template');
  62.             $className self::getRealClass(\get_class($template->getOwner()[0]));
  63.             $matchController $matchAction null;
  64.             if (preg_match('/Controller\\\(.+)Controller$/'$className$tempMatch)) {
  65.                 $matchController $tempMatch;
  66.             }
  67.             if ($template->getOwner()[1] === '__invoke') {
  68.                 $matchAction $matchController;
  69.                 $matchController null;
  70.             } elseif (!preg_match('/^(.+)Action$/'$template->getOwner()[1], $matchAction)) {
  71.                 $matchAction = [null$template->getOwner()[1]];
  72.             }
  73.             $bundle $this->getBundleForClass($className);
  74.             if ($bundle) {
  75.                 while ($bundleName $bundle->getName()) {
  76.                     if (!method_exists($bundle'getParent') || (null === $parentBundleName $bundle->getParent())) {
  77.                         $bundleName $bundle->getName();
  78.                         break;
  79.                     }
  80.                     $bundles $this->kernel->getBundle($parentBundleNamefalse);
  81.                     $bundle array_pop($bundles);
  82.                 }
  83.             } else {
  84.                 $bundleName null;
  85.             }
  86.             $deviceTemplateReference = new TemplateReference($bundleName$matchController[1], $matchAction[1] . '.' $deviceType$request->getRequestFormat(), 'php');
  87.             try {
  88.                 $this->kernel->locateResource($deviceTemplateReference->getPath());
  89.                 $template->setTemplate($deviceTemplateReference);
  90.             } catch (\Exception $e) {
  91.                 // do nothing
  92.             }
  93.         }
  94.     }
  95.     private static function getRealClass(string $class): string
  96.     {
  97.         if (false === $pos strrpos($class'\\'.Proxy::MARKER.'\\')) {
  98.             return $class;
  99.         }
  100.         return substr($class$pos Proxy::MARKER_LENGTH 2);
  101.     }
  102.     protected function getBundleForClass($class): mixed
  103.     {
  104.         $reflectionClass = new \ReflectionClass($class);
  105.         $returnBundle null;
  106.         $bundles $this->kernel->getBundles();
  107.         do {
  108.             $namespace $reflectionClass->getNamespaceName();
  109.             foreach ($bundles as $bundle) {
  110.                 if (str_starts_with($namespace$bundle->getNamespace())) {
  111.                     $returnBundle $bundle;
  112.                     break;
  113.                 }
  114.             }
  115.             $reflectionClass $reflectionClass->getParentClass();
  116.         } while ($reflectionClass);
  117.         return $returnBundle;
  118.     }
  119. }