Skip to content

Commit 6f3ffae

Browse files
committed
add: playlist categories
1 parent e9acd76 commit 6f3ffae

17 files changed

+611
-3
lines changed

app/Http/Controllers/PlaylistController.php

+8-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use App\Http\Requests\UpdatePlaylistRequest;
2121
use App\Models\TmdbMovie;
2222
use App\Models\Playlist;
23+
use App\Models\PlaylistCategory;
2324
use App\Models\TmdbTv;
2425
use App\Repositories\ChatRepository;
2526
use App\Traits\TorrentMeta;
@@ -55,7 +56,9 @@ public function index(): \Illuminate\Contracts\View\Factory|\Illuminate\View\Vie
5556
*/
5657
public function create(): \Illuminate\Contracts\View\Factory|\Illuminate\View\View
5758
{
58-
return view('playlist.create');
59+
return view('playlist.create', [
60+
'playlistCategories' => PlaylistCategory::query()->orderBy('position')->get(),
61+
]);
5962
}
6063

6164
/**
@@ -136,7 +139,10 @@ public function edit(Request $request, Playlist $playlist): \Illuminate\Contract
136139
{
137140
abort_unless($request->user()->id === $playlist->user_id || $request->user()->group->is_modo, 403);
138141

139-
return view('playlist.edit', ['playlist' => $playlist]);
142+
return view('playlist.edit', [
143+
'playlist' => $playlist,
144+
'playlistCategories' => PlaylistCategory::query()->orderBy('position')->get(),
145+
]);
140146
}
141147

142148
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* NOTICE OF LICENSE.
7+
*
8+
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
9+
* The details is bundled with this project in the file LICENSE.txt.
10+
*
11+
* @project UNIT3D Community Edition
12+
*
13+
* @author Roardom <roardom@protonmail.com>
14+
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
15+
*/
16+
17+
namespace App\Http\Controllers\Staff;
18+
19+
use App\Http\Controllers\Controller;
20+
use App\Http\Requests\Staff\StorePlaylistCategoryRequest;
21+
use App\Http\Requests\Staff\UpdatePlaylistCategoryRequest;
22+
use App\Models\Category;
23+
use App\Models\PlaylistCategory;
24+
use Exception;
25+
26+
class PlaylistCategoryController extends Controller
27+
{
28+
/**
29+
* Display all playlist categories.
30+
*/
31+
public function index(): \Illuminate\Contracts\View\Factory|\Illuminate\View\View
32+
{
33+
return view('Staff.playlist-category.index', [
34+
'playlistCategories' => PlaylistCategory::query()->orderBy('position')->get(),
35+
]);
36+
}
37+
38+
/**
39+
* Show form for creating a new category.
40+
*/
41+
public function create(): \Illuminate\Contracts\View\Factory|\Illuminate\View\View
42+
{
43+
return view('Staff.playlist-category.create');
44+
}
45+
46+
/**
47+
* Store a category.
48+
*/
49+
public function store(StorePlaylistCategoryRequest $request): \Illuminate\Http\RedirectResponse
50+
{
51+
PlaylistCategory::create($request->validated());
52+
53+
return to_route('staff.playlist_categories.index');
54+
}
55+
56+
/**
57+
* Playlist category edit form.
58+
*/
59+
public function edit(PlaylistCategory $playlistCategory): \Illuminate\Contracts\View\Factory|\Illuminate\View\View
60+
{
61+
return view('Staff.playlist-category.edit', [
62+
'playlistCategory' => $playlistCategory,
63+
]);
64+
}
65+
66+
/**
67+
* Update a playlist category.
68+
*/
69+
public function update(UpdatePlaylistCategoryRequest $request, PlaylistCategory $playlistCategory): \Illuminate\Http\RedirectResponse
70+
{
71+
$playlistCategory->update($request->validated());
72+
73+
return to_route('staff.playlist_categories.index');
74+
}
75+
76+
/**
77+
* Destroy a category.
78+
*
79+
* @throws Exception
80+
*/
81+
public function destroy(PlaylistCategory $playlistCategory): \Illuminate\Http\RedirectResponse
82+
{
83+
if ($playlistCategory->playlists()->exists()) {
84+
return to_route('staff.playlist_categories.index')
85+
->withErrors('Can\'t delete playlist category that still contains playlists');
86+
}
87+
88+
$playlistCategory->delete();
89+
90+
return to_route('staff.playlist_categories.index');
91+
}
92+
}

