Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
85f8776
Removing role table from codebase
yannik131 Aug 25, 2026
6969cf0
further replacing roles with enum
yannik131 Aug 26, 2026
d8c9c82
further replacing roles with enum
yannik131 Aug 26, 2026
9f75cb6
Fixed remaining role tests
yannik131 Aug 26, 2026
daccf56
formatting
yannik131 Aug 26, 2026
0f62736
fixed linter errors
yannik131 Aug 26, 2026
fcaf783
made down() recreate FKs
yannik131 Aug 26, 2026
22157ad
Moved Role to Enums folder
yannik131 Aug 26, 2026
439e854
composer fix
yannik131 Aug 26, 2026
e5718e4
media_type enum and migration
yannik131 Aug 27, 2026
09beb1a
todo comments
yannik131 Aug 27, 2026
ee19c9b
replace MediaType with enum
yannik131 Aug 28, 2026
c67a0b2
replacing media type with enum
yannik131 Aug 28, 2026
bda4219
fixed tests (media type enum)
yannik131 Aug 28, 2026
d4988d1
fixed frontend bugs
yannik131 Aug 28, 2026
c110ea2
composer lint & fix
yannik131 Aug 29, 2026
6762396
Reversed enum folder creation
yannik131 Aug 29, 2026
91e3c41
shapes enum & migrations
yannik131 Aug 29, 2026
bf7101b
Deleted factories
yannik131 Aug 29, 2026
e73c747
Working on fixing shape tests
yannik131 Aug 29, 2026
c229549
fixed last failing shape test
yannik131 Aug 30, 2026
b84216d
visiblity enum was very easy
yannik131 Aug 30, 2026
b306951
composer lint
yannik131 Aug 30, 2026
888823e
Replacing report type with enum
yannik131 Aug 30, 2026
77d1b10
remaining report type replacements
yannik131 Aug 30, 2026
0b05f8e
fixed linter errors
yannik131 Aug 31, 2026
5e78462
fixed failing tests
yannik131 Aug 31, 2026
b2d43c1
renamed role migration
yannik131 Aug 31, 2026
01ecd5d
fixed name access
yannik131 Aug 31, 2026
ccb63ba
Use Rule::enum
yannik131 Sep 9, 2026
2f50442
Fix Role typo
yannik131 Sep 9, 2026
904762f
Use named argument
yannik131 Sep 9, 2026
ef8be76
Introduce EnumSerialization trait
yannik131 Sep 9, 2026
48608be
Apply linter
yannik131 Sep 9, 2026
bab6151
Rename migrations & map old to new
yannik131 Sep 10, 2026
9cd6c7a
Add EnumMigrationHelper to make code DRY
yannik131 Sep 10, 2026
ec93a0f
Drop fk constraint before updating values
yannik131 Sep 10, 2026
8a12695
Fix migration helper code ordering
yannik131 Sep 11, 2026
6a7b404
Remove Role eloquent wrapping
yannik131 Sep 11, 2026
d1e77b2
Update EnumMigrationHelper comment
yannik131 Sep 11, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions app/Annotation.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,11 @@ abstract public function getFileIdAttribute();
/**
* The shape of this annotation.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo<Shape, $this>
* @return Shape
*/
public function shape()
public function getShapeAttribute()
{
return $this->belongsTo(Shape::class);
return Shape::from($this->shape_id);
}

/**
Expand All @@ -213,7 +213,7 @@ public function getPoints(): array
*/
public function getShape(): Shape
{
return $this->shape;
return Shape::from($this->shape_id);
}

