appWithRoles = MagicApps::with('appRoles')->get()->toArray(); //Итоговый массив с доступами пользователя к приложению и ролью $userAppAccess = []; foreach ($this->appWithRoles as $appData) { //Определяем по какому массиву проверять доступ к приложению - почтовые рассылки или группы AD if (empty($appData['access_groups_email'])) { $appAccess = explode(';', $appData['access_groups_ad']); $userAccessGroups = UserContext::getUserADGroups(); } else { $appAccess = explode(';', $appData['access_groups_email']); $userAccessGroups = UserContext::getUserEmails(); } //Если пересечения групп доступа приложения и групп доступа пользователя отсутствуют, считаем, что доступа нет if (empty(array_intersect($appAccess, $userAccessGroups))) { continue; } //Если ролевая модель отсутствует для приложения как таковая, прописывам значение null if (empty($appData['app_roles'])) { $userAppAccess[$appData['app_name']] = null; } else { //Если ролевая модель существует, ставим значение false, которое будет заменено ролью пользователя. Сохранение false на выходе, в свою очередь, сигнализирует, что роль пользователя не определилась $userAppAccess[$appData['app_name']] = false; foreach ($appData['app_roles'] as $roleData) { if($this->checkRoleAccess($appData['role_driver'], explode(';', $roleData['role_access']))) { $userAppAccess[$appData['app_name']] = $roleData['app_role']; //Все роли идут по приоритету важности, поэтому останавливаемся на самой важной и возвращаем ее, остальные роли не перебираем. Я пока не уверен как лучше организовать отображение функционала ролей в приложениях: весь нужный функционал "класть" в одну роль и отображать строго тот функционал, который относится к роли. Или распределять функционал между ролями и, если пользователь входит в несколько ролей, отображать весь функционал всех ролей, куда он может входить. В случае последнего варианта, нужно будет хранить все доступные роли пользователя, а не только самую важную по приортету. //Также пока непонятно, реализовывать ли возможность переключаться между ролями на продакшн среде. Если реализовывать, так же придется хранить все роли, куда входит пользователь. Но в этом случае есть риски запутаться в логировании, например, если пользователь под ролью админ переключится на пользователя юзер и совершит от него действие break; } } } } return $userAppAccess; } /** * Возвращаем результат проверки доступности роли * * @param string $roleAccessDriver название драйвера доступа роли * @param array $roleData массив с перечисленными рассылками/логинами/группами, которым доступна роль * @return bool */ public function checkRoleAccess(string $roleAccessDriver, array $roleData): bool { switch ($roleAccessDriver) { case 'login': return in_array(UserContext::getUserLogin(), $roleData); break; case 'email': return !empty(array_intersect(UserContext::getUserEmails(), $roleData)); break; case 'ADgroup': return !empty(array_intersect(UserContext::getUserADGroups(), $roleData)); break; } } //УДАЛИТЬ // public function getUserAppRoles(array $userGroups) // { // $userEmails = session()->get('_auth_groups'); // $userLogin = session()->get('_auth_login'); // $magicApps = $this->getAppRoles(); // } }