app/Http/Livewire/PlaylistSearch.php

+16-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
namespace App\Http\Livewire;
1818

1919
use App\Models\Playlist;
20+
use App\Models\PlaylistCategory;
2021
use App\Traits\LivewireSort;
2122
use Livewire\Attributes\Computed;
2223
use Livewire\Attributes\Url;
@@ -42,6 +43,9 @@ class PlaylistSearch extends Component
4243
#[Url(history: true)]
4344
public string $username = '';
4445

46+
#[Url(history: true)]
47+
public string $playlistCategoryId = "__any";
48+
4549
#[Url(history: true)]
4650
public string $sortDirection = 'asc';
4751

@@ -71,14 +75,25 @@ final public function playlists()
7175
)
7276
->when($this->name !== '', fn ($query) => $query->where('name', 'LIKE', '%'.str_replace(' ', '%', $this->name).'%'))
7377
->when($this->username !== '', fn ($query) => $query->whereRelation('user', 'username', 'LIKE', '%'.$this->username.'%'))
78+
->when($this->playlistCategoryId !== "__any", fn ($query) => $query->where('playlist_category_id', '=', $this->playlistCategoryId))
7479
->orderBy($this->sortField, $this->sortDirection)
7580
->paginate(min($this->perPage, 100));
7681
}
7782

