src/Service/RequestService.php line 256

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