Big commit whatever

This commit is contained in:
2026-06-04 12:44:22 +02:00
parent ee1a87f125
commit 4fb7b1691c
133 changed files with 26137 additions and 1097 deletions
@@ -0,0 +1,90 @@
<?php
namespace App\Http\Controllers;
use App\Models\Album;
use App\Models\Track;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class AlbumController extends Controller
{
public function index(): JsonResponse
{
return response()->json(Album::with(['label', 'artist', 'genres', 'tracks.artists', 'tracks.genres'])->get());
}
public function show(Album $album): JsonResponse
{
return response()->json($album->load(['label', 'artist', 'genres', 'tracks.artists', 'tracks.genres']));
}
public function store(Request $request): JsonResponse
{
$data = $request->validate([
'title' => 'required|string|max:255',
'cover_path' => 'nullable|string|max:255',
'release_date' => 'nullable|date',
'duration_seconds' => 'nullable|integer',
'type' => 'nullable|in:album,single,ep',
'label_id' => 'nullable|exists:labels,id',
'artist_id' => 'nullable|exists:artists,id',
'genre_ids' => 'nullable|array',
'genre_ids.*' => 'exists:genres,id',
]);
$genreIds = $data['genre_ids'] ?? [];
unset($data['genre_ids']);
$album = Album::create($data);
if (!empty($genreIds)) {
$album->genres()->sync($genreIds);
}
if ($request->has('tracks')) {
foreach ($request->input('tracks') as $index => $trackData) {
$album->tracks()->create([
'title' => $trackData['title'],
'file_path' => $trackData['file_path'] ?? '',
'position' => $trackData['position'] ?? $index,
]);
}
}
return response()->json($album->load(['label', 'artist', 'genres', 'tracks.artists', 'tracks.genres']), 201);
}
public function update(Request $request, Album $album): JsonResponse
{
$data = $request->validate([
'title' => 'sometimes|required|string|max:255',
'cover_path' => 'nullable|string|max:255',
'release_date' => 'nullable|date',
'duration_seconds' => 'nullable|integer',
'type' => 'nullable|in:album,single,ep',
'label_id' => 'nullable|exists:labels,id',
'artist_id' => 'nullable|exists:artists,id',
'genre_ids' => 'nullable|array',
'genre_ids.*' => 'exists:genres,id',
]);
$genreIds = $data['genre_ids'] ?? null;
unset($data['genre_ids']);
$album->update($data);
if ($genreIds !== null) {
$album->genres()->sync($genreIds);
}
return response()->json($album->load(['label', 'artist', 'genres', 'tracks.artists', 'tracks.genres']));
}
public function destroy(Album $album): JsonResponse
{
$album->delete();
return response()->json(null, 204);
}
}
@@ -0,0 +1,57 @@
<?php
namespace App\Http\Controllers;
use App\Models\Artist;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class ArtistController extends Controller
{
public function index(): JsonResponse
{
return response()->json(Artist::with('label')->get());
}
public function show(Artist $artist): JsonResponse
{
return response()->json($artist->load(['label', 'tracks.album', 'tracks.genres']));
}
public function store(Request $request): JsonResponse
{
$data = $request->validate([
'name' => 'required|string|max:255',
'cover_path' => 'nullable|string|max:255',
'release_date' => 'nullable|date',
'label_id' => 'nullable|exists:labels,id',
'duration' => 'nullable|integer',
]);
$artist = Artist::create($data);
return response()->json($artist->load('label'), 201);
}
public function update(Request $request, Artist $artist): JsonResponse
{
$data = $request->validate([
'name' => 'sometimes|required|string|max:255',
'cover_path' => 'nullable|string|max:255',
'release_date' => 'nullable|date',
'label_id' => 'nullable|exists:labels,id',
'duration' => 'nullable|integer',
]);
$artist->update($data);
return response()->json($artist->load('label'));
}
public function destroy(Artist $artist): JsonResponse
{
$artist->delete();
return response()->json(null, 204);
}
}
@@ -0,0 +1,73 @@
<?php
namespace App\Http\Controllers;
use App\Models\Role;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Validation\ValidationException;
class AuthController extends Controller
{
public function register(Request $request): JsonResponse
{
$data = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users,email',
'password' => 'required|string|min:8|confirmed',
]);
$userRole = Role::where('name', 'user')->firstOrFail();
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => $data['password'],
'role_id' => $userRole->id,
]);
$token = $user->createToken('api')->plainTextToken;
return response()->json([
'token' => $token,
'user' => $user->load('role'),
], 201);
}
public function login(Request $request): JsonResponse
{
$data = $request->validate([
'email' => 'required|email',
'password' => 'required|string',
]);
$user = User::where('email', $data['email'])->first();
if (! $user || ! Hash::check($data['password'], $user->password)) {
throw ValidationException::withMessages([
'email' => ['The provided credentials are incorrect.'],
]);
}
$token = $user->createToken('api')->plainTextToken;
return response()->json([
'token' => $token,
'user' => $user->load('role'),
]);
}
public function logout(Request $request): JsonResponse
{
$request->user()->currentAccessToken()->delete();
return response()->json(['message' => 'Logged out.']);
}
public function me(Request $request): JsonResponse
{
return response()->json($request->user()->load('role'));
}
}
@@ -0,0 +1,8 @@
<?php
namespace App\Http\Controllers;
abstract class Controller
{
//
}
@@ -0,0 +1,43 @@
<?php
namespace App\Http\Controllers;
use App\Models\Genre;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class GenreController extends Controller
{
public function index(): JsonResponse
{
return response()->json(Genre::all());
}
public function show(Genre $genre): JsonResponse
{
return response()->json($genre);
}
public function store(Request $request): JsonResponse
{
$data = $request->validate(['name' => 'required|string|max:100']);
$genre = Genre::create($data);
return response()->json($genre, 201);
}
public function update(Request $request, Genre $genre): JsonResponse
{
$data = $request->validate(['name' => 'sometimes|required|string|max:100']);
$genre->update($data);
return response()->json($genre);
}
public function destroy(Genre $genre): JsonResponse
{
$genre->delete();
return response()->json(null, 204);
}
}
@@ -0,0 +1,43 @@
<?php
namespace App\Http\Controllers;
use App\Models\Label;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class LabelController extends Controller
{
public function index(): JsonResponse
{
return response()->json(Label::all());
}
public function show(Label $label): JsonResponse
{
return response()->json($label);
}
public function store(Request $request): JsonResponse
{
$data = $request->validate(['name' => 'required|string|max:100']);
$label = Label::create($data);
return response()->json($label, 201);
}
public function update(Request $request, Label $label): JsonResponse
{
$data = $request->validate(['name' => 'sometimes|required|string|max:100']);
$label->update($data);
return response()->json($label);
}
public function destroy(Label $label): JsonResponse
{
$label->delete();
return response()->json(null, 204);
}
}
@@ -0,0 +1,31 @@
<?php
namespace App\Http\Controllers;
use App\Models\Track;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class LikeController extends Controller
{
public function like(Request $request, Track $track): JsonResponse
{
$request->user()->likes()->syncWithoutDetaching([$track->id]);
return response()->json(['message' => 'Track liked.']);
}
public function unlike(Request $request, Track $track): JsonResponse
{
$request->user()->likes()->detach($track->id);
return response()->json(['message' => 'Track unliked.']);
}
public function index(Request $request): JsonResponse
{
$tracks = $request->user()->likes()->with(['album', 'artists', 'genres'])->get();
return response()->json($tracks);
}
}
@@ -0,0 +1,105 @@
<?php
namespace App\Http\Controllers;
use App\Models\Album;
use App\Models\Track;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class TrackController extends Controller
{
public function index(): JsonResponse
{
return response()->json(Track::with(['album', 'artists', 'genres'])->orderBy('position')->get());
}
public function show(Track $track): JsonResponse
{
return response()->json($track->load(['album.label', 'artists', 'genres']));
}
public function store(Request $request): JsonResponse
{
$data = $request->validate([
'title' => 'required|string|max:255',
'file_path' => 'required|string|max:255',
'duration_seconds' => 'nullable|integer',
'album_id' => 'nullable|exists:albums,id',
'position' => 'nullable|integer',
'artist_ids' => 'nullable|array',
'artist_ids.*' => 'exists:artists,id',
'genre_ids' => 'nullable|array',
'genre_ids.*' => 'exists:genres,id',
]);
if (!isset($data['position']) && isset($data['album_id'])) {
$data['position'] = Track::where('album_id', $data['album_id'])->max('position') + 1;
}
$track = Track::create($data);
if (!empty($data['artist_ids'])) {
$track->artists()->sync($data['artist_ids']);
}
if (!empty($data['genre_ids'])) {
$track->genres()->sync($data['genre_ids']);
}
return response()->json($track->load(['album', 'artists', 'genres']), 201);
}
public function update(Request $request, Track $track): JsonResponse
{
$data = $request->validate([
'title' => 'sometimes|required|string|max:255',
'file_path' => 'sometimes|required|string|max:255',
'duration_seconds' => 'nullable|integer',
'album_id' => 'nullable|exists:albums,id',
'position' => 'nullable|integer',
'artist_ids' => 'nullable|array',
'artist_ids.*' => 'exists:artists,id',
'genre_ids' => 'nullable|array',
'genre_ids.*' => 'exists:genres,id',
]);
$track->update($data);
if (array_key_exists('artist_ids', $data)) {
$track->artists()->sync($data['artist_ids'] ?? []);
}
if (array_key_exists('genre_ids', $data)) {
$track->genres()->sync($data['genre_ids'] ?? []);
}
return response()->json($track->load(['album', 'artists', 'genres']));
}
public function destroy(Track $track): JsonResponse
{
$track->delete();
return response()->json(null, 204);
}
public function reorder(Request $request, Album $album): JsonResponse
{
$data = $request->validate([
'positions' => 'required|array',
'positions.*.id' => 'required|exists:tracks,id',
'positions.*.position' => 'required|integer|min:0',
]);
foreach ($data['positions'] as $item) {
Track::where('id', $item['id'])
->where('album_id', $album->id)
->update(['position' => $item['position']]);
}
return response()->json(
$album->load(['tracks.artists', 'tracks.genres'])->tracks->sortBy('position')->values()
);
}
}
@@ -0,0 +1,31 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UploadController extends Controller
{
public function image(Request $request): JsonResponse
{
$request->validate([
'file' => 'required|image|max:10240',
]);
$path = $request->file('file')->store('covers', 'public');
return response()->json(['path' => $path]);
}
public function audio(Request $request): JsonResponse
{
$request->validate([
'file' => 'required|file|mimes:mp3,wav,flac,ogg,aac|max:51200',
]);
$path = $request->file('file')->store('tracks', 'public');
return response()->json(['path' => $path]);
}
}
@@ -0,0 +1,41 @@
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index(): JsonResponse
{
return response()->json(User::with('role')->get());
}
public function show(User $user): JsonResponse
{
return response()->json($user->load('role'));
}
public function update(Request $request, User $user): JsonResponse
{
$data = $request->validate([
'name' => 'sometimes|required|string|max:255',
'email' => 'sometimes|required|email|unique:users,email,' . $user->id,
'password' => 'sometimes|required|string|min:8|confirmed',
'role_id' => 'sometimes|required|exists:roles,id',
]);
$user->update($data);
return response()->json($user->load('role'));
}
public function destroy(User $user): JsonResponse
{
$user->delete();
return response()->json(null, 204);
}
}