class EntityPermissionEvaluator
{
- protected string $action;
-
- public function __construct(string $action)
- {
- $this->action = $action;
+ public function __construct(
+ protected string $action
+ ) {
}
public function evaluateEntityForUser(Entity $entity, array $userRoleIds): ?bool
*/
protected function getPermissionsMapByTypeId(array $typeIdChain, array $filterRoleIds): array
{
- $query = EntityPermission::query()->where(function (Builder $query) use ($typeIdChain) {
- foreach ($typeIdChain as $typeId) {
- $query->orWhere(function (Builder $query) use ($typeId) {
- [$type, $id] = explode(':', $typeId);
- $query->where('entity_type', '=', $type)
- ->where('entity_id', '=', $id);
- });
+ $idsByType = [];
+ foreach ($typeIdChain as $typeId) {
+ [$type, $id] = explode(':', $typeId);
+ if (!isset($idsByType[$type])) {
+ $idsByType[$type] = [];
}
- });
- if (!empty($filterRoleIds)) {
- $query->where(function (Builder $query) use ($filterRoleIds) {
- $query->whereIn('role_id', [...$filterRoleIds, 0]);
- });
+ $idsByType[$type][] = $id;
}
- $relevantPermissions = $query->get(['entity_id', 'entity_type', 'role_id', $this->action])->all();
+ $relevantPermissions = [];
+
+ foreach ($idsByType as $type => $ids) {
+ $idsChunked = array_chunk($ids, 10000);
+ foreach ($idsChunked as $idChunk) {
+ $permissions = $this->getPermissionsForEntityIdsOfType($type, $idChunk, $filterRoleIds);
+ array_push($relevantPermissions, ...$permissions);
+ }
+ }
$map = [];
foreach ($relevantPermissions as $permission) {
return $map;
}
+ /**
+ * @param string[] $ids
+ * @param int[] $filterRoleIds
+ * @return EntityPermission[]
+ */
+ protected function getPermissionsForEntityIdsOfType(string $type, array $ids, array $filterRoleIds): array
+ {
+ $query = EntityPermission::query()
+ ->where('entity_type', '=', $type)
+ ->whereIn('entity_id', $ids);
+
+ if (!empty($filterRoleIds)) {
+ $query->where(function (Builder $query) use ($filterRoleIds) {
+ $query->whereIn('role_id', [...$filterRoleIds, 0]);
+ });
+ }
+
+ return $query->get(['entity_id', 'entity_type', 'role_id', $this->action])->all();
+ }
+
/**
* @return string[]
*/
$role->load('permissions');
// Chunk through all books
- $this->bookFetchQuery()->chunk(20, function ($books) use ($roles) {
+ $this->bookFetchQuery()->chunk(10, function ($books) use ($roles) {
$this->buildJointPermissionsForBooks($books, $roles);
});
// Chunk through all bookshelves
Bookshelf::query()->select(['id', 'owned_by'])
- ->chunk(50, function ($shelves) use ($roles) {
+ ->chunk(100, function ($shelves) use ($roles) {
$this->createManyJointPermissions($shelves->all(), $roles);
});
}
/** @var Book $largeBook */
$largeBook = Book::factory()->create(['name' => 'Large book' . Str::random(10), 'created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
- $pages = Page::factory()->count(200)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
$chapters = Chapter::factory()->count(50)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
-
- $largeBook->pages()->saveMany($pages);
$largeBook->chapters()->saveMany($chapters);
- $all = array_merge([$largeBook], array_values($pages->all()), array_values($chapters->all()));
+
+ $allPages = [];
+
+ foreach ($chapters as $chapter) {
+ $pages = Page::factory()->count(100)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id, 'chapter_id' => $chapter->id]);
+ $largeBook->pages()->saveMany($pages);
+ array_push($allPages, ...$pages->all());
+ }
+
+ $all = array_merge([$largeBook], $allPages, array_values($chapters->all()));
app()->make(JointPermissionBuilder::class)->rebuildForEntity($largeBook);
app()->make(SearchIndex::class)->indexEntities($all);