/**
Expand Down
4 changes: 2 additions & 2 deletions app/Console/Commands/NewUser.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@
$u->uuid = Uuid::uuid4();

if ($this->confirm('Should the user be global admin? [y|N]')) {
$u->role_id = Role::adminId();
$u->role_id = Role::ADMIN->value;

Check failure on line 41 in app/Console/Commands/NewUser.php

View workflow job for this annotation

GitHub Actions / lint-php

Property Biigle\User::$role_id (Biigle\Role) does not accept int.
} else {
$u->role_id = Role::editorId();
$u->role_id = Role::EDITOR->value;

Check failure on line 43 in app/Console/Commands/NewUser.php

View workflow job for this annotation

GitHub Actions / lint-php

Property Biigle\User::$role_id (Biigle\Role) does not accept int.
}

if ($this->confirm('Do you wish to auto-generate a password? [y|N]')) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public function store(Request $request, ArchiveManager $manager)
}
$tree = DB::transaction(function () use ($import, $request) {
$tree = $import->perform();
$tree->addMember($request->user(), Role::admin());
$tree->addMember($request->user(), Role::ADMIN);

return $tree;
});
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Controllers/Api/LabelTreeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public function store(StoreLabelTree $request)
$tree->description = $request->input('description');
$tree->uuid = Uuid::uuid4();
$tree->save();
$tree->addMember($request->user(), Role::admin());
$tree->addMember($request->user(), Role::ADMIN);

if (isset($request->project)) {
$tree->projects()->attach($request->project);
Expand Down
8 changes: 5 additions & 3 deletions app/Http/Controllers/Api/MediaTypeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ class MediaTypeController extends Controller
* }
* ]
*
* @return \Illuminate\Database\Eloquent\Collection
* @return \Illuminate\Support\Collection<int, array>
*/
public function index()
{
return MediaType::all();
return collect(MediaType::cases())->map->toArray()->values();
}

/**
Expand All @@ -54,6 +54,8 @@ public function index()
*/
public function show($id)
{
return MediaType::findOrFail($id);
$mediaType = MediaType::tryFrom((int) $id);
abort_if($mediaType === null, 404);
return $mediaType;
}
}
2 changes: 1 addition & 1 deletion app/Http/Controllers/Api/PendingVolumeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public function store(StorePendingVolume $request)
*/
public function storeVolume(StorePendingVolumeFromVolume $request)
{
$project = Project::inCommon($request->user(), $request->volume->id, [Role::adminId()])->first();
$project = Project::inCommon($request->user(), $request->volume->id, [Role::ADMIN->value])->first();

// Delete individually to trigger deletion of metadata files.
$project->pendingVolumes()->where('user_id', $request->user()->id)
Expand Down
4 changes: 2 additions & 2 deletions app/Http/Controllers/Api/ProjectInvitationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function store(StoreProjectInvitation $request)
'uuid' => Uuid::uuid4(),
'project_id' => $request->project->id,
'expires_at' => $request->input('expires_at'),
'role_id' => $request->input('role_id', Role::editorId()),
'role_id' => $request->input('role_id', Role::EDITOR->value),
'max_uses' => $request->input('max_uses'),
'add_to_sessions' => $request->input('add_to_sessions', false),
]);
Expand Down Expand Up @@ -77,7 +77,7 @@ public function join(JoinProjectInvitation $request, $id)
$project = $request->invitation->project;
$userId = $request->user()->id;
if (!$project->users()->where('user_id', $userId)->exists()) {
$project->addUserId($userId, $request->invitation->role_id);
$project->addUserId($userId, $request->invitation->role_id->value);
$invitation->increment('current_uses');

if ($invitation->add_to_sessions) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,13 @@ public function index(Request $request, $id, $name)
$this->authorize('update', $project);

$volumes = Volume::select('id', 'name', 'updated_at', 'media_type_id')
->with('mediaType')
// All volumes of other projects where the user has admin rights on.
->whereIn('id', fn ($query) => $query->select('volume_id')
->from('project_volume')
->whereIn('project_id', fn ($query) => $query->select('project_id')
->from('project_user')
->where('user_id', $request->user()->id)
->where('project_role_id', Role::adminId())
->where('project_role_id', Role::ADMIN->value)
->where('project_id', '!=', $id)))
->where('name', 'ilike', "%{$name}%")
// Do not return volumes that are already attached to this project.
Expand All @@ -68,6 +67,7 @@ public function index(Request $request, $id, $name)
$volumes->each(function ($item) use ($hidden) {
$item->append('thumbnailUrl')
->append('thumbnailsUrl')
->setAttribute('media_type', $item->mediaType) // TODO compare with others for test, test index and fuzzy search
->makeHidden($hidden);
});

Expand Down
4 changes: 2 additions & 2 deletions app/Http/Controllers/Api/ReportsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,10 @@ public function destroy($id)
* @apiGroup Reports
* @apiName IndexReports
* @apiPermission user
* @return \Illuminate\Database\Eloquent\Collection
* @return \Illuminate\Support\Collection
*/
public function index()
{
return ReportType::all();
return collect(ReportType::cases())->map->toArray()->values();
}
}
10 changes: 6 additions & 4 deletions app/Http/Controllers/Api/RoleController.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ class RoleController extends Controller
* }
* ]
*
* @return \Illuminate\Database\Eloquent\Collection
* @return \Illuminate\Support\Collection<int, array>
*/
public function index()
{
return Role::all();
return collect(Role::cases())->map->toArray()->values();
}

