2022-05-20 13:50:04 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Core\EventListener;
|
|
|
|
|
|
|
|
use App\Core\Ab\AbContainer;
|
|
|
|
use App\Core\Ab\AbTest;
|
2022-05-21 00:15:37 +02:00
|
|
|
use App\Core\Entity\Site\Node;
|
2022-05-20 13:50:04 +02:00
|
|
|
use App\Core\Event\Ab\AbTestEvent;
|
2022-05-21 00:15:37 +02:00
|
|
|
use App\Core\Site\SiteRequest;
|
2022-05-20 13:50:04 +02:00
|
|
|
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
|
|
|
use Symfony\Component\HttpFoundation\Cookie;
|
2022-05-21 00:15:37 +02:00
|
|
|
use Symfony\Component\HttpFoundation\Request;
|
2022-05-20 13:50:04 +02:00
|
|
|
use Symfony\Component\HttpKernel\Event\RequestEvent;
|
|
|
|
use Symfony\Component\HttpKernel\Event\ResponseEvent;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* class AbListener.
|
|
|
|
*
|
|
|
|
* @author Simon Vieille <simon@deblan.fr>
|
|
|
|
*/
|
|
|
|
class AbListener
|
|
|
|
{
|
2022-05-21 00:15:37 +02:00
|
|
|
protected ?Node $node;
|
2022-05-20 13:50:04 +02:00
|
|
|
|
|
|
|
public function __construct(
|
2023-10-20 09:44:18 +02:00
|
|
|
protected AbContainer $container,
|
|
|
|
protected EventDispatcherInterface $eventDispatcher,
|
|
|
|
protected SiteRequest $siteRequest
|
2022-05-20 13:50:04 +02:00
|
|
|
) {
|
|
|
|
}
|
|
|
|
|
|
|
|
public function onKernelRequest(RequestEvent $event)
|
|
|
|
{
|
2022-05-21 00:15:37 +02:00
|
|
|
$this->node = $this->siteRequest->getNode();
|
2022-05-20 13:50:04 +02:00
|
|
|
|
2022-05-21 00:15:37 +02:00
|
|
|
if (!$this->supports($event->getRequest())) {
|
2022-05-20 13:50:04 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-05-21 00:15:37 +02:00
|
|
|
$request = $event->getRequest();
|
|
|
|
$cookieName = md5($this->getCookieName());
|
|
|
|
$cookieValue = $event->getRequest()->cookies->get($cookieName);
|
2022-05-20 13:50:04 +02:00
|
|
|
|
2022-05-21 00:15:37 +02:00
|
|
|
$abTest = new AbTest($this->getAbTestCode());
|
2022-05-20 13:50:04 +02:00
|
|
|
$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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-10-12 16:15:07 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-05-21 00:15:37 +02:00
|
|
|
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;
|
|
|
|
}
|
2022-05-20 13:50:04 +02:00
|
|
|
}
|