*/ class AbListener { protected ?Node $node; public function __construct( protected AbContainer $container, protected EventDispatcherInterface $eventDispatcher, protected SiteRequest $siteRequest ) { } public function onKernelRequest(RequestEvent $event) { $this->node = $this->siteRequest->getNode(); if (!$this->supports($event->getRequest())) { return; } $request = $event->getRequest(); $cookieName = md5($this->getCookieName()); $cookieValue = $event->getRequest()->cookies->get($cookieName); $abTest = new AbTest($this->getAbTestCode()); $event = new AbTestEvent($abTest); $this->container->add($abTest); $this->eventDispatcher->dispatch($event, AbTestEvent::INIT_EVENT); if (!$abTest->isValidVariation($cookieValue)) { $abTest->run(); $result = $abTest->getResult(); $attributes = array_merge($request->attributes->get('ab_test_cookies', []), [ $cookieName => ['value' => $result, 'duration' => $abTest->getDuration()], ]); $request->attributes->set('ab_test_cookies', $attributes); $this->eventDispatcher->dispatch($event, AbTestEvent::RUN_EVENT); } else { $abTest->setResult($cookieValue); } } public function onKernelResponse(ResponseEvent $event) { $cookies = $event->getRequest()->attributes->get('ab_test_cookies', []); foreach ($cookies as $name => $value) { $cookie = Cookie::create($name, $value['value'], time() + $value['duration']); $event->getResponse()->headers->setCookie($cookie); } } protected function getCookieName(): string { return 'ab_test_'.$this->getAbTestCode(); } protected function getAbTestCode(): string { return $this->node->getAbTestCode(); } protected function supports(Request $request): bool { if (!$this->node) { return false; } if (!$this->node->getHasAbTest()) { return false; } if (!$this->node->getAbTestCode()) { return false; } return true; } }