/**
Expand All @@ -56,8 +56,10 @@ public function index()
* @param int $id
* @return Role
*/
public function show($id)
public function show($id): Role
{
return Role::findOrFail($id);
$role = Role::tryFrom((int) $id);
abort_if($role === null, 404);
return $role;
}
}
8 changes: 5 additions & 3 deletions app/Http/Controllers/Api/ShapeController.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ class ShapeController extends Controller
* }
* ]
*
* @return \Illuminate\Database\Eloquent\Collection
* @return \Illuminate\Support\Collection<int, array>
*/
public function index()
{
return Shape::all();
return collect(Shape::cases())->map->toArray()->values();
}

/**
Expand All @@ -54,6 +54,8 @@ public function index()
*/
public function show($id)
{
return Shape::findOrFail($id);
$shape = Shape::tryFrom((int) $id);
abort_if($shape === null, 404);
return $shape;
}
}
8 changes: 4 additions & 4 deletions app/Http/Controllers/Api/UserController.php
Original file line number Diff line number Diff line change
Expand Up @@ -222,18 +222,18 @@
$user->password = bcrypt($request->input('password'));
}

$user->role_id = $request->input('role_id', $user->role_id);
$user->role_id = $request->input('role_id', $user->role_id->value);
$user->firstname = $request->input('firstname', $user->firstname);
$user->lastname = $request->input('lastname', $user->lastname);
$user->email = $request->input('email', $user->email);
$user->affiliation = $request->input('affiliation', $user->affiliation);
if ($request->filled('can_review') && $user->role_id === Role::editorId()) {
if ($request->filled('can_review') && $user->role_id->value === Role::EDITOR->value) {
$user->canReview = (bool) $request->input('can_review');
} else {
$user->canReview = false;
}

if ($request->filled('rate_limit') && $user->role_id === Role::editorId()) {
if ($request->filled('rate_limit') && $user->role_id->value === Role::EDITOR->value) {
$user->hasNoRateLimit = !boolval($request->input('rate_limit'));
} else {
$user->hasNoRateLimit = false;
Expand Down Expand Up @@ -352,7 +352,7 @@
$user->email = $request->input('email');
$user->affiliation = $request->input('affiliation');
$user->password = bcrypt($request->input('password'));
$user->role_id = Role::editorId();
$user->role_id = Role::EDITOR->value;

Check failure on line 355 in app/Http/Controllers/Api/UserController.php

View workflow job for this annotation

GitHub Actions / lint-php

Property Biigle\User::$role_id (Biigle\Role) does not accept int.
if ($request->filled('uuid')) {
$user->uuid = $request->input('uuid');
} else {
Expand Down
6 changes: 3 additions & 3 deletions app/Http/Controllers/Api/UserRegistrationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
abort(Response::HTTP_NOT_FOUND);
}

$user = User::where('role_id', Role::guestId())->findOrFail($id);
$user->role_id = Role::editorId();
$user = User::where('role_id', Role::GUEST->value)->findOrFail($id);
$user->role_id = Role::EDITOR->value;

Check failure on line 44 in app/Http/Controllers/Api/UserRegistrationController.php

View workflow job for this annotation

GitHub Actions / lint-php

Property Biigle\User::$role_id (Biigle\Role) does not accept int.
$user->save();

$user->notify(new RegistrationAccepted);
Expand Down Expand Up @@ -80,7 +80,7 @@
abort(Response::HTTP_NOT_FOUND);
}

$user = User::where('role_id', Role::guestId())->findOrFail($id);
$user = User::where('role_id', Role::GUEST->value)->findOrFail($id);
$user->notifyNow(new RegistrationRejected);
$user->delete();

Expand Down
8 changes: 5 additions & 3 deletions app/Http/Controllers/Api/VisibilityController.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ class VisibilityController extends Controller
* }
* ]
*
* @return \Illuminate\Database\Eloquent\Collection
* @return \Illuminate\Support\Collection
*/
public function index()
{
return Visibility::all();
return collect(Visibility::cases())->map->toArray()->values();
}

