src/Security/IndividualVoter.php line 92

Open in your IDE?
  1. <?php
  2. //------------------------------------------------------------------------------
  3. // src/Security/IndividualVoter.php
  4. //------------------------------------------------------------------------------
  5. namespace App\Security;
  6. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  7. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  8. use Doctrine\Persistence\ManagerRegistry;
  9. use App\Entity\Access;
  10. use App\Entity\Client\Individual;
  11. use App\Entity\Config\Config;
  12. use App\Entity\Config\Module;
  13. use App\Entity\HR\AccessFunction;
  14. use App\Entity\Planning\Task;
  15. use App\Entity\Security\Acl;
  16. use App\Entity\Security\AclPermission;
  17. use App\Services\Config\ModuleTools;
  18. class IndividualVoter extends Voter
  19. {
  20.     //--------------------------------------------------------------------------------
  21.     // is_granted constants
  22.     const ADD "add_individual";
  23.     const LISTING "list_individuals";
  24.     const LISTING_SOCIETY "list_individuals_society";
  25.     const LISTING_MANAGER "list_individuals_manager";
  26.     const LISTING_ANY "list_individuals_any";
  27.     const VIEW "view_individual";
  28.     const EDIT "edit_individual";
  29.     const ANONYMIZE "anonymize_individual";
  30.     const EDIT_SOCIETY "edit_individual_society";
  31.     const IMPORT "import_individuals";
  32.     // Plan.Io Task #3747
  33.     const MERGE "merge_individual";
  34.     const MERGE_TOOL "merge_tool_individual";
  35.     const IS_GRANTED_CONSTANTS = array(
  36.         self::ADD,
  37.         self::LISTING,
  38.         self::LISTING_SOCIETY,
  39.         self::LISTING_MANAGER,
  40.         self::LISTING_ANY,
  41.         self::VIEW,
  42.         self::EDIT,
  43.         self::ANONYMIZE,
  44.         self::EDIT_SOCIETY,
  45.         self::IMPORT,
  46.         self::MERGE,
  47.         self::MERGE_TOOL,
  48.     );
  49.     //--------------------------------------------------------------------------------
  50.     // acl constants
  51.     const ACL_PERM_ADD "ind_add";
  52.     const ACL_PERM_LISTING "ind_list";
  53.     const ACL_PERM_LISTING_SOCIETY "ind_list_society";
  54.     const ACL_PERM_LISTING_MANAGER "ind_list_manager";
  55.     const ACL_PERM_VIEW "ind_view";
  56.     const ACL_PERM_VIEW_SOCIETY "ind_view_society";
  57.     const ACL_PERM_VIEW_MANAGER "ind_view_manager";
  58.     const ACL_PERM_VIEW_IF_TASK "ind_view_if_task";
  59.     const ACL_PERM_EDIT "ind_edit";
  60.     const ACL_PERM_EDIT_SOCIETY "ind_edit_society";
  61.     const ACL_PERM_EDIT_MANAGER "ind_edit_manager";
  62.     const ACL_PERM_ANONYMIZE "ind_anonymize";
  63.     const ACL_PERM_ANONYMIZE_SOCIETY "ind_anonymize_society";
  64.     const ACL_PERM_ANONYMIZE_MANAGER "ind_anonymize_manager";
  65.     const ACL_PERM_SOCIETY_EDIT "ind_society_edit";
  66.     const ACL_PERM_SOCIETY_EDIT_SOCIETY "ind_society_edit_society";
  67.     const ACL_PERM_SOCIETY_EDIT_MANAGER "ind_society_edit_manager";
  68.     const ACL_PERM_IMPORT "ind_import";
  69.     // Plan.io Task #3747
  70.     const ACL_PERM_MERGE "ind_merge";
  71.     const ACL_PERM_MERGE_SOCIETY "ind_merge_society";
  72.     //--------------------------------------------------------------------------------
  73.     public function __construct(ManagerRegistry $doctrineModuleTools $moduleTools)
  74.     {
  75.         $this->em $doctrine->getManager();
  76.         $this->moduleTools $moduleTools;
  77.         $this->aclRepository $this->em->getRepository(Acl::class);
  78.         $this->aclPermissionRepository $this->em->getRepository(AclPermission::class);
  79.     }
  80.     // Plan.io Task #4453 [See AccessVoter for details]
  81.     public function supportsAttribute(string $attribute): bool
  82.     {
  83.         return in_array($attributeself::IS_GRANTED_CONSTANTStrue);
  84.     }
  85.     
  86.     protected function supports(string $attribute$subject): bool
  87.     {
  88.         // if the attribute isn't one we support, return false
  89.         if (!in_array($attributeself::IS_GRANTED_CONSTANTS))
  90.         {
  91.             return false;
  92.         }
  93.         // only vote on Individual objects inside this voter
  94.         if ($subject !== null && !$subject instanceof Individual)
  95.         {
  96.             return false;
  97.         }
  98.         return true;
  99.     }
  100.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  101.     {
  102.         $user $token->getUser();
  103.         if (!$user instanceof Access)
  104.         {
  105.             // the user must be logged in; if not, deny access
  106.             return false;
  107.         }
  108.         // The user must have a function; if not deny access
  109.         $function $user->getFunction();
  110.         if ($function === null)        return false;
  111.         // Plan.io Task #3710 : Get current group
  112.         $currentGroup $user->getSocietyGroup();
  113.         if ($currentGroup === null)
  114.             return false;
  115.         $this->currentGroup $currentGroup;
  116.         // Module activated ?
  117.         if ($this->moduleTools->isInactiveByCode($currentGroupModule::MODULE_CLIENT) && $this->moduleTools->isInactiveByCode($currentGroupModule::MODULE_CLIENT_LIGHT))
  118.         {
  119.             return false;
  120.         }
  121.         if ($attribute == self::EDIT || $attribute == self::EDIT_SOCIETY)
  122.         {
  123.             if ($subject->getAnonymized())
  124.             {
  125.                 return false;
  126.             }
  127.         }
  128.         // you know $subject is a Individual object, thanks to supports
  129.         /** @var Individual $individual */
  130.         $individual $subject;
  131.         // Check current group affectation
  132.         if ($individual !== null)
  133.         {
  134.             $individualSociety $individual->getSociety();
  135.             if ($individualSociety === null)
  136.                 return false;
  137.             $individualSocietyGroup $individualSociety->getGroup();
  138.             if ($individualSocietyGroup === null)
  139.                 return false;
  140.             // Checking ...
  141.             // Do not allow viewing/editing the client of a shared mission
  142.             if (!$currentGroup->equals($individualSocietyGroup))
  143.             {
  144.                 return false;
  145.             }
  146.         }
  147.         switch ($attribute)
  148.         {
  149.             case self::ADD:
  150.                 return $this->canAdd($user$function);
  151.             case self::LISTING:
  152.                 return $this->canList($individual$user$function);
  153.             case self::LISTING_SOCIETY:
  154.                 return $this->canListSociety($individual$user$function);
  155.             case self::LISTING_MANAGER:
  156.                 return $this->canListManager($individual$user$function);
  157.             case self::LISTING_ANY:
  158.                 return $this->canListAny($individual$user$function);
  159.             case self::VIEW:
  160.                 return $this->canView($individual$user$function);
  161.             case self::EDIT:
  162.                 return $this->canEdit($individual$user$function);
  163.             case self::ANONYMIZE:
  164.                 return $this->canAnonymize($individual$user$function);
  165.             case self::EDIT_SOCIETY:
  166.                 return $this->canEditSociety($individual$user$function);
  167.             case self::IMPORT:
  168.                 return $this->canImport($user$function);
  169.             case self::MERGE:
  170.                 return $this->canMerge($individual$user$function);
  171.             case self::MERGE_TOOL:
  172.                 return $this->canUseMergeTool($user$function);
  173.         }
  174.         throw new \LogicException('This code should not be reached!');
  175.     }
  176.     // $access is the user trying to load the resource
  177.     // $individual is the resource being loaded
  178.     // Check if the Society of the resource
  179.     // belongs to the societies of the $access
  180.     private function checkSociety(Individual $individualAccess $access)
  181.     {
  182.         // Get all the societies of the access
  183.         $societies $access->getSocieties();
  184.         // Get the Society of the Individual
  185.         $individualSociety $individual->getSociety();
  186.         if ($individualSociety === null)
  187.             return false;
  188.         $found false;
  189.         foreach ($societies as $society)
  190.         {
  191.             if ($society->getId() == $individualSociety->getId())
  192.             {
  193.                 $found true;
  194.                 break;
  195.             }
  196.         }
  197.         return $found;
  198.     }
  199.     // Check if the $access is the manager / author of the $individual
  200.     private function checkManager(Individual $individualAccess $access)
  201.     {
  202.         // Get manager and author
  203.         $manager $individual->getManager();
  204.         $author $individual->getAuthor();
  205.         if ($manager === null && $author === null)
  206.             return false;
  207.         if ($manager !== null)
  208.             if ($manager->getId() === $access->getId())
  209.                 return true;
  210.         if ($author !== null)
  211.             if ($author->getId() === $access->getId())
  212.                 return true;
  213.         return false;
  214.     }
  215.     // Check if there is at least one task
  216.     // having this access as resource and this individual as client
  217.     private function checkTask(Individual $individualAccess $access)
  218.     {
  219.         $taskRep $this->em->getRepository(Task::class);
  220.         $resources $access->getPlanningResources();
  221.         $client $individual->getClient();
  222.         if ($client === null)
  223.             return false;
  224.         foreach ($resources as $r)
  225.         {
  226.             $tasks $taskRep->findForClientAndResource($client$r);
  227.             if (count($tasks) > 0)
  228.                 return true;
  229.         }
  230.         return false;
  231.     }
  232.     private function canAdd(Access $userAccessFunction $function)
  233.     {
  234.         // Module activated ?
  235.         // CLIENT_LIGHT cannot add Clients / Stores
  236.         if ($this->moduleTools->isInactiveByCode($this->currentGroupModule::MODULE_CLIENT))
  237.         {
  238.             return false;
  239.         }
  240.         // Get Acl_Permission
  241.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ADD);
  242.         if ($aclPerm === null)        return false;
  243.         // Get Acl
  244.         $acl $this->aclRepository->findOneBy(array(
  245.             'function'        =>    $function,
  246.             'permission'    =>    $aclPerm
  247.         ));
  248.         if ($acl === null)        return false;
  249.         // Since only one acl type can exist
  250.         // we can return the result of the acl_permission
  251.         return $acl->getValue();
  252.     }
  253.     private function canList(Individual $individual nullAccess $userAccessFunction $function)
  254.     {
  255.         // Get Acl_Permission
  256.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING);
  257.         if ($aclPerm === null)        return false;
  258.         // Get Acl
  259.         $acl $this->aclRepository->findOneBy(array(
  260.             'function'        =>    $function,
  261.             'permission'    =>    $aclPerm
  262.         ));
  263.         if ($acl === null)        return false;
  264.         // Since only one acl type can exist
  265.         // we can return the result of the acl_permission
  266.         return $acl->getValue();
  267.     }
  268.     private function canListSociety(Individual $individual nullAccess $userAccessFunction $function)
  269.     {
  270.         // Get Acl_Permission
  271.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_SOCIETY);
  272.         if ($aclPerm === null)        return false;
  273.         // Get Acl
  274.         $acl $this->aclRepository->findOneBy(array(
  275.             'function'        =>    $function,
  276.             'permission'    =>    $aclPerm
  277.         ));
  278.         if ($acl === null)        return false;
  279.         // Since only one acl type can exist
  280.         // we can return the result of the acl_permission
  281.         // Further filtering is done in the Controller
  282.         return $acl->getValue();
  283.     }
  284.     private function canListManager(Individual $individual nullAccess $userAccessFunction $function)
  285.     {
  286.         // Get Acl_Permission
  287.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_MANAGER);
  288.         if ($aclPerm === null)        return false;
  289.         // Get Acl
  290.         $acl $this->aclRepository->findOneBy(array(
  291.             'function'        =>    $function,
  292.             'permission'    =>    $aclPerm
  293.         ));
  294.         if ($acl === null)        return false;
  295.         // Since only one acl type can exist
  296.         // we can return the result of the acl_permission
  297.         // Further filtering is done in the Controller
  298.         return $acl->getValue();
  299.     }
  300.     private function canListAny(Individual $individual nullAccess $userAccessFunction $function)
  301.     {
  302.         // Two Acl_Permission may exist
  303.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING);
  304.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_SOCIETY);
  305.         $aclPermManager $this->aclPermissionRepository->findOneByName(self::ACL_PERM_LISTING_MANAGER);
  306.         // If both are null, exit
  307.         if ($aclPerm === null && $aclPermSociety === null && $aclPermManager === null)
  308.             return false;
  309.         // Get First one
  310.         if ($aclPerm !== null)
  311.         {
  312.             $acl $this->aclRepository->findOneBy(array(
  313.                 'function'        =>    $function,
  314.                 'permission'    =>    $aclPerm
  315.             ));
  316.             if ($acl !== null)
  317.             {
  318.                 if ($acl->getValue())
  319.                 {
  320.                     // A single positive answer is enough
  321.                     return true;
  322.                 }
  323.             }
  324.         }
  325.         // If we are here it means that nothing good has been found
  326.         // Load second permission
  327.         if ($aclPermSociety !== null)
  328.         {
  329.             $acl $this->aclRepository->findOneBy(array(
  330.                 'function'        =>    $function,
  331.                 'permission'    =>    $aclPermSociety
  332.             ));
  333.             if ($acl !== null)
  334.             {
  335.                 if ($acl->getValue())
  336.                 {
  337.                     // A single positive answer is enough
  338.                     return true;
  339.                 }
  340.             }
  341.         }
  342.         // If we are here it means that nothing good has been found
  343.         // Load third permission
  344.         if ($aclPermManager !== null)
  345.         {
  346.             $acl $this->aclRepository->findOneBy(array(
  347.                 'function'        =>    $function,
  348.                 'permission'    =>    $aclPermManager
  349.             ));
  350.             if ($acl !== null)
  351.             {
  352.                 if ($acl->getValue())
  353.                 {
  354.                     // A single positive answer is enough
  355.                     return true;
  356.                 }
  357.             }
  358.         }
  359.         // If we are here, all hope is lost
  360.         return false;
  361.     }
  362.     private function canView(Individual $individual nullAccess $userAccessFunction $function)
  363.     {
  364.         // Get Acl_Permissions
  365.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW);
  366.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW_SOCIETY);
  367.         $aclPermManager $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW_MANAGER);
  368.         $aclPermIfTask $this->aclPermissionRepository->findOneByName(self::ACL_PERM_VIEW_IF_TASK);
  369.         // If all are null, exit
  370.         if ($aclPerm === null && $aclPermSociety === null && $aclPermManager === null && $aclPermIfTask === null)
  371.             return false;
  372.         // The aclPermIfTask should be checked first, and if it is false, the others should be cheked
  373.         // ($aclPerm ^ $aclPermSociety ^ $aclPermManager) = empty
  374.         // ($aclPerm ^ $aclPermSociety ^ $aclPermManager) ^ $aclPermIfTask = not empty
  375.         // This means that an user can have access to the clients of his society
  376.         // and also have access to the individuals realted to his tasks
  377.         if ($aclPermIfTask !== null)
  378.         {
  379.             $acl $this->aclRepository->findOneBy(array(
  380.                 'function'        =>    $function,
  381.                 'permission'    =>    $aclPermIfTask
  382.             ));
  383.             if ($acl !== null)
  384.             {
  385.                 if ($acl->getValue())
  386.                 {
  387.                     if ($this->checkTask($individual$user))
  388.                         return true;
  389.                 }
  390.             }
  391.         }
  392.         // If we are here it means that the user doesn't have access to the Individual
  393.         // by the bias of one of his tasks
  394.         // So check regular permissions next
  395.         // Get First one
  396.         if ($aclPerm !== null)
  397.         {
  398.             $acl $this->aclRepository->findOneBy(array(
  399.                 'function'        =>    $function,
  400.                 'permission'    =>    $aclPerm
  401.             ));
  402.             if ($acl !== null)
  403.             {
  404.                 if ($acl->getValue())
  405.                 {
  406.                     // A single positive answer is enough
  407.                     return true;
  408.                 }
  409.             }
  410.         }
  411.         // If we are here it means that nothing good has been found
  412.         // Load second permission
  413.         if ($aclPermSociety !== null)
  414.         {
  415.             $acl $this->aclRepository->findOneBy(array(
  416.                 'function'        =>    $function,
  417.                 'permission'    =>    $aclPermSociety
  418.             ));
  419.             if ($acl !== null)
  420.             {
  421.                 if ($acl->getValue())
  422.                 {
  423.                     // A single positive answer is enough
  424.                     // In this case the good answer will be provided by the checkSociety
  425.                     return $this->checkSociety($individual$user);
  426.                 }
  427.             }
  428.         }
  429.         // If we are here it means that nothing good has been found
  430.         // Load third permission
  431.         if ($aclPermManager !== null)
  432.         {
  433.             $acl $this->aclRepository->findOneBy(array(
  434.                 'function'        =>    $function,
  435.                 'permission'    =>    $aclPermManager
  436.             ));
  437.             if ($acl !== null)
  438.             {
  439.                 if ($acl->getValue())
  440.                 {
  441.                     // A single positive answer is enough
  442.                     // In this case the good answer will be provided by the checkSociety
  443.                     return $this->checkManager($individual$user);
  444.                 }
  445.             }
  446.         }
  447.         // If we are here, all hope is lost
  448.         return false;
  449.     }
  450.     private function canEdit(Individual $individual nullAccess $userAccessFunction $function)
  451.     {
  452.         if($individual->getAnonymized())
  453.         {
  454.             return false;
  455.         }
  456.         // Two Acl_Permission may exist
  457.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_EDIT);
  458.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_EDIT_SOCIETY);
  459.         $aclPermManager $this->aclPermissionRepository->findOneByName(self::ACL_PERM_EDIT_MANAGER);
  460.         // If all are null, exit
  461.         if ($aclPerm === null && $aclPermSociety === null && $aclPermManager === null)
  462.             return false;
  463.         // Get First one
  464.         if ($aclPerm !== null)
  465.         {
  466.             $acl $this->aclRepository->findOneBy(array(
  467.                 'function'        =>    $function,
  468.                 'permission'    =>    $aclPerm
  469.             ));
  470.             if ($acl !== null)
  471.             {
  472.                 if ($acl->getValue())
  473.                 {
  474.                     // A single positive answer is enough
  475.                     return true;
  476.                 }
  477.             }
  478.         }
  479.         // If we are here it means that nothing good has been found
  480.         // Load second permission
  481.         if ($aclPermSociety !== null)
  482.         {
  483.             $acl $this->aclRepository->findOneBy(array(
  484.                 'function'        =>    $function,
  485.                 'permission'    =>    $aclPermSociety
  486.             ));
  487.             if ($acl !== null)
  488.             {
  489.                 if ($acl->getValue())
  490.                 {
  491.                     // A single positive answer is enough
  492.                     // In this case the good answer will be provided by the checkSociety
  493.                     return $this->checkSociety($individual$user);
  494.                 }
  495.             }
  496.         }
  497.         // If we are here it means that nothing good has been found
  498.         // Load third permission
  499.         if ($aclPermManager !== null)
  500.         {
  501.             $acl $this->aclRepository->findOneBy(array(
  502.                 'function'        =>    $function,
  503.                 'permission'    =>    $aclPermManager
  504.             ));
  505.             if ($acl !== null)
  506.             {
  507.                 if ($acl->getValue())
  508.                 {
  509.                     // A single positive answer is enough
  510.                     // In this case the good answer will be provided by the checkSociety
  511.                     return $this->checkManager($individual$user);
  512.                 }
  513.             }
  514.         }
  515.         // If we are here, all hope is lost
  516.         return false;
  517.     }
  518.     private function canAnonymize(Individual $individual nullAccess $userAccessFunction $function)
  519.     {
  520.         // Three Acl_Permission may exist
  521.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ANONYMIZE);
  522.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ANONYMIZE_SOCIETY);
  523.         $aclPermManager $this->aclPermissionRepository->findOneByName(self::ACL_PERM_ANONYMIZE_MANAGER);
  524.         // If all are null, exit
  525.         if ($aclPerm === null && $aclPermSociety === null && $aclPermManager === null)
  526.             return false;
  527.         // Get First one
  528.         if ($aclPerm !== null)
  529.         {
  530.             $acl $this->aclRepository->findOneBy(array(
  531.                 'function'        =>    $function,
  532.                 'permission'    =>    $aclPerm
  533.             ));
  534.             if ($acl !== null)
  535.             {
  536.                 if ($acl->getValue())
  537.                 {
  538.                     // A single positive answer is enough
  539.                     return true;
  540.                 }
  541.             }
  542.         }
  543.         // If we are here it means that nothing good has been found
  544.         // Load second permission
  545.         if ($aclPermSociety !== null)
  546.         {
  547.             $acl $this->aclRepository->findOneBy(array(
  548.                 'function'        =>    $function,
  549.                 'permission'    =>    $aclPermSociety
  550.             ));
  551.             if ($acl !== null)
  552.             {
  553.                 if ($acl->getValue())
  554.                 {
  555.                     // A single positive answer is enough
  556.                     // In this case the good answer will be provided by the checkSociety
  557.                     return $this->checkSociety($individual$user);
  558.                 }
  559.             }
  560.         }
  561.         // If we are here it means that nothing good has been found
  562.         // Load third permission
  563.         if ($aclPermManager !== null)
  564.         {
  565.             $acl $this->aclRepository->findOneBy(array(
  566.                 'function'        =>    $function,
  567.                 'permission'    =>    $aclPermManager
  568.             ));
  569.             if ($acl !== null)
  570.             {
  571.                 if ($acl->getValue())
  572.                 {
  573.                     // A single positive answer is enough
  574.                     // In this case the good answer will be provided by the checkSociety
  575.                     return $this->checkManager($individual$user);
  576.                 }
  577.             }
  578.         }
  579.         // If we are here, all hope is lost
  580.         return false;
  581.     }
  582.     private function canEditSociety(Individual $individual nullAccess $userAccessFunction $function)
  583.     {
  584.         if($individual->getAnonymized())
  585.         {
  586.             return false;
  587.         }
  588.         // Two Acl_Permission may exist
  589.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_SOCIETY_EDIT);
  590.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_SOCIETY_EDIT_SOCIETY);
  591.         $aclPermManager $this->aclPermissionRepository->findOneByName(self::ACL_PERM_SOCIETY_EDIT_MANAGER);
  592.         // If all are null, exit
  593.         if ($aclPerm === null && $aclPermSociety === null && $aclPermManager === null)
  594.             return false;
  595.         // Get First one
  596.         if ($aclPerm !== null)
  597.         {
  598.             $acl $this->aclRepository->findOneBy(array(
  599.                 'function'        =>    $function,
  600.                 'permission'    =>    $aclPerm
  601.             ));
  602.             if ($acl !== null)
  603.             {
  604.                 if ($acl->getValue())
  605.                 {
  606.                     // A single positive answer is enough
  607.                     return true;
  608.                 }
  609.             }
  610.         }
  611.         // If we are here it means that nothing good has been found
  612.         // Load second permission
  613.         if ($aclPermSociety !== null)
  614.         {
  615.             $acl $this->aclRepository->findOneBy(array(
  616.                 'function'        =>    $function,
  617.                 'permission'    =>    $aclPermSociety
  618.             ));
  619.             if ($acl !== null)
  620.             {
  621.                 if ($acl->getValue())
  622.                 {
  623.                     // A single positive answer is enough
  624.                     // In this case the good answer will be provided by the checkSociety
  625.                     return $this->checkSociety($individual$user);
  626.                 }
  627.             }
  628.         }
  629.         // If we are here it means that nothing good has been found
  630.         // Load third permission
  631.         if ($aclPermManager !== null)
  632.         {
  633.             $acl $this->aclRepository->findOneBy(array(
  634.                 'function'        =>    $function,
  635.                 'permission'    =>    $aclPermManager
  636.             ));
  637.             if ($acl !== null)
  638.             {
  639.                 if ($acl->getValue())
  640.                 {
  641.                     // A single positive answer is enough
  642.                     // In this case the good answer will be provided by the checkSociety
  643.                     return $this->checkManager($individual$user);
  644.                 }
  645.             }
  646.         }
  647.         // If we are here, all hope is lost
  648.         return false;
  649.     }
  650.     private function canImport(Access $userAccessFunction $function)
  651.     {
  652.         // Module activated ?
  653.         // CLIENT_LIGHT cannot add Clients / Stores
  654.         if ($this->moduleTools->isInactiveByCode($this->currentGroupModule::MODULE_CLIENT))
  655.         {
  656.             return false;
  657.         }
  658.         // Get Acl_Permission
  659.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_IMPORT);
  660.         if ($aclPerm === null)        return false;
  661.         // Get Acl
  662.         $acl $this->aclRepository->findOneBy(array(
  663.             'function'        =>    $function,
  664.             'permission'    =>    $aclPerm
  665.         ));
  666.         if ($acl === null)        return false;
  667.         // Since only one acl type can exist
  668.         // we can return the result of the acl_permission
  669.         return $acl->getValue();
  670.     }
  671.     // Plan.io Task #3747
  672.     private function canMerge(Individual $individualAccess $userAccessFunction $accessFunction)
  673.     {
  674.         // Two Acl_Permission may exist
  675.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_MERGE);
  676.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_MERGE_SOCIETY);
  677.         // If all are null, exit
  678.         if ($aclPerm === null && $aclPermSociety === null)
  679.             return false;
  680.         // Get First one
  681.         if ($aclPerm !== null)
  682.         {
  683.             $acl $this->aclRepository->findOneBy(array(
  684.                 'function'        =>    $accessFunction,
  685.                 'permission'    =>    $aclPerm
  686.             ));
  687.             if ($acl !== null)
  688.             {
  689.                 if ($acl->getValue())
  690.                 {
  691.                     // A single positive answer is enough
  692.                     return true;
  693.                 }
  694.             }
  695.         }
  696.         // If we are here it means that nothing good has been found
  697.         // Load second permission
  698.         if ($aclPermSociety !== null)
  699.         {
  700.             $acl $this->aclRepository->findOneBy(array(
  701.                 'function'        =>    $accessFunction,
  702.                 'permission'    =>    $aclPermSociety
  703.             ));
  704.             if ($acl !== null)
  705.             {
  706.                 if ($acl->getValue())
  707.                 {
  708.                     // A single positive answer is enough
  709.                     // In this case the good answer will be provided by the checkSociety
  710.                     return $this->checkSociety($individual$user);
  711.                 }
  712.             }
  713.         }
  714.         // If we are here, all hope is lost
  715.         return false;
  716.     }
  717.     // Plan.io Task #3747
  718.     // We need to know if the user can access the merge tool
  719.     // Specific merge permissions will be checked later
  720.     private function canUseMergeTool(Access $userAccessFunction $accessFunction)
  721.     {
  722.         // Two Acl_Permission may exist
  723.         $aclPerm $this->aclPermissionRepository->findOneByName(self::ACL_PERM_MERGE);
  724.         $aclPermSociety $this->aclPermissionRepository->findOneByName(self::ACL_PERM_MERGE_SOCIETY);
  725.         // If all are null, exit
  726.         if ($aclPerm === null && $aclPermSociety === null)
  727.             return false;
  728.         // Get First one
  729.         if ($aclPerm !== null)
  730.         {
  731.             $acl $this->aclRepository->findOneBy(array(
  732.                 'function'        =>    $accessFunction,
  733.                 'permission'    =>    $aclPerm
  734.             ));
  735.             if ($acl !== null)
  736.             {
  737.                 if ($acl->getValue())
  738.                 {
  739.                     // A single positive answer is enough
  740.                     return true;
  741.                 }
  742.             }
  743.         }
  744.         // If we are here it means that nothing good has been found
  745.         // Load second permission
  746.         if ($aclPermSociety !== null)
  747.         {
  748.             $acl $this->aclRepository->findOneBy(array(
  749.                 'function'        =>    $accessFunction,
  750.                 'permission'    =>    $aclPermSociety
  751.             ));
  752.             if ($acl !== null)
  753.             {
  754.                 if ($acl->getValue())
  755.                 {
  756.                     // A single positive answer is enough
  757.                     return true;
  758.                 }
  759.             }
  760.         }
  761.         // If we are here, all hope is lost
  762.         return false;
  763.     }
  764. }