vendor/symfony/ux-live-component/src/EventListener/AddLiveAttributesSubscriber.php line 43

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\UX\LiveComponent\EventListener;
  11. use Psr\Container\ContainerInterface;
  12. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  13. use Symfony\Contracts\Service\ServiceSubscriberInterface;
  14. use Symfony\UX\LiveComponent\Util\LiveControllerAttributesCreator;
  15. use Symfony\UX\TwigComponent\ComponentAttributes;
  16. use Symfony\UX\TwigComponent\ComponentMetadata;
  17. use Symfony\UX\TwigComponent\ComponentStack;
  18. use Symfony\UX\TwigComponent\Event\PreRenderEvent;
  19. use Symfony\UX\TwigComponent\MountedComponent;
  20. /**
  21.  * Adds the extra attributes needed to activate a live controller.
  22.  *
  23.  * Used during initial render and a re-render of a component.
  24.  *
  25.  * @author Kevin Bond <kevinbond@gmail.com>
  26.  *
  27.  * @experimental
  28.  *
  29.  * @internal
  30.  */
  31. final class AddLiveAttributesSubscriber implements EventSubscriberInterfaceServiceSubscriberInterface
  32. {
  33.     public function __construct(
  34.         private ComponentStack $componentStack,
  35.         private ContainerInterface $container
  36.     ) {
  37.     }
  38.     public function onPreRender(PreRenderEvent $event): void
  39.     {
  40.         if (!$event->getMetadata()->get('live'false)) {
  41.             // not a live component, skip
  42.             return;
  43.         }
  44.         if ($event->isEmbedded()) {
  45.             throw new \LogicException('Embedded components cannot be live.');
  46.         }
  47.         $metadata $event->getMetadata();
  48.         $attributes $this->getLiveAttributes($event->getMountedComponent(), $metadata);
  49.         $variables $event->getVariables();
  50.         $attributesKey $metadata->getAttributesVar();
  51.         // the original ComponentAttributes have already been processed and set
  52.         // onto the variables. So, we manually merge our new attributes in and
  53.         // override that variable.
  54.         if (isset($variables[$attributesKey]) && $variables[$attributesKey] instanceof ComponentAttributes) {
  55.             // merge with existing attributes if available
  56.             $attributes $attributes->defaults($variables[$attributesKey]->all());
  57.         }
  58.         // "key" is a special attribute: don't actually render it
  59.         // this is used inside LiveControllerAttributesCreator
  60.         $attributes $attributes->without(LiveControllerAttributesCreator::KEY_PROP_NAME);
  61.         $variables[$attributesKey] = $attributes;
  62.         $event->setVariables($variables);
  63.     }
  64.     public static function getSubscribedEvents(): array
  65.     {
  66.         return [PreRenderEvent::class => 'onPreRender'];
  67.     }
  68.     public static function getSubscribedServices(): array
  69.     {
  70.         return [
  71.             LiveControllerAttributesCreator::class,
  72.         ];
  73.     }
  74.     private function getLiveAttributes(MountedComponent $mountedComponentMetadata $metadata): ComponentAttributes
  75.     {
  76.         $attributesCreator $this->container->get(LiveControllerAttributesCreator::class);
  77.         \assert($attributesCreator instanceof LiveControllerAttributesCreator);
  78.         $attributesCollection $attributesCreator->attributesForRendering(
  79.             $mounted,
  80.             $metadata,
  81.             $this->componentStack->hasParentComponent()
  82.         );
  83.         return new ComponentAttributes($attributesCollection->toEscapedArray());
  84.     }
  85. }