<?php
namespace App\Services\Common;
use App\Constants\ACL;
use App\Constants\UserExtension;
use App\Entity\AclSetting;
use App\Entity\Parameter;
use App\Entity\Univers;
use App\Entity\User;
use App\Model\AclSettingConfig;
use App\Model\Product;
use App\Services\Back\ParameterService;
use App\Services\Front\Catalogue\JsonCatalogueService;
use Doctrine\ORM\EntityManagerInterface;
use JsonException;
use League\Csv\Exception;
use Psr\Log\LoggerInterface;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
/**
* Service pour la gestion des ACL V2 coté Plateforme
*/
class AclServiceV2
{
private RouterInterface $router;
private TokenStorageInterface $tokenStorage;
private ParameterService $parameterService;
private EntityManagerInterface $em;
private ModuleSettingService $moduleSettingService;
private JsonCatalogueService $jsonCatalogueService;
private CommunityService $communityService;
private LoggerInterface $logger;
private array $aclRouteOptionsCache = [];
private array $aclItemCache = [];
private array $userIsGrantedCache = [];
private array $normalizedParamsCache = [];
private array $firstGrantedCatalogCache = [];
private ?array $defaultRoleAndJobCache = NULL;
public function __construct(RouterInterface $router, ParameterService $parameterService, TokenStorageInterface $tokenStorage, EntityManagerInterface $em, ModuleSettingService $moduleSettingService, JsonCatalogueService $jsonCatalogueService, CommunityService $communityService, LoggerInterface $logger)
{
$this->router = $router;
$this->parameterService = $parameterService;
$this->tokenStorage = $tokenStorage;
$this->em = $em;
$this->moduleSettingService = $moduleSettingService;
$this->jsonCatalogueService = $jsonCatalogueService;
$this->communityService = $communityService;
$this->logger = $logger;
}
/**
* @param $config
*
* @return false|mixed|string
*
* @throws JsonException
*/
public function getNormalizedAclSettingConfigParams($config)
{
$config = $config instanceof AclSettingConfig ? $config->toArray() : $config;
$params = $config['params'] ?? ACL::ACL_NO_PARAMS;
if(is_array($params))
{
if($config['route'] !== NULL)
{
$params = $this->getRouteParamsForAcl($config['route'], $params);
}
else
{
$params = $this->formatArrayParamsToString($params);
}
}
elseif(in_array($params, [NULL, ''], TRUE))
{
$params = ACL::ACL_NO_PARAMS;
}
return $params;
}
/**
* Retourne les params sous forme de string pour les ACL
*
* Supprime les params inutiles comme "_env"
* Supprime les params qui ne sont pas configurés pour être pris en compte dans la route
*
* @param string|null $routeName
* @param array|string|null $params
*
* @return string
*
*/
public function getRouteParamsForAcl(?string $routeName, array|string|null $params): string
{
$cacheKey = $routeName . '|' . (is_array($params) ? $this->formatArrayParamsToString($params) : (string)$params);
if(array_key_exists($cacheKey, $this->normalizedParamsCache))
{
return $this->normalizedParamsCache[$cacheKey];
}
// cette fonction doit être capable de normalizer les params qui sont en string ou en array
if(is_string($params))
{
try
{
$params = json_decode($params, TRUE, 512, JSON_THROW_ON_ERROR);
} catch(JsonException $e)
{
$this->logger->error($e->getMessage());
$params = [];
}
}
//unset de la clef _env présente en back_office
if(isset($params['_env']))
{
unset($params['_env']);
}
$paramsOptions = $this->getAclRouteOptions($routeName);
foreach($paramsOptions as $key => $value)
{
if(isset($params[$key]) && !$value)
{
unset($params[$key]);
}
}
return $this->normalizedParamsCache[$cacheKey] = $this->formatArrayParamsToString($params);
}
/**
* Retourne les informations de la clef acl dans les options de la route
*
* Certains params ne doivent pas être pris en compte pour la création des ACL (ex id d'une commande)
* Il faut ajouter dans les options de la route le tableau suivant
* acl :
* id : false <=== le params ID ne doit pas peser dans la règle des ACL
*
* @param string|null $routeName
*
* @return array|mixed|null
*/
public function getAclRouteOptions(?string $routeName): mixed
{
if($routeName === NULL)
{
return [];
}
if(array_key_exists($routeName, $this->aclRouteOptionsCache))
{
return $this->aclRouteOptionsCache[$routeName];
}
// Récupère les informations complètes de la route courante
$route = $this->router->getRouteCollection()->get($routeName);
if($route === NULL)
{
return $this->aclRouteOptionsCache[$routeName] = [];
}
return $this->aclRouteOptionsCache[$routeName] = ($route->getOption('acl') ?? []);
}
/**
* Normalise le json_encode des params pour la transformation array to string
*
* @param array|null $params
*
* @return string
*/
public function formatArrayParamsToString(?array $params): string
{
if($params === NULL) return ACL::ACL_NO_PARAMS;
try
{
return json_encode($params, JSON_THROW_ON_ERROR | JSON_UNESCAPED_UNICODE);
} catch(JsonException $e)
{
$this->logger->error($e->getMessage());
return ACL::ACL_NO_PARAMS;
}
}
/**
* Récupère l'environnement d'une route (front ou back) par le début du routename
*
* @param string $routeName
*
* @return string
*/
public function getEnvByRoute(string $routeName): string
{
if(str_contains($routeName, ACL::START_ROUTE_BACK))
{
return ACL::BACK_ENV;
}
return ACL::FRONT_ENV;
}
/**
* Remplit le fichier d'ACL avec les données lors du POST de la modale
*
* @param AclSettingConfig $config
* @param array $acl
*
* @return array
*/
public function setAllData(AclSettingConfig $config, array $acl = []): array
{
$acls = [];
foreach($acl as $role => $jobs)
{
$config->setRole($role);
foreach($jobs as $job => $value)
{
$config->setJob($job);
$acls[] = $this->setData($config, $value, FALSE);
}
}
// reset de la config si on en a besoin ultérieurement
$config->setRole(NULL)->setJob(NULL);
$this->em->flush();
return $acls;
}
/**
* Set 1 ligne d'acl uniquement
*
* @param AclSettingConfig $config
* @param bool $value
* @param bool $withFlush
*
* @return AclSetting|float|int|mixed|string|null
*/
public function setData(AclSettingConfig $config, bool $value, bool $withFlush = TRUE): mixed
{
// SI pas de role set, on met par défaut le ROLE_USER
// TODO voir si on retourne une erreur à la place
if($config->getRole() === NULL) $config->setRole('ROLE_USER');
// Si pas de job set, on met la constant ACL_NO_JOB
if($config->getJob() === NULL) $config->setRole(ACL::ACL_NO_JOB);
// vérifications des params en fonction de la configuration des routes
$params = $this->getRouteParamsForAcl($config->getRoute(), $config->getParams());
$config->setParams($params);
$registeredAcl = $this->em->getRepository(AclSetting::class)->getAclSettingsFor($config, TRUE);
if($registeredAcl === NULL)
{
$aclSetting = (new AclSetting())
->setFromAclSettingConfig($config)->setConcatKey($config->getConcatKey())
;
$this->em->persist($aclSetting);
}
else
{
$aclSetting = $registeredAcl;
}
$aclSetting->setValue($value);
if($withFlush) $this->em->flush();
$this->aclItemCache[$config->getConcatKey()] = $aclSetting;
$this->userIsGrantedCache = [];
return $aclSetting;
}
/**
* @param $config
*
* @return string
* @deprecated
*/
private function getConcatKey($config): string
{
$default = [
'env' => ACL::FRONT_ENV,
'route' => NULL,
'params' => ACL::ACL_NO_PARAMS,
'component' => ACL::ACL_NO_COMPONENT,
'slug' => ACL::ACL_NO_SLUG,
'action' => ACL::READ,
];
$config = array_merge($default, $config);
return $config['env'] . ACL::ACL_KEY_SEPARATOR . ($config['route'] ?? '') . ACL::ACL_KEY_SEPARATOR . $config['params'] . ACL::ACL_KEY_SEPARATOR . $config['component'] . ACL::ACL_KEY_SEPARATOR . $config['slug'] . ACL::ACL_KEY_SEPARATOR . $config['action'];
}
/**
* Retourne l'objet utilisé pour construire le tableau d'ACL dans la modale
*
* @param AclSettingConfig $config
*
* @return array
*/
public function getAclConfig(AclSettingConfig $config): array
{
// on garde la route d'origine en mémoire
$routeName = $config->getRoute();
if(NULL === $routeName) return [];
// on transforme les valeurs pour correspondre aux différents cas
$config = $this->transformAclVariables($config);
$aclItems = $this->getAclItems($config);
$tables = [];
foreach($aclItems as $role => $jobs)
{
$rows = [];
$rows[] = array_merge([$role], array_values($jobs));
$tables[$role] = [
'header' => [array_keys($jobs)],
'row' => $rows,
];
// Ajoute au début du tableau $jobs le $role
$rows = [array_merge([$role], array_values($jobs))];
$tables[$role] = [
'rows' => $rows,
'header' => array_keys($jobs),
];
}
$data = [
'method' => 'NaN',
'env' => $config->getEnv(),
'route' => $config->getRoute(),
'params' => $config->getParams(),
'component' => $config->getComponent(),
'slug' => $config->getSlug(),
'action' => $config->getAction(),
'tables' => $tables,
];
$route = $this->router->getRouteCollection()->get($routeName);
if($route !== NULL)
{
$defaults = $route->getDefaults();
// On remplace ':' par '::' pour pouvoir utiliser la reflection
$re = '/(.*\w):(\w.*)/m';
$subst = "$1::$2";
$defaults['_controller'] = preg_replace($re, $subst, $defaults['_controller']);
$method = explode('::', $defaults['_controller']);
if(method_exists($method[0], $method[1]))
{
$data['method'] = $defaults['_controller'];
}
}
$data['routeName'] = $routeName;
return $data;
}
/**
* Prépare les variables d'ACL en fonction de cas particulier
*
* - slug pas toujours obligatoire
* - les composants "commun" (header, footer) ne dépendent pas de la route
* - les catalogues ne dépendent pas des routes
*
* @param AclSettingConfig $config
*
* @return AclSettingConfig
*/
private function transformAclVariables(AclSettingConfig $config): AclSettingConfig
{
// le slug n'est pas toujours obligatoire
if(in_array($config->getSlug(), ['', NULL], TRUE))
{
$config->setSlug(ACL::ACL_NO_SLUG);
}
// les components dans la partie common ne sont pas dépendant de la page
if(str_starts_with($config->getComponent(), 'common.'))
{
$config->setRoute(ACL::ACL_ROUTE_FRONT_ALL);
$config->setParams(ACL::ACL_NO_PARAMS);
}
// même principe pour le header dans le back office
if($config->getEnv() === ACL::BACK_ENV && str_starts_with($config->getComponent(), 'header.'))
{
$config->setRoute(ACL::ACL_ROUTE_BACK_ALL);
$config->setParams(ACL::ACL_NO_PARAMS);
}
// on s'occupe d'un acl global de catalogue
if(str_starts_with($config->getSlug(), ACL::ACL_KEY_SLUG_SHOP_CATALOG))
{
$config->setRoute(ACL::ACL_ROUTE_SHOP_CONFIG);
$config->setParams(ACL::ACL_NO_PARAMS);
$config->setEnv(ACL::FRONT_ENV);
}
return $config;
}
/**
* Donne l'ACL correspondant à l'environnement, la route, au composant et à l'action demandés et retourne un
* tableau formaté pour l'affichage de la modale d'édition
*
* @param AclSettingConfig $config
*
* @return array
*/
private function getAclItems(AclSettingConfig $config): array
{
$currentUser = $this->tokenStorage->getToken() !== NULL ? $this->tokenStorage->getToken()->getUser() : NULL;
// on est obligé de transformer les clefs en premier en fonction des conditions
$config = $this->transformAclVariables($config);
$rolesAndJobs = $this->getDefaultRoleAndJob();
$acls = [];
foreach($rolesAndJobs as $role => $jobs)
{
$config->setRole($role);
foreach($jobs as $job => $value)
{
$config->setJob($job);
$acls[] = $this->getAclItemForRoleAndJob($config, TRUE, FALSE);
}
}
$formattedResult = [];
// Pour chaque acl, injecte dans $formattedResult les roles et jobs voulus
/** @var AclSetting $acl */
foreach($acls as $acl)
{
$formattedResult[$acl->getRole()][$acl->getJob()] = $acl->getValue();
}
// Si on est ROLE_ADMIN, on a accès au tableau pour les ROLE_USER
if($currentUser instanceof User && $currentUser->isAdmin())
{
unset($formattedResult['ROLE_SUPER_ADMIN'], $formattedResult['ROLE_DEVELOPER']);
}
// Si on est ROLE_SUPER_ADMIN, on a accès au tableau pour les ROLE_USER, et ROLE_ADMIN
if($currentUser instanceof User && $currentUser->isSuperAdmin())
{
unset($formattedResult['ROLE_DEVELOPER']);
}
return $formattedResult;
}
/**
* Retourne le tableau des roles et job en fonction de la configuration YAML
*
* Si un role n'a pas de job, le système des acls le considère avec le job ACL::ACL_NO_JOB
*
* @return array[]
*/
public function getDefaultRoleAndJob(bool $debug = FALSE): array
{
if($this->defaultRoleAndJobCache !== NULL)
{
return $this->defaultRoleAndJobCache;
}
$tree = $this->communityService->getTreeJobs();
$roles = [
'ROLE_USER' => array_merge(array_keys(array_filter($tree, static function($item)
{
return !isset($item['role']) || $item['role'] === 'ROLE_USER';
})), [ACL::ACL_NO_JOB]),
'ROLE_ADMIN' => array_merge(array_keys(array_filter($tree, static function($item)
{
return isset($item['role']) && $item['role'] === 'ROLE_ADMIN';
})), [ACL::ACL_NO_JOB]),
'ROLE_SUPER_ADMIN' => array_merge(array_keys(array_filter($tree, static function($item)
{
return isset($item['role']) && $item['role'] === 'ROLE_SUPER_ADMIN';
})), [ACL::ACL_NO_JOB]),
];
if(isset($roles['ROLE_DEVELOPER']))
{
unset($roles['ROLE_DEVELOPER']);
}
return $this->defaultRoleAndJobCache = array_map(static function($role)
{
// Si $role est vide, ajoute une clé 'ACL::ACL_NO_JOB'
if(count($role) === 0)
{
return [ACL::ACL_NO_JOB => TRUE];
}
return array_map(static function()
{
return TRUE;
},
array_flip($role));
}, $roles);
}
/**
* Retourne une règle d'ACL complète
*
* Retourne une règle existante ou en créé une nouvelle par rapport au contexte
* Force la valeur à FALSE pour la création d'une règle qui concerne le back + un ROLE_USER
*
* @param AclSettingConfig $config config complète contexte + ROLE + JOB
* @param bool $withFlush ajoute un flush dans la fonction pour enregistrer AclSetting
* @param bool $debug
*
* @return AclSetting|float|int|mixed|string|null
*/
public function getAclItemForRoleAndJob(AclSettingConfig $config, bool $withFlush = TRUE, bool $debug = FALSE): mixed
{
$cacheKey = $config->getConcatKey();
if(array_key_exists($cacheKey, $this->aclItemCache))
{
return $this->aclItemCache[$cacheKey];
}
$acl = $this->em->getRepository(AclSetting::class)->getAclSettingsFor($config, TRUE, TRUE);
// si les clefs n'existent pas, on les set pour chaque role/job
if($acl === NULL)
{
// Si la règle concerne le back pour un ROLE_USER, on set à FALSE par défaut
if($config->getEnv() === ACL::BACK_ENV && $config->getRole() === "ROLE_USER")
{
$defaultValue = FALSE;
}
else
{
$defaultValues = $this->getDefaultRoleAndJob();
try
{
$defaultValue = (bool)$defaultValues[$config->getRole()][$config->getJob()];
}
catch(\Exception $e)
{
$this->logger->error($e->getMessage());
$defaultValue = FALSE;
}
}
$acl = $this->setData($config, $defaultValue, $withFlush, $debug);
}
return $this->aclItemCache[$cacheKey] = $acl;
}
/**
* Vérifie si le user à le droit de voir le produit
*
* Vérifie les catalogues où est présent le produit et recherche les droits d'accès du user sur ces catalogues
* Retourne TRUE au premier qui match
*
* @param User|null $user
* @param Product $product
*
* @return bool
*
* @throws JsonException
*/
public function userIsGrantedProduct(?User $user, Product $product): bool
{
foreach($product->getCatalogues() as $catalogue)
{
//if ($this->userIsGrantedCatalogue($user, $catalogue) && $this->jsonCatalogueService->isProductInCatalogue($product->getSku(), $catalogue)) {
//TODO @Manu la vérification pour savoir si le produit est dans le catalogue est lourde, sans doute redondante si on a déjà récupéré le produit via le JSON pour obtenir la variable $product
if($this->userIsGrantedCatalogue($user, $catalogue)) return TRUE;
}
return FALSE;
}
/**
* Retourne si l'utilisateur peut voir ou non le catalogue via son slug, prend en compte les Univers si
* l'option est active
*
* @param User|null $user
* @param string $catalogueSlug
* @param bool $debug
*
* @return bool
*
* @throws JsonException
*/
public function userIsGrantedCatalogue(?User $user, string $catalogueSlug, bool $debug = FALSE): bool
{
$isGranted = $this->userIsGranted($user, [
'route' => ACL::ACL_ROUTE_SHOP_CONFIG,
'params' => ACL::ACL_NO_PARAMS,
'component' => ACL::ACL_NO_COMPONENT,
'slug' => ACL::ACL_KEY_SLUG_SHOP_CATALOG . '.' . $catalogueSlug,
'env' => ACL::FRONT_ENV,
]);
// en cas d'univers, il faut vérifier si on a le droit de voir quand on est ni dev, ni super admin
$universActive = $this->moduleSettingService->isModuleActive('univers');
if($universActive && $user !== NULL && !$user->isSuperAdmin() && !$user->isDeveloper())
{
$catalogueHasUnivers = $this->em->getRepository(Univers::class)->findUniversForUserAndCatalogSlug($user, $catalogueSlug);
$isGranted = $catalogueHasUnivers !== [];
}
return $isGranted;
}
/**
* Indique si un utilisateur a les droits d'accès de la page ou du composant avec son action
*
* Retourne TRUE si on est sur un component qui s'affiche coté security (non logué)
* Retourne TRUE si on est ROLE_DEVELOPER
* Retourne FALSE si la règle n'est pas trouvée ou qu'aucune règle n'est TRUE
* Retourne TRUE à la première règle dont la valeur est TRUE (si le user à plusieurs roles par exemple)
*
* @param User|null $user
* @param array $config
* @param bool $debug
*
* @return bool
* @throws JsonException
*/
public function userIsGranted(?User $user, array $config, bool $debug = FALSE): bool
{
$default = [
'route' => NULL,
'params' => ACL::ACL_NO_PARAMS,
'component' => ACL::ACL_NO_COMPONENT,
'slug' => ACL::ACL_NO_SLUG,
'action' => ACL::READ,
'env' => ACL::FRONT_ENV,
];
$config = array_merge($default, $config);
//Si c'est un component qui vient de la clef security alors on autorise
// @todo passer par l'array des routes concernée par la security ?
// security_path dans twig.yaml
if(str_contains($config['component'], 'security.') || in_array($config['route'], ACL::ACL_SECURITY_ROUTES, TRUE))
{
return TRUE;
}
// Utilisateur non connecté
if(!$user instanceof User) return FALSE;
// Aucune restriction pour le ROLE_DEVELOPER
if($user->isDeveloper()) return TRUE;
// cette étape normalise la variable params que ça soit une string ou un array.
$config['params'] = $this->getRouteParamsForAcl($config['route'], $config['params']);
$cacheKey = implode('|', [
$user->getId() ?? 'anon',
$user->getJob() ?? ACL::ACL_NO_JOB,
implode(',', $user->getRoles()),
$config['env'],
$config['route'] ?? '',
$config['params'],
$config['component'],
$config['slug'],
$config['action'],
]);
if(array_key_exists($cacheKey, $this->userIsGrantedCache))
{
return $this->userIsGrantedCache[$cacheKey];
}
$isGranted = FALSE;
$job = $user->getJob() ?? ACL::ACL_NO_JOB;
$baseAclConfig = (new AclSettingConfig())->setFromArray($config)->setJob($job);
$baseAclConfig = $this->transformAclVariables($baseAclConfig);
foreach($user->getRoles() as $role)
{
$aclConfig = (clone $baseAclConfig)->setRole($role);
$aclItem = $this->getAclItemForRoleAndJob($aclConfig, TRUE, $debug);
$isGranted = $aclItem->getValue();
if($isGranted) break;
}
return $this->userIsGrantedCache[$cacheKey] = $isGranted;
}
/**
* Retourne le slug du premier catalogue où le user a les accès ACL
*
* @param User|null $user
* @param Product $product
*
* @return mixed|null
* @throws JsonException
*/
public function getUserFirstGrantedCatalogSlugForProduct(?User $user, Product $product): mixed
{
$cacheKey = ($user?->getId() ?? 'anonymous') . '|' . $product->getSku();
if (array_key_exists($cacheKey, $this->firstGrantedCatalogCache)) {
return $this->firstGrantedCatalogCache[$cacheKey];
}
foreach($product->getCatalogues() as $catalogue)
{
//TODO @manu la vérification pour savoir si le produit est dans le catalogue est lourde, sans doute redondante si on a déjà récupéré le produit via le JSON pour obtenir la variable $product
if($this->userIsGrantedCatalogue($user, $catalogue) /*&& $this->jsonCatalogueService->isProductInCatalogue($product->getSku(), $catalogue)*/)
{
return $this->firstGrantedCatalogCache[$cacheKey] = $catalogue;
}
}
return $this->firstGrantedCatalogCache[$cacheKey] = NULL;
}
/**
* Indique si un user a les droits d'accès au document
*
* Les ACL du document se font lors de la création de l'entité
* Choix des roles => si pas de choix tout le monde voit
* Choix des jobs => si pas de choix tout le monde voit
* Choix des univers => si pas de choix tout le monde voit
*
* @param User|null $user
* @param Parameter $document
*
* @return bool
*
* @throws JsonException
* @throws Exception
*/
public function userIsGrantedOnDocument(?User $user, Parameter $document): bool
{
if($user === NULL)
{
return TRUE;
}
$isGranted = TRUE;
//Check sur job
if($document->getDisplayJob() !== NULL && !in_array($user->getJob(), $document->getDisplayJob(), TRUE))
{
return FALSE;
}
//Check sur le role
if($document->getDisplayRole() !== NULL && array_diff($user->getRoles(), $document->getDisplayRole()) !== [])
{
return FALSE;
}
$universes = $document->getDisplayUniverses();
// Si config par univers on regarde si ça match
if($universes !== NULL)
{
$isGranted = FALSE;
foreach($user->getUniverses() as $userUnivers)
{
if(in_array($userUnivers->getSlug(), $universes, TRUE))
{
$isGranted = TRUE;
break;
}
}
if(!$isGranted) return FALSE;
}
// Check si la selection des documents est activé sur des parents dont il dépend et qui ont une extension
if($user->getParents()->getValues() !== [])
{
$isGranted = $this->parameterService->isDocumentSelectedByUserParents($user, $document->getId());
}
// sur le user lui-même si une extension existe
$currentUserDocumentSelected = $user->getExtensionBySlug(UserExtension::DOCUMENT_SELECTION);
if($currentUserDocumentSelected !== NULL)
{
$isGranted = $this->parameterService->isDocumentSelectedForUser($user, $document->getId());
}
return $isGranted;
}
/**
* Définit si un element d'un formType est visible en fonction de ses droits configurés dans le yaml
*
* @param AclSettingConfig|null $aclConfig
* @param array $config
* @param bool $debug
*
* @return bool
* @throws JsonException
*/
public function currentUserIsGrantedByConfigFormType(?AclSettingConfig $aclConfig, array $config = [], bool $debug = FALSE): bool
{
// Pas de config, tout le monde voit
if($aclConfig === NULL && !array_key_exists('jobs', $config) && !array_key_exists('roles', $config) && !array_key_exists('univers', $config))
{
return TRUE;
}
$tokenStorage = $this->tokenStorage->getToken();
$currentUser = $tokenStorage ? $tokenStorage->getUser() : NULL;
if(!$currentUser instanceof User) return FALSE;
if($currentUser->isDeveloper() || $currentUser->isSuperAdmin()) return TRUE;
if(array_key_exists('jobs', $config) && $config['jobs'] !== null)
{
return $this->canDisplayByJobs($currentUser, $config['jobs']);
}
if(array_key_exists('roles', $config) && $config['roles'] !== null)
{
return $this->canDisplayByRoles($currentUser, $config['roles']);
}
$universesConfig = isset($config['univers']) && count($config['univers']) > 0;
// cas 2 $aclConfig + config => on ne garde que les univers pour le moment, $aclConfig prend le dessus.
$isGranted = !$aclConfig || $this->userIsGranted($currentUser, $aclConfig->toArray(), $debug);
if($isGranted && $universesConfig)
{
return $this->canDisplayByUniverses($currentUser, $config['univers']);
}
return $isGranted;
}
/**
* Vérifie si on peut afficher un élément en fonction du roles
*
* @param User $user
* @param array $roles
*
* @return bool
*/
public function canDisplayByRoles(User $user, array $roles): bool
{
$userRole = $user->getRoles();
if(array_diff($userRole, $roles) === []) return TRUE;
return FALSE;
}
/**
* Vérifie si on peut afficher un élément en fonction du jobs
*
* @param User $user
* @param array $jobs
*
* @return bool
*/
public function canDisplayByJobs(User $user, array $jobs): bool
{
$userJob = $user->getJob();
if(in_array($userJob, $jobs)) return TRUE;
return FALSE;
}
/**
* Vérifie si on peut afficher un élément en fonction des univers de l'utilisateur
*
* @param User $user
* @param array $universes
*
* @return bool
*/
public function canDisplayByUniverses(User $user, array $universes): bool
{
$userUniverses = $user->getUniverses();
foreach($userUniverses as $univers)
{
if(in_array($univers->getSlug(), $universes, TRUE))
{
return TRUE;
}
}
return FALSE;
}
}