[ 'onBuildForm', -200 ], RegistrationEvents::HANDLE_FORM => [ 'onHandleForm', -20 // After persisting user ], KernelEvents::REQUEST => 'onKernelRequest' ]; if (class_exists(AdminEvents::class) && defined(AdminEvents::class . '::FILTER_LIST')) { $handlers[AdminEvents::FILTER_LIST] = [ [ 'onFilterListCreateForm', 10 ], [ 'onFilterListFilter', -10 ] ]; } return $handlers; } public function __construct($terms, $tosVersion, EntityManagerInterface $em, TokenStorageInterface $tokenStorage, UrlGeneratorInterface $urlGenerator) { $this->terms = $terms; $this->tosVersion = $tosVersion; $this->em = $em; $this->tokenStorage = $tokenStorage; $this->urlGenerator = $urlGenerator; } public function onBuildForm(RegistrationFormEvent $event) { $event->getFormBuilder()->add('vl_tos', AcceptTosType::class, [ 'terms' => $this->terms, 'mapped' => false ]); } public function onHandleForm(RegistrationHandleEvent $event) { if ($event->getForm() ->get('vl_tos') ->getData()['accept']) { $user = $event->getForm()->getData(); /* @var $user \App\Entity\User */ $tosUser = new UserTos($user); $tosUser->setAcceptedVersion($this->tosVersion); $this->em->persist($tosUser); } } public function onKernelRequest(GetResponseEvent $event) { if (!$event->isMasterRequest()) return; if (!($token = $this->tokenStorage->getToken())) return; if (!($user = $token->getUser())) return; if (!($user instanceof User)) return; if ($token->hasAttribute('vl_tos_accept_ok')) return; $userTos = $this->em->find(UserTos::class, $user); if ($userTos && $userTos->getAcceptedVersion() >= $this->tosVersion) { $token->setAttribute('vl_tos_accept_ok', true); return; } if ($event->getRequest()->getRequestFormat() !== 'html') { throw new AccessDeniedHttpException('You need to accept the latest version of the terms of service.'); } switch ($event->getRequest()->attributes->get('_route')) { case 'vl_tos_accept': break; default: $response = RedirectResponse::create($this->urlGenerator->generate('vl_tos_accept')); $event->setResponse($response); } } public function onFilterListCreateForm(FilterListEvent $event) { $event->getSearchFormBuilder()->add('tos_accepted', ChoiceType::class, [ 'choices' => [ 'Yes' => '1', 'No' => '0' ], 'expanded' => true, 'required' => false ]); } public function onFilterListFilter(FilterListEvent $event) { $field = $event->getSearchForm()->get('tos_accepted'); if ($field->isEmpty() || $field->getData() === null) return; $toses = $this->em->createQueryBuilder() ->select('t') ->from(UserTos::class, 't') ->where('t.acceptedVersion >= :currentVersion') ->setParameter('currentVersion', $this->tosVersion) ->groupBy('t.user') ->getQuery() ->getArrayResult(); $userIds = array_map(function ($tos) { return $tos['user_id']; }, $toses); $expr = $field->getData() === "1" ? Criteria::expr()->in('id', $userIds) : Criteria::expr()->notIn('id', $userIds); $event->addFilter('tos_accepted', $expr); } }