/** * Returns permission masks for each route. * This is where permissions are interpreted. * * @param string|null $board_uri * @return array */ protected function getPermissionMask($board_uri = null) { // Get our routes. $routes = $this->getPermissionRoutes(); // Build a route name to empty array relationship. $permissions = array_combine(array_keys($routes), array_map(function ($n) { return []; }, $routes)); // There are two kinds of permission assignments. // 1. Permissions that belong to the route. // 2. Permissions directly assigned to the user. // // When a permission is a part of a major mask branch (identified in getPermissionRoutes), // then any role with that role name becomes a part of the mask. // // When a permission is directly assigned to the user, then only that mask and its // inherited mask are incorporated. Inheritance only goes up one step for right now. $allGroups = []; // Pull each route and add its groups to the master collection. foreach ($routes as $branch => $roleGroups) { $allGroups = array_merge($allGroups, $roleGroups); } // We only want uniques. $allGroups = array_unique($allGroups); // In order to determine if we want to include a role in a specific mask, // we must also pull a user's roles to see what is directly applied to them. $userRoles = $this->getRoles()->modelKeys(); $parentRoles = Role::where('system', true)->with('permissions')->get()->getDictionary(); // Write out a monster query to pull precisely what we need to build our permission masks. $query = Role::where(function ($query) use($board_uri, $allGroups) { $query->where(function ($query) use($board_uri) { $query->orWhereNull('board_uri'); $query->orWhere('board_uri', $board_uri); }); // Pull any role that belongs to our masks's route. $query->whereIn('roles.role', $allGroups); // If we're not anonymous, we also need directly assigned roles. if (!$this->isAnonymous()) { $query->orWhereHas('users', function ($query) { //$query->where( \DB::raw("`user_roles`.`user_id`"), $this->user_id); $query->where("user_roles.user_id", $this->user_id); }); } else { $query->whereDoesntHave('users'); } }); // Gather our inherited roles, their permissions, and our permissions. $query->with('permissions'); $query->orderBy('weight'); // Gather our inherited roles, their permissions, and our permissions. // Execute query $query->chunk(100, function ($roles) use($routes, $parentRoles, $userRoles, &$permissions) { RoleCache::addRolesToPermissions($roles, $routes, $parentRoles, $userRoles, $permissions); }); return $permissions; }