src/Service/RequestService.php line 239

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use App\Entity\Permission;
  4. use App\Entity\Role;
  5. use Symfony\Component\HttpFoundation\RequestStack;
  6. use Doctrine\Common\Annotations\Reader;
  7. use App\Entity\Log;
  8. use App\Exception\CacheHitResponse;
  9. use App\Exception\AccessDeniedException;
  10. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  11. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  12. use Gedmo\Translatable\TranslatableListener;
  13. /**
  14.  * Class RequestService
  15.  * @package App\Service
  16.  */
  17. class RequestService extends BaseService
  18. {
  19.     public $exception null;
  20.     public $exceptionCode 0;
  21.     public $methodName null;
  22.     public $logging false;
  23.     public $log null;
  24.     public $useCache false;
  25.     public $cacheResponseKey null;
  26.     public $isBackend false;
  27.     public $language 'fr';
  28.     public $deletedEntities = [];
  29.     public $timezone null;
  30.     /**
  31.      * RequestService constructor.
  32.      * @param BaseService $baseService
  33.      * @param Reader $reader
  34.      * @param UserAgentService $userAgentService
  35.      */
  36.     public function __construct(
  37.         BaseService $baseService,
  38.         private Reader $reader,
  39.         private RequestStack $requestStack,
  40.         private TranslatableListener $translatableListener
  41.     ) {
  42.         $this->reflectFromParent($baseService);
  43.     }
  44.     public function checkPermission($methodName$controller)
  45.     {
  46.         if ($methodName == 'showAction') return;
  47.         $this->isBackend strpos(get_class($controller), 'Backend') !== false;
  48.         $token $this->getToken();
  49.         if ((!$token || !($token->getUser() instanceof \App\Entity\User)) && (!$this->isBackend || $methodName === 'authenticate')) {
  50.             return;
  51.         }
  52.         // except public route
  53.         $isPublicRoute $this->checkAnnotation(
  54.             'App\Annotation\PermissionPublic',
  55.             $methodName,
  56.             $controller
  57.         );
  58.         if ($isPublicRoute) return;
  59.         // check user route
  60.         $isUserRoute $this->checkAnnotation(
  61.             'App\Annotation\PermissionUser',
  62.             $methodName,
  63.             $controller
  64.         );
  65.         if ($isUserRoute && !empty($token)) return;
  66.         // check admin route
  67.         $isAdminRoute $this->checkAnnotation(
  68.             'App\Annotation\PermissionAdmin',
  69.             $methodName,
  70.             $controller
  71.         );
  72.         if ($isAdminRoute) {
  73.             // If super admin -> permit allow all
  74.             if (!empty($token) && $this->isSuperAdmin($this->getUser())) {
  75.                 return;
  76.             }
  77.             if (empty($token) || !$this->isAdmin($this->getUser())) {
  78.                 throw new AccessDeniedException(AccessDeniedException::NOT_PERMITTED$methodName);
  79.             }
  80.             $controllerClassName get_class($controller);
  81.             if (!$this->userService->isGranted($this->getUser(), $controllerClassName$methodName)) {
  82.                 throw new AccessDeniedException(AccessDeniedException::NOT_PERMITTED$methodName);
  83.             }
  84.             return;
  85.         }
  86.     }
  87.     public function startLogging($methodName$controller)
  88.     {
  89.         $this->methodName $methodName;
  90.         $this->logging $this->checkAnnotation('App\Annotation\Log'$methodName$controller);
  91.     }
  92.     public function startCache($methodName$controller)
  93.     {
  94.         $request $this->requestStack->getCurrentRequest();
  95.         $this->language $request->headers->get('X-Language') ?? 'fr';
  96.         $this->useCache $this->checkAnnotation('App\Annotation\Cache'$methodName$controller);
  97.         if ($this->useCache === true) {
  98.             $route $request->attributes->get('_route');
  99.             $routeParams $request->attributes->get('_route_params');
  100.             $allInputs array_merge($this->stripRequest($request), $routeParams);
  101.             $allInputs['lang'] = $this->language;
  102.             $hashedInputs md5(json_encode($allInputs1));
  103.             $this->cacheResponseKey 'Response.' $route '.' $hashedInputs;
  104.             $cacheResponse $this->appCache->getItem($this->cacheResponseKey);
  105.             if ($cacheResponse->isHit()) {
  106.                 $payload json_decode($cacheResponse->get(), 1);
  107.                 $data json_encode($payload['data'], 1);
  108.                 throw new CacheHitResponse($data$payload['code']);
  109.             }
  110.         }
  111.     }
  112.     public function checkAnnotation($nameAnnotation$methodName$controller)
  113.     {
  114.         $controllerName $this->commonService->getClassName($controller);
  115.         $annotationShortName $this->commonService->getClassName($nameAnnotation);
  116.         $cacheKey 'Annotation.' $annotationShortName '.' $controllerName '.' $methodName;
  117.         $cachedCheckAnnotation $this->appCache->getItem($cacheKey);
  118.         if ($cachedCheckAnnotation->isHit()) {
  119.             return $cachedCheckAnnotation->get() == 'yes';
  120.         }
  121.         $reflectionClass = new \ReflectionClass($controller);
  122.         $reflectionObject = new \ReflectionObject($controller);
  123.         $reflectionMethod $reflectionObject->getMethod($methodName);
  124.         $hasAnnotation false;
  125.         if (!is_null($reflectionClass) && !is_null($reflectionMethod)) {
  126.             $classAnnotation $this->reader
  127.                 ->getClassAnnotation($reflectionClass$nameAnnotation);
  128.             $methodAnnotation $this->reader
  129.                 ->getMethodAnnotation($reflectionMethod$nameAnnotation);
  130.             if ($classAnnotation || $methodAnnotation) {
  131.                 $hasAnnotation true;
  132.             }
  133.         }
  134.         $cachedCheckAnnotation->set($hasAnnotation === true 'yes' 'no');
  135.         $this->appCache->save($cachedCheckAnnotation);
  136.         return $hasAnnotation;
  137.     }
  138.     public function saveLog($code$content$methodName null$force false)
  139.     {
  140.         if ($this->logging || $force) {
  141.             $this->logging false;
  142.             $request $this->requestStack->getCurrentRequest();
  143.             $log = new Log();
  144.             $log->setIp($request->getClientIp());
  145.             $log->setMethod($request->getMethod());
  146.             $methodName $this->methodName $methodName $methodName;
  147.             if ($methodName) {
  148.                 $log->setPermission($this->permissionRepo->findOneBy(['action' => $methodName]));
  149.             }
  150.             if (!is_null($this->getUser())) {
  151.                 $log->setUserId($this->getUser()->getId());
  152.             }
  153.             $allInputs $this->stripRequest($request);
  154.             $log->setRequest($allInputs);
  155.             $log->setUrl($request->getRequestUri());
  156.             $log->setResult($code);
  157.             if ($this->exception) {
  158.                 $log->setResult($this->exceptionCode);
  159.                 $log->setException($this->exception->getLine() . " of " $this->exception->getFile() . ' ' $this->exception->getTraceAsString());
  160.             } else {
  161.                 $log->setResult($code);
  162.             }
  163.             $response json_decode($content1);
  164.             if (is_string($response)) {
  165.                 $response = [$response];
  166.             }
  167.             $log->setResponse($response1);
  168.             $log->setSize(memory_get_usage() / 1000);
  169.             $log->setResponseTime((microtime(true) - $_SERVER['REQUEST_TIME_FLOAT']) * 1000);
  170.             $logRepo $this->logRepo;
  171.             $userAgentHeader $request->headers->get('user-agent');
  172.             $callback = function () use ($logRepo$log$userAgentHeader) {
  173.                 if ($userAgentHeader) {
  174.                     $log->setUserAgent($this->getUserAgent($userAgentHeader));
  175.                 }
  176.                 $logRepo->save($logtrue);
  177.             };
  178.             $logRepo->getEntityManager()->transactional($callback);
  179.         }
  180.     }
  181.     public function stripRequest($request)
  182.     {
  183.         $allInputs $request->request->all() + $request->query->all();
  184.         if (count($allInputs) > 0) {
  185.             if (isset($allInputs['result']['websiteLogo'])) {
  186.                 unset($allInputs['result']['websiteLogo']);
  187.             }
  188.             if (isset($allInputs['result']['websiteBanner'])) {
  189.                 unset($allInputs['result']['websiteBanner']);
  190.             }
  191.             if (isset($allInputs['result']['facebookLogo'])) {
  192.                 unset($allInputs['result']['facebookLogo']);
  193.             }
  194.             if (isset($allInputs['result']['facebookBanner'])) {
  195.                 unset($allInputs['result']['facebookBanner']);
  196.             }
  197.         }
  198.         return $allInputs;
  199.     }
  200.     public function archiveDeletedEntities()
  201.     {
  202.         foreach ($this->deletedEntities as $entity) {
  203.             $this->archiveService->add($entitynullnullnulltrue);
  204.         }
  205.         $this->getEntityManager()->flush();
  206.     }
  207.     public function getTimezone($controller)
  208.     {
  209.         $request $this->requestStack->getCurrentRequest();
  210.         $session $this->requestStack->getSession();
  211.         if ($request->headers->has('X-Ozone-Spot')) {
  212.             $this->timezone $request->headers->get('X-Ozone-Spot');
  213.             //$this->logger->error('found timezone in header', [$this->timezone]);
  214.         } else if ($session->has('X-Ozone-Spot')) {
  215.             $this->timezone $session->get('X-Ozone-Spot');
  216.             //$this->logger->error('found timezone in session', [$this->timezone]);
  217.         }
  218.         if (!$this->timezone) {
  219.             $this->timezone $this->params->get('fallback_timezone');
  220.             //$this->logger->error('use fall back timezone', [$this->timezone]);
  221.             $session->set('X-Ozone-Spot'$this->timezone);
  222.         }
  223.         //$this->logger->error('timezone', [$this->timezone]);
  224.         return $this->timezone;
  225.         //todo: set timezone on response
  226.     }
  227.     public function getUserAgent($name)
  228.     {
  229.         $userAgent $this->userAgentRepo->findOneBy(['name' => $name]);
  230.         if (!$userAgent) {
  231.             $userAgent $this->userAgentService->newEntity();
  232.             $userAgent->setName($name);
  233.             $this->userAgentRepo->save($userAgenttrue);
  234.         }
  235.         return $userAgent;
  236.     }
  237.     public function setLocale($methodName$controller)
  238.     {
  239.         $request $this->requestStack->getCurrentRequest();
  240.         if ($request->attributes->has('_locale')) {
  241.             $this->translatableListener->setTranslatableLocale($request->attributes->get('_locale'));
  242.         } else {
  243.             $this->translatableListener->setTranslatableLocale($request->headers->get('X-Language') ?? 'fr');
  244.         }
  245.     }
  246.     public function setTrackingCode()
  247.     {
  248.         if ($this->requestStack->getSession()->has('trackingCode')) return;
  249.         $request $this->requestStack->getCurrentRequest();
  250.         if ($request->query->has('utm_source')) {
  251.             $this->requestStack->getSession()->set('trackingCode'$request->query->get('utm_source'));
  252.         }
  253.     }
  254. }