83+
/**
84+
* @return \Illuminate\Database\Eloquent\Collection<int, PlaylistCategory>
85+
*/
86+
#[Computed(seconds: 3600, cache: true)]
87+
final public function playlistCategories(): \Illuminate\Database\Eloquent\Collection
88+
{
89+
return PlaylistCategory::query()->orderBy('position')->get();
90+
}
91+
7892
final public function render(): \Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Contracts\Foundation\Application
7993
{
8094
return view('livewire.playlist-search', [
81-
'playlists' => $this->playlists,
95+
'playlists' => $this->playlists,
96+
'playlistCategories' => $this->playlistCategories,
8297
]);
8398
}
8499
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* NOTICE OF LICENSE.
7+
*
8+
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
9+
* The details is bundled with this project in the file LICENSE.txt.
10+
*
11+
* @project UNIT3D Community Edition
12+
*
13+
* @author Roardom <roardom@protonmail.com>
14+
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
15+
*/
16+
17+
namespace App\Http\Requests\Staff;
18+
19+
use Illuminate\Foundation\Http\FormRequest;
20+
21+
class StorePlaylistCategoryRequest extends FormRequest
22+
{
23+
/**
24+
* Get the validation rules that apply to the request.
25+
*
26+
* @return array<string, list<string>>
27+
*/
28+
public function rules(): array
29+
{
30+
return [
31+
'name' => [
32+
'required',
33+
'string',
34+
],
35+
'position' => [
36+
'required',
37+
'numeric',
38+
'decimal:0',
39+
],
40+
];
41+
}
42+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* NOTICE OF LICENSE.
7+
*
8+
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
9+
* The details is bundled with this project in the file LICENSE.txt.
10+
*
11+
* @project UNIT3D Community Edition
12+
*
13+
* @author Roardom <roardom@protonmail.com>
14+
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
15+
*/
16+
17+
namespace App\Http\Requests\Staff;
18+
19+
use Illuminate\Foundation\Http\FormRequest;
20+
21+
class UpdatePlaylistCategoryRequest extends FormRequest
22+
{
23+
/**
24+
* Get the validation rules that apply to the request.
25+
*
26+
* @return array<string, list<string>>
27+
*/
28+
public function rules(): array
29+
{
30+
return [
31+
'name' => [
32+
'required',
33+
'string',
34+
],
35+
'position' => [
36+
'required',
37+
'numeric',
38+
'decimal:0',
39+
],
40+
];
41+
}
42+
}

app/Http/Requests/StorePlaylistRequest.php

+4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ public function rules(): array
4343
'required',
4444
'max:255',
4545
],
46+
'playlist_category_id' => [
47+
'required',
48+
'exists:playlist_categories,id',
49+
],
4650
'description' => [
4751
'required',
4852
'max:65535',

app/Http/Requests/UpdatePlaylistRequest.php

+4
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ public function rules(): array
4343
'required',
4444
'max:255',
4545
],
46+
'playlist_category_id' => [
47+
'required',
48+
'exists:playlist_categories,id',
49+
],
4650
'description' => [
4751
'required',
4852
'max:65536',

app/Models/PlaylistCategory.php

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* NOTICE OF LICENSE.
7+
*
8+
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
9+
* The details is bundled with this project in the file LICENSE.txt.
10+
*
11+
* @project UNIT3D Community Edition
12+
*
13+
* @author Roardom <roardom@protonmail.com>
14+
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
15+
*/
16+
17+
namespace App\Models;
18+
19+
use App\Traits\Auditable;
20+
use Illuminate\Database\Eloquent\Model;
21+
22+
/**
23+
* App\Models\PlaylistCategory.
24+
*
25+
* @property int $id
26+
* @property string $name
27+
* @property int $position
28+
*/
29+
class PlaylistCategory extends Model
30+
{
31+
use Auditable;
32+
33+
/**
34+
* Indicates if the model should be timestamped.
35+
*
36+
* @var bool
37+
*/
38+
public $timestamps = false;
39+
40+
/**
41+
* The attributes that aren't mass assignable.
42+
*
43+
* @var list<string>
44+
*/
45+
protected $guarded = [];
46+
47+
/**
48+
* Has many playlists.
49+
*
50+
* @return \Illuminate\Database\Eloquent\Relations\HasMany<Playlist, $this>
51+
*/
52+
public function playlists(): \Illuminate\Database\Eloquent\Relations\HasMany
53+
{
54+
return $this->hasMany(Playlist::class);
55+
}
56+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/**
6+
* NOTICE OF LICENSE.
7+
*
8+
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
9+
* The details is bundled with this project in the file LICENSE.txt.
10+
*
11+
* @project UNIT3D Community Edition
12+
*
13+
* @author Roardom <roardom@protonmail.com>
14+
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
15+
*/
16+
17+
use Illuminate\Database\Migrations\Migration;
18+
use Illuminate\Database\Schema\Blueprint;
19+
use Illuminate\Support\Facades\DB;
20+
use Illuminate\Support\Facades\Schema;
21+
22+
return new class () extends Migration {
23+
/**
24+
* Run the migrations.
25+
*/
26+
public function up(): void
27+
{
28+
Schema::create('playlist_categories', function (Blueprint $table): void {
29+
$table->increments('id');
30+
$table->smallInteger('position');
31+
$table->string('name');
32+
});
33+
34+
DB::table('playlist_categories')->insert([
35+
'id' => 1,
36+
'position' => 100,
37+
'name' => 'Other',
38+
]);
39+
40+
Schema::table('playlists', function (Blueprint $table): void {
41+
// Add the default 1 to migrate all existing playlists to the newly created
42+
// "Other" category, and then remove the default so that sysops can delete
43+
// the "Other" category if they want (and it contains no playlists).
44+
$table->unsignedInteger('playlist_category_id')->after('id')->default(1);
45+
$table->unsignedInteger('playlist_category_id')->change();
46+
47+
$table->foreign('playlist_category_id')->references('id')->on('playlist_categories');
48+
});
49+
}
50+
};

0 commit comments

Comments
 (0)