join('permissions', 'permissions.id', '=', 'album_permissions_cache.permission_id') ->where([ ['album_permissions_cache.user_id', null], ['permissions.section', 'album'], ['permissions.description', $permission] ]) ->select('album_permissions_cache.album_id') ->distinct() ->get(); foreach ($anonymousUsersCan as $item) { $result[] = $item->album_id; } $query = DB::table('album_permissions_cache') ->join('permissions', 'permissions.id', '=', 'album_permissions_cache.permission_id') ->where([ ['album_permissions_cache.user_id', (is_null($user) || $user->isAnonymous() ? null : $user->id)], ['permissions.section', 'album'], ['permissions.description', $permission] ]) ->select('album_permissions_cache.album_id') ->distinct() ->get(); foreach ($query as $item) { if (!in_array($item->album_id, $result)) { $result[] = $item->album_id; } } return $result; } public function rebuildCache() { $this->rebuildAlbumCache(); } public function userCan_Album(Album $album, User $user, $permission) { // First check if the anonymous user can do what is being requested - if so, the permission would also inherit // to logged-in users $anonymousUsersCan = DB::table('album_permissions_cache') ->join('permissions', 'permissions.id', '=', 'album_permissions_cache.permission_id') ->where([ ['album_permissions_cache.album_id', $album->id], ['album_permissions_cache.user_id', null], ['permissions.section', 'album'], ['permissions.description', $permission] ]) ->count() > 0; if ($anonymousUsersCan) { return true; } return DB::table('album_permissions_cache') ->join('permissions', 'permissions.id', '=', 'album_permissions_cache.permission_id') ->where([ ['album_permissions_cache.album_id', $album->id], ['album_permissions_cache.user_id', (is_null($user) || $user->isAnonymous() ? null : $user->id)], ['permissions.section', 'album'], ['permissions.description', $permission] ]) ->count() > 0; } public function usersWhoCan_Album(Album $album, $permission) { $users = DB::table('album_permissions_cache') ->join('permissions', 'permissions.id', '=', 'album_permissions_cache.permission_id') ->where([ ['album_permissions_cache.album_id', $album->id], ['permissions.section', 'album'], ['permissions.description', $permission] ]) ->get(); // Include the album's owner (who can do everything) $users->push($album->user); return $users; } private function rebuildAlbumCache() { // Get a list of albums $albums = Album::all(); // Get a list of all configured permissions $albumUserPermissions = DB::table('album_user_permissions')->get(); $albumGroupPermissions = DB::table('album_group_permissions')->get(); $albumAnonPermissions = DB::table('album_anonymous_permissions')->get(); $defaultAlbumUserPermissions = AlbumDefaultUserPermission::all(); $defaultAlbumGroupPermissions = AlbumDefaultGroupPermission::all(); $defaultAnonPermissions = AlbumDefaultAnonymousPermission::all(); // Get a list of all user->group memberships $userGroups = DB::table('user_groups')->get(); // Build a matrix of new permissions $permissionsCache = []; /** @var Album $album */ foreach ($albums as $album) { $effectiveAlbumID = $album->effectiveAlbumIDForPermissions(); if ($effectiveAlbumID === 0) { /* Use the default permissions list */ foreach ($defaultAnonPermissions as $anonymousPermission) { $permissionsCache[] = [ 'album_id' => $album->id, 'permission_id' => $anonymousPermission->permission_id, 'created_at' => new \DateTime(), 'updated_at' => new \DateTime() ]; } foreach ($defaultAlbumUserPermissions as $userPermission) { $permissionsCache[] = [ 'user_id' => $userPermission->user_id, 'album_id' => $album->id, 'permission_id' => $userPermission->permission_id, 'created_at' => new \DateTime(), 'updated_at' => new \DateTime() ]; } foreach ($defaultAlbumGroupPermissions as $groupPermission) { // Get a list of users in this group, and add one per user $usersInGroup = array_filter($userGroups->toArray(), function ($item) use ($groupPermission) { return $item->group_id = $groupPermission->group_id; }); foreach ($usersInGroup as $userGroup) { $permissionsCache[] = [ 'user_id' => $userGroup->user_id, 'album_id' => $album->id, 'permission_id' => $groupPermission->permission_id, 'created_at' => new \DateTime(), 'updated_at' => new \DateTime() ]; } } } else { /* Use the specified album-specific permissions */ $anonymousPermissions = array_filter($albumAnonPermissions->toArray(), function ($item) use ($effectiveAlbumID) { return ($item->album_id == $effectiveAlbumID); }); foreach ($anonymousPermissions as $anonymousPermission) { $permissionsCache[] = [ 'album_id' => $album->id, 'permission_id' => $anonymousPermission->permission_id, 'created_at' => new \DateTime(), 'updated_at' => new \DateTime() ]; } $userPermissions = array_filter($albumUserPermissions->toArray(), function ($item) use ($effectiveAlbumID) { return ($item->album_id == $effectiveAlbumID); }); foreach ($userPermissions as $userPermission) { $permissionsCache[] = [ 'user_id' => $userPermission->user_id, 'album_id' => $album->id, 'permission_id' => $userPermission->permission_id, 'created_at' => new \DateTime(), 'updated_at' => new \DateTime() ]; } $groupPermissions = array_filter($albumGroupPermissions->toArray(), function ($item) use ($effectiveAlbumID) { return ($item->album_id == $effectiveAlbumID); }); foreach ($groupPermissions as $groupPermission) { // Get a list of users in this group, and add one per user $usersInGroup = array_filter($userGroups->toArray(), function ($item) use ($groupPermission) { return $item->group_id = $groupPermission->group_id; }); foreach ($usersInGroup as $userGroup) { $permissionsCache[] = [ 'user_id' => $userGroup->user_id, 'album_id' => $album->id, 'permission_id' => $groupPermission->permission_id, 'created_at' => new \DateTime(), 'updated_at' => new \DateTime() ]; } } } } $this->savePermissionsCache($permissionsCache); } private function savePermissionsCache(array $cacheToSave) { DB::transaction(function() use ($cacheToSave) { DB::table('album_permissions_cache')->truncate(); foreach ($cacheToSave as $cacheItem) { DB::table('album_permissions_cache')->insert($cacheItem); } }); } }