/**
Expand All @@ -54,6 +54,8 @@ public function index()
*/
public function show($id)
{
return Visibility::findOrFail($id);
$visibility = Visibility::tryFrom((int) $id);
abort_if($visibility === null, 404);
return $visibility;
}
}
4 changes: 2 additions & 2 deletions app/Http/Controllers/Auth/RegisterController.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,9 @@
$user->password = Hash::make($data['password']);
$user->uuid = Uuid::uuid4();
if ($this->isAdminConfirmationEnabled()) {
$user->role_id = Role::guestId();
$user->role_id = Role::GUEST->value;

Check failure on line 102 in app/Http/Controllers/Auth/RegisterController.php

View workflow job for this annotation

GitHub Actions / lint-php

Property Biigle\User::$role_id (Biigle\Role) does not accept int.
} else {
$user->role_id = Role::editorId();
$user->role_id = Role::EDITOR->value;

Check failure on line 104 in app/Http/Controllers/Auth/RegisterController.php

View workflow job for this annotation

GitHub Actions / lint-php

Property Biigle\User::$role_id (Biigle\Role) does not accept int.
}

app()->make(Modules::class)->callControllerMixins('createNewUser', [
Expand Down
5 changes: 4 additions & 1 deletion app/Http/Controllers/Views/Admin/ExportController.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ public function index()
abort(404);
}

$mediaTypes = MediaType::pluck('id', 'name');
$mediaTypes = collect(MediaType::cases())->mapWithKeys(
fn (MediaType $mediaType)
=> [$mediaType->label() => $mediaType->value]
);

return view('export.index', compact('allowedExports', 'mediaTypes'));
}
Expand Down
4 changes: 2 additions & 2 deletions app/Http/Controllers/Views/Admin/ImportController.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ protected function showLabelTreeImport(LabelTreeImport $import, $token)

$excludedLabelTreeCandidatesCount = $importLabelTreesCount - $labelTreeCandidatesCount;

$adminRoleId = Role::adminId();
$adminRoleId = Role::ADMIN->value;

return view('import.showLabelTree', compact(
'importLabelTreesCount',
Expand Down Expand Up @@ -161,7 +161,7 @@ protected function showVolumeImport(VolumeImport $import, string $token)
$userCandidates = $import->getUserImportCandidates()
->map([$this, 'hideUserCredentials']);

$adminRoleId = Role::adminId();
$adminRoleId = Role::ADMIN->value;

return view('import.showVolume', compact(
'volumeCandidates',
Expand Down
20 changes: 10 additions & 10 deletions app/Http/Controllers/Views/Admin/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ public function get(Request $request)
->paginate(100);

$roleNames = [
Role::adminId() => 'Admin',
Role::editorId() => 'Editor',
Role::guestId() => 'Guest',
Role::ADMIN->value => 'Admin',
Role::EDITOR->value => 'Editor',
Role::GUEST->value => 'Guest',
];

$usersCount = User::whereDate('created_at', '>=', now()->subWeek())
Expand Down Expand Up @@ -75,9 +75,9 @@ public function edit($id)
return view('admin.users.edit')
->with('affectedUser', User::findOrFail($id))
->with('roles', [
Role::admin(),
Role::editor(),
Role::guest(),
Role::ADMIN,
Role::EDITOR,
Role::GUEST,
]);
}

Expand All @@ -99,7 +99,7 @@ public function delete($id)
public function show(Modules $modules, $id)
{
$user = User::findOrFail($id);
$roleClass = $this->roleClassMap($user->role_id);
$roleClass = $this->roleClassMap($user->role_id->value);
$values = $this->showProject($user);
$values = array_merge($values, $this->showVolume($user));
$values = array_merge($values, $this->showAnnotations($user));
Expand All @@ -122,9 +122,9 @@ public function show(Modules $modules, $id)
protected function roleClassMap($id = null)
{
$map = [
Role::adminId() => 'danger',
Role::editorId() => 'primary',
Role::guestId() => 'default',
Role::ADMIN->value => 'danger',
Role::EDITOR->value => 'primary',
Role::GUEST->value => 'default',
];

if (!is_null($id)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ public function show(Request $request, $id)
// Array of all project IDs that the user and the image have in common
// and where the user is editor, expert or admin.
$projectIds = Project::inCommon($user, $image->volume_id, [
Role::editorId(),
Role::expertId(),
Role::adminId(),
Role::EDITOR->value,
Role::EXPERT->value,
Role::ADMIN->value,
])->pluck('id');
}

Expand All @@ -56,7 +56,7 @@ public function show(Request $request, $id)
})
->get();

$shapes = Shape::pluck('name', 'id');
$shapes = Shape::pluckById();

$annotationSessions = $image->volume->annotationSessions()
->select('id', 'name', 'starts_at', 'ends_at')
Expand Down
Loading
Loading