chore: clean up and make code php8-y

This commit is contained in:
Phan An 2022-07-29 08:47:10 +02:00
parent 2ac7b43830
commit bfd1008f6c
No known key found for this signature in database
GPG key ID: A81E4477F0BB6FDC
118 changed files with 304 additions and 493 deletions

View file

@ -11,20 +11,16 @@ class ChangePasswordCommand extends Command
{
use AskForPassword;
protected $signature = "koel:admin:change-password
protected $signature = "koel:admin:change-password
{email? : The user's email. If empty, will get the default admin user.}";
protected $description = "Change a user's password";
private Hash $hash;
public function __construct(Hash $hash)
public function __construct(private Hash $hash)
{
parent::__construct();
$this->hash = $hash;
}
public function handle(): void
public function handle(): int
{
$email = $this->argument('email');
@ -34,7 +30,7 @@ class ChangePasswordCommand extends Command
if (!$user) {
$this->error('The user account cannot be found.');
return;
return self::FAILURE;
}
$this->comment("Changing the user's password (ID: $user->id, email: $user->email)");
@ -43,5 +39,7 @@ class ChangePasswordCommand extends Command
$user->save();
$this->comment('Alrighty, the new password has been saved. Enjoy! 👌');
return self::SUCCESS;
}
}

View file

@ -30,6 +30,6 @@ class ImportSearchableEntitiesCommand extends Command
$this->call('scout:import', ['model' => $entity]);
}
return 0;
return self::SUCCESS;
}
}

View file

@ -38,7 +38,7 @@ class InitCommand extends Command
parent::__construct();
}
public function handle(): void
public function handle(): int
{
$this->comment('Attempting to install or upgrade Koel.');
$this->comment('Remember, you can always install/upgrade manually following the guide here:');
@ -60,7 +60,7 @@ class InitCommand extends Command
$this->error('Please try again, or visit ' . config('koel.misc.docs_url') . ' for manual installation.');
$this->error('😥 Sorry for this. You deserve better.');
return;
return self::FAILURE;
}
$this->comment(PHP_EOL . '🎆 Success! Koel can now be run from localhost with `php artisan serve`.');
@ -76,12 +76,16 @@ class InitCommand extends Command
}
$this->comment('Again, visit 📙 ' . config('koel.misc.docs_url') . ' for the official documentation.');
$this->comment(
"Feeling generous and want to support Koel's development? Check out "
. config('koel.misc.sponsor_github_url')
. ' 🤗'
);
$this->comment('Thanks for using Koel. You rock! 🤘');
return self::SUCCESS;
}
/**

View file

@ -21,6 +21,6 @@ class PruneLibraryCommand extends Command
$this->info('Empty artists and albums removed.');
return Command::SUCCESS;
return self::SUCCESS;
}
}

View file

@ -40,7 +40,7 @@ class SyncCommand extends Command
$this->syncAll();
}
return Command::SUCCESS;
return self::SUCCESS;
}
/**

View file

@ -9,8 +9,10 @@ class TidyLibraryCommand extends Command
protected $signature = 'koel:tidy';
protected $hidden = true;
public function handle(): void
public function handle(): int
{
$this->warn('koel:tidy has been renamed. Use koel:prune instead.');
return self::SUCCESS;
}
}

View file

@ -9,10 +9,7 @@ class MediaSyncCompleted extends Event
{
use SerializesModels;
public SyncResult $result;
public function __construct(SyncResult $result)
public function __construct(public SyncResult $result)
{
$this->result = $result;
}
}

View file

@ -3,19 +3,13 @@
namespace App\Events;
use App\Models\Interaction;
use App\Models\User;
use Illuminate\Queue\SerializesModels;
class SongLikeToggled extends Event
{
use SerializesModels;
public Interaction $interaction;
public ?User $user = null;
public function __construct(Interaction $interaction, ?User $user = null)
public function __construct(public Interaction $interaction)
{
$this->interaction = $interaction;
$this->user = $user ?: auth()->user();
}
}

View file

@ -10,12 +10,7 @@ class SongStartedPlaying extends Event
{
use SerializesModels;
public Song $song;
public User $user;
public function __construct(Song $song, User $user)
public function __construct(public Song $song, public User $user)
{
$this->song = $song;
$this->user = $user;
}
}

View file

@ -10,12 +10,7 @@ class SongsBatchLiked extends Event
{
use SerializesModels;
public Collection $songs;
public User $user;
public function __construct(Collection $songs, User $user)
public function __construct(public Collection $songs, public User $user)
{
$this->songs = $songs;
$this->user = $user;
}
}

View file

@ -10,12 +10,7 @@ class SongsBatchUnliked extends Event
{
use SerializesModels;
public Collection $songs;
public User $user;
public function __construct(Collection $songs, User $user)
public function __construct(public Collection $songs, public User $user)
{
$this->songs = $songs;
$this->user = $user;
}
}

View file

@ -11,21 +11,12 @@ use App\Services\TranscodingService;
class StreamerFactory
{
private DirectStreamerInterface $directStreamer;
private TranscodingStreamerInterface $transcodingStreamer;
private ObjectStorageStreamerInterface $objectStorageStreamer;
private TranscodingService $transcodingService;
public function __construct(
DirectStreamerInterface $directStreamer,
TranscodingStreamerInterface $transcodingStreamer,
ObjectStorageStreamerInterface $objectStorageStreamer,
TranscodingService $transcodingService
private DirectStreamerInterface $directStreamer,
private TranscodingStreamerInterface $transcodingStreamer,
private ObjectStorageStreamerInterface $objectStorageStreamer,
private TranscodingService $transcodingService
) {
$this->directStreamer = $directStreamer;
$this->transcodingStreamer = $transcodingStreamer;
$this->objectStorageStreamer = $objectStorageStreamer;
$this->transcodingService = $transcodingService;
}
public function createStreamer(

View file

@ -3,6 +3,7 @@
namespace App\Http\Controllers\API;
use App\Events\LibraryChanged;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\AlbumCoverUpdateRequest;
use App\Models\Album;
use App\Services\MediaMetadataService;
@ -10,11 +11,8 @@ use Illuminate\Http\JsonResponse;
class AlbumCoverController extends Controller
{
private MediaMetadataService $mediaMetadataService;
public function __construct(MediaMetadataService $mediaMetadataService)
public function __construct(private MediaMetadataService $mediaMetadataService)
{
$this->mediaMetadataService = $mediaMetadataService;
}
public function update(AlbumCoverUpdateRequest $request, Album $album)

View file

@ -2,17 +2,15 @@
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Models\Album;
use App\Services\MediaMetadataService;
use Illuminate\Http\JsonResponse;
class AlbumThumbnailController extends Controller
{
private MediaMetadataService $mediaMetadataService;
public function __construct(MediaMetadataService $mediaMetadataService)
public function __construct(private MediaMetadataService $mediaMetadataService)
{
$this->mediaMetadataService = $mediaMetadataService;
}
public function show(Album $album): JsonResponse

View file

@ -3,6 +3,7 @@
namespace App\Http\Controllers\API;
use App\Events\LibraryChanged;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\ArtistImageUpdateRequest;
use App\Models\Artist;
use App\Services\MediaMetadataService;
@ -10,11 +11,8 @@ use Illuminate\Http\JsonResponse;
class ArtistImageController extends Controller
{
private MediaMetadataService $mediaMetadataService;
public function __construct(MediaMetadataService $mediaMetadataService)
public function __construct(private MediaMetadataService $mediaMetadataService)
{
$this->mediaMetadataService = $mediaMetadataService;
}
public function update(ArtistImageUpdateRequest $request, Artist $artist)

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\UserLoginRequest;
use App\Models\User;
use App\Repositories\UserRepository;
@ -15,23 +16,13 @@ class AuthController extends Controller
{
use ThrottlesLogins;
private UserRepository $userRepository;
private HashManager $hash;
private TokenManager $tokenManager;
/** @var User */
private ?Authenticatable $currentUser;
/** @param User $user */
public function __construct(
UserRepository $userRepository,
HashManager $hash,
TokenManager $tokenManager,
?Authenticatable $currentUser
private UserRepository $userRepository,
private HashManager $hash,
private TokenManager $tokenManager,
private ?Authenticatable $user
) {
$this->userRepository = $userRepository;
$this->hash = $hash;
$this->tokenManager = $tokenManager;
$this->currentUser = $currentUser;
}
public function login(UserLoginRequest $request)
@ -50,8 +41,8 @@ class AuthController extends Controller
public function logout()
{
if ($this->currentUser) {
$this->tokenManager->destroyTokens($this->currentUser);
if ($this->user) {
$this->tokenManager->destroyTokens($this->user);
}
return response()->noContent();

View file

@ -1,9 +0,0 @@
<?php
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller as BaseController;
abstract class Controller extends BaseController
{
}

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Repositories\InteractionRepository;
use App\Repositories\PlaylistRepository;
@ -18,41 +19,19 @@ class DataController extends Controller
{
private const RECENTLY_PLAYED_EXCERPT_COUNT = 7;
private LastfmService $lastfmService;
private YouTubeService $youTubeService;
private ITunesService $iTunesService;
private MediaCacheService $mediaCacheService;
private SettingRepository $settingRepository;
private PlaylistRepository $playlistRepository;
private InteractionRepository $interactionRepository;
private UserRepository $userRepository;
private ApplicationInformationService $applicationInformationService;
/** @var User */
private ?Authenticatable $currentUser;
/** @param User $currentUser */
public function __construct(
LastfmService $lastfmService,
YouTubeService $youTubeService,
ITunesService $iTunesService,
MediaCacheService $mediaCacheService,
SettingRepository $settingRepository,
PlaylistRepository $playlistRepository,
InteractionRepository $interactionRepository,
UserRepository $userRepository,
ApplicationInformationService $applicationInformationService,
?Authenticatable $currentUser
private LastfmService $lastfmService,
private YouTubeService $youTubeService,
private ITunesService $iTunesService,
private MediaCacheService $mediaCacheService,
private SettingRepository $settingRepository,
private PlaylistRepository $playlistRepository,
private InteractionRepository $interactionRepository,
private UserRepository $userRepository,
private ApplicationInformationService $applicationInformationService,
private ?Authenticatable $currentUser
) {
$this->lastfmService = $lastfmService;
$this->youTubeService = $youTubeService;
$this->iTunesService = $iTunesService;
$this->mediaCacheService = $mediaCacheService;
$this->settingRepository = $settingRepository;
$this->playlistRepository = $playlistRepository;
$this->interactionRepository = $interactionRepository;
$this->userRepository = $userRepository;
$this->applicationInformationService = $applicationInformationService;
$this->currentUser = $currentUser;
}
public function index()

View file

@ -2,10 +2,19 @@
namespace App\Http\Controllers\API\Interaction;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\BatchInteractionRequest;
use App\Models\User;
use App\Services\InteractionService;
use Illuminate\Contracts\Auth\Authenticatable;
class BatchLikeController extends Controller
{
/** @param User $user */
public function __construct(private InteractionService $interactionService, protected ?Authenticatable $user)
{
}
public function store(BatchInteractionRequest $request)
{
$interactions = $this->interactionService->batchLike((array) $request->songs, $this->user);

View file

@ -1,22 +0,0 @@
<?php
namespace App\Http\Controllers\API\Interaction;
use App\Http\Controllers\Controller as BaseController;
use App\Models\User;
use App\Services\InteractionService;
use Illuminate\Contracts\Auth\Authenticatable;
class Controller extends BaseController
{
protected InteractionService $interactionService;
/** @var User */
protected ?Authenticatable $user = null;
public function __construct(InteractionService $interactionService, ?Authenticatable $currentUser)
{
$this->interactionService = $interactionService;
$this->user = $currentUser;
}
}

View file

@ -2,10 +2,19 @@
namespace App\Http\Controllers\API\Interaction;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\SongLikeRequest;
use App\Models\User;
use App\Services\InteractionService;
use Illuminate\Contracts\Auth\Authenticatable;
class LikeController extends Controller
{
/** @param User $user */
public function __construct(private InteractionService $interactionService, private ?Authenticatable $user)
{
}
public function store(SongLikeRequest $request)
{
return response()->json($this->interactionService->toggleLike($request->song, $this->user));

View file

@ -3,10 +3,19 @@
namespace App\Http\Controllers\API\Interaction;
use App\Events\SongStartedPlaying;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\Interaction\StorePlayCountRequest;
use App\Models\User;
use App\Services\InteractionService;
use Illuminate\Contracts\Auth\Authenticatable;
class PlayCountController extends Controller
{
/** @param User $user */
public function __construct(private InteractionService $interactionService, private ?Authenticatable $user)
{
}
public function store(StorePlayCountRequest $request)
{
$interaction = $this->interactionService->increasePlayCount($request->song, $this->user);

View file

@ -2,20 +2,16 @@
namespace App\Http\Controllers\API\Interaction;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Repositories\InteractionRepository;
use App\Services\InteractionService;
use Illuminate\Contracts\Auth\Authenticatable;
class RecentlyPlayedController extends Controller
{
/** @param User $user */
public function __construct(
protected InteractionService $interactionService,
protected InteractionRepository $interactionRepository,
protected ?Authenticatable $user
) {
parent::__construct($interactionService, $user);
public function __construct(private InteractionRepository $interactionRepository, private ?Authenticatable $user)
{
}
public function index(?int $count = null)

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\LastfmSetSessionKeyRequest;
use App\Models\User;
use App\Services\LastfmService;
@ -9,20 +10,14 @@ use Illuminate\Contracts\Auth\Authenticatable;
class LastfmController extends Controller
{
private LastfmService $lastfm;
/** @var User */
private ?Authenticatable $currentUser;
public function __construct(LastfmService $lastfm, ?Authenticatable $currentUser)
/** @param User $currentUser */
public function __construct(private LastfmService $lastfm, private ?Authenticatable $currentUser)
{
$this->lastfm = $lastfm;
$this->currentUser = $currentUser;
}
public function setSessionKey(LastfmSetSessionKeyRequest $request)
{
$this->lastfm->setUserSessionKey($this->currentUser, trim($request->key));
$this->lastfm->setUserSessionKey($this->currentUser, $request->key);
return response()->noContent();
}

View file

@ -2,10 +2,16 @@
namespace App\Http\Controllers\API\MediaInformation;
use App\Http\Controllers\Controller;
use App\Models\Album;
use App\Services\MediaInformationService;
class AlbumController extends Controller
{
public function __construct(private MediaInformationService $mediaInformationService)
{
}
public function show(Album $album)
{
return response()->json($this->mediaInformationService->getAlbumInformation($album)?->toArray() ?: []);

View file

@ -2,10 +2,16 @@
namespace App\Http\Controllers\API\MediaInformation;
use App\Http\Controllers\Controller;
use App\Models\Artist;
use App\Services\MediaInformationService;
class ArtistController extends Controller
{
public function __construct(private MediaInformationService $mediaInformationService)
{
}
public function show(Artist $artist)
{
return response()->json($this->mediaInformationService->getArtistInformation($artist)?->toArray() ?: []);

View file

@ -1,16 +0,0 @@
<?php
namespace App\Http\Controllers\API\MediaInformation;
use App\Http\Controllers\API\Controller as BaseController;
use App\Services\MediaInformationService;
class Controller extends BaseController
{
protected MediaInformationService $mediaInformationService;
public function __construct(MediaInformationService $mediaInformationService)
{
$this->mediaInformationService = $mediaInformationService;
}
}

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\API\MediaInformation;
use App\Http\Controllers\Controller;
use App\Models\Song;
use App\Services\MediaInformationService;
use App\Services\YouTubeService;
@ -9,10 +10,9 @@ use App\Services\YouTubeService;
class SongController extends Controller
{
public function __construct(
protected MediaInformationService $mediaInformationService,
private MediaInformationService $mediaInformationService,
private YouTubeService $youTubeService
) {
parent::__construct($mediaInformationService);
}
public function show(Song $song)

View file

@ -1,9 +0,0 @@
<?php
namespace App\Http\Controllers\API\ObjectStorage;
use App\Http\Controllers\API\Controller as BaseController;
class Controller extends BaseController
{
}

View file

@ -1,9 +0,0 @@
<?php
namespace App\Http\Controllers\API\ObjectStorage\S3;
use App\Http\Controllers\API\ObjectStorage\Controller as BaseController;
class Controller extends BaseController
{
}

View file

@ -3,6 +3,7 @@
namespace App\Http\Controllers\API\ObjectStorage\S3;
use App\Exceptions\SongPathNotFoundException;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\ObjectStorage\S3\PutSongRequest;
use App\Http\Requests\API\ObjectStorage\S3\RemoveSongRequest;
use App\Services\S3Service;
@ -10,11 +11,8 @@ use Illuminate\Http\Response;
class SongController extends Controller
{
private S3Service $s3Service;
public function __construct(S3Service $s3Service)
public function __construct(private S3Service $s3Service)
{
$this->s3Service = $s3Service;
}
public function put(PutSongRequest $request)

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\PlaylistStoreRequest;
use App\Http\Requests\API\PlaylistUpdateRequest;
use App\Models\Playlist;
@ -12,20 +13,12 @@ use Illuminate\Contracts\Auth\Authenticatable;
class PlaylistController extends Controller
{
private PlaylistRepository $playlistRepository;
private PlaylistService $playlistService;
/** @var User */
private ?Authenticatable $currentUser;
/** @param User $user */
public function __construct(
PlaylistRepository $playlistRepository,
PlaylistService $playlistService,
?Authenticatable $currentUser
private PlaylistRepository $playlistRepository,
private PlaylistService $playlistService,
private ?Authenticatable $user
) {
$this->playlistRepository = $playlistRepository;
$this->playlistService = $playlistService;
$this->currentUser = $currentUser;
}
public function index()
@ -37,7 +30,7 @@ class PlaylistController extends Controller
{
$playlist = $this->playlistService->createPlaylist(
$request->name,
$this->currentUser,
$this->user,
(array) $request->songs,
$request->rules
);
@ -62,6 +55,6 @@ class PlaylistController extends Controller
$playlist->delete();
return response()->json();
return response()->noContent();
}
}

View file

@ -2,17 +2,18 @@
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\PlaylistSongUpdateRequest;
use App\Models\Playlist;
use App\Services\PlaylistService;
use App\Services\SmartPlaylistService;
class PlaylistSongController extends Controller
{
private SmartPlaylistService $smartPlaylistService;
public function __construct(SmartPlaylistService $smartPlaylistService)
{
$this->smartPlaylistService = $smartPlaylistService;
public function __construct(
private SmartPlaylistService $smartPlaylistService,
private PlaylistService $playlistService
) {
}
public function index(Playlist $playlist)
@ -26,14 +27,15 @@ class PlaylistSongController extends Controller
);
}
/** @deprecated */
public function update(PlaylistSongUpdateRequest $request, Playlist $playlist)
{
$this->authorize('owner', $playlist);
abort_if($playlist->is_smart, 403, 'A smart playlist\'s content cannot be updated manually.');
abort_if($playlist->is_smart, 403, 'A smart playlist cannot be populated manually.');
$playlist->songs()->sync((array) $request->songs);
$this->playlistService->populatePlaylist($playlist, (array) $request->songs);
return response()->json();
return response()->noContent();
}
}

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\ProfileUpdateRequest;
use App\Http\Resources\UserResource;
use App\Models\User;

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\ScrobbleStoreRequest;
use App\Jobs\ScrobbleJob;
use App\Models\Song;
@ -10,12 +11,9 @@ use Illuminate\Contracts\Auth\Authenticatable;
class ScrobbleController extends Controller
{
/** @var User */
private ?Authenticatable $currentUser;
public function __construct(?Authenticatable $currentUser)
/** @param User $currentUser */
public function __construct(private ?Authenticatable $currentUser)
{
$this->currentUser = $currentUser;
}
public function store(ScrobbleStoreRequest $request, Song $song)

View file

@ -2,31 +2,23 @@
namespace App\Http\Controllers\API\Search;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Services\SearchService;
use Illuminate\Http\Request;
use InvalidArgumentException;
class ExcerptSearchController extends Controller
{
private SearchService $searchService;
public function __construct(SearchService $searchService)
public function __construct(private SearchService $searchService)
{
$this->searchService = $searchService;
}
public function index(Request $request)
{
if (!$request->get('q')) {
throw new InvalidArgumentException('A search query is required.');
}
throw_unless((bool) $request->get('q'), new InvalidArgumentException('A search query is required.'));
$count = (int) $request->get('count', SearchService::DEFAULT_EXCERPT_RESULT_COUNT);
if ($count < 0) {
throw new InvalidArgumentException('Invalid count parameter.');
}
throw_if($count < 0, new InvalidArgumentException('Invalid count parameter.'));
return [
'results' => $this->searchService->excerptSearch($request->get('q'), $count),

View file

@ -2,25 +2,20 @@
namespace App\Http\Controllers\API\Search;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Services\SearchService;
use Illuminate\Http\Request;
use InvalidArgumentException;
class SongSearchController extends Controller
{
private SearchService $searchService;
public function __construct(SearchService $searchService)
public function __construct(private SearchService $searchService)
{
$this->searchService = $searchService;
}
public function index(Request $request)
{
if (!$request->get('q')) {
throw new InvalidArgumentException('A search query is required.');
}
throw_unless((bool) $request->get('q'), new InvalidArgumentException('A search query is required.'));
return [
'songs' => $this->searchService->searchSongs($request->get('q')),

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\SettingRequest;
use App\Models\Setting;
use App\Models\User;

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\SongUpdateRequest;
use App\Http\Resources\AlbumResource;
use App\Http\Resources\ArtistResource;

View file

@ -4,6 +4,7 @@ namespace App\Http\Controllers\API;
use App\Exceptions\MediaPathNotSetException;
use App\Exceptions\SongUploadFailedException;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\UploadRequest;
use App\Http\Resources\AlbumResource;
use App\Http\Resources\SongResource;

View file

@ -2,6 +2,7 @@
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\UserStoreRequest;
use App\Http\Requests\API\UserUpdateRequest;
use App\Http\Resources\UserResource;

View file

@ -2,17 +2,15 @@
namespace App\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\YouTubeSearchRequest;
use App\Models\Song;
use App\Services\YouTubeService;
class YouTubeController extends Controller
{
private YouTubeService $youTubeService;
public function __construct(YouTubeService $youTubeService)
public function __construct(private YouTubeService $youTubeService)
{
$this->youTubeService = $youTubeService;
}
public function searchVideosRelatedToSong(YouTubeSearchRequest $request, Song $song)

View file

@ -2,10 +2,16 @@
namespace App\Http\Controllers\Download;
use App\Http\Controllers\Controller;
use App\Models\Album;
use App\Services\DownloadService;
class AlbumController extends Controller
{
public function __construct(private DownloadService $downloadService)
{
}
public function show(Album $album)
{
return response()->download($this->downloadService->from($album));

View file

@ -2,10 +2,16 @@
namespace App\Http\Controllers\Download;
use App\Http\Controllers\Controller;
use App\Models\Artist;
use App\Services\DownloadService;
class ArtistController extends Controller
{
public function __construct(private DownloadService $downloadService)
{
}
public function show(Artist $artist)
{
return response()->download($this->downloadService->from($artist));

View file

@ -1,16 +0,0 @@
<?php
namespace App\Http\Controllers\Download;
use App\Http\Controllers\API\Controller as BaseController;
use App\Services\DownloadService;
abstract class Controller extends BaseController
{
protected DownloadService $downloadService;
public function __construct(DownloadService $downloadService)
{
$this->downloadService = $downloadService;
}
}

View file

@ -2,24 +2,25 @@
namespace App\Http\Controllers\Download;
use App\Http\Requests\Download\Request;
use App\Http\Controllers\Controller;
use App\Models\User;
use App\Repositories\InteractionRepository;
use App\Services\DownloadService;
use Illuminate\Contracts\Auth\Authenticatable;
class FavoritesController extends Controller
{
private InteractionRepository $interactionRepository;
public function __construct(DownloadService $downloadService, InteractionRepository $interactionRepository)
{
parent::__construct($downloadService);
$this->interactionRepository = $interactionRepository;
/** @param User $user */
public function __construct(
private DownloadService $downloadService,
private InteractionRepository $interactionRepository,
private ?Authenticatable $user
) {
}
public function show(Request $request)
public function show()
{
$songs = $this->interactionRepository->getUserFavorites($request->user());
$songs = $this->interactionRepository->getUserFavorites($this->user);
return response()->download($this->downloadService->from($songs));
}

View file

@ -2,10 +2,16 @@
namespace App\Http\Controllers\Download;
use App\Http\Controllers\Controller;
use App\Models\Playlist;
use App\Services\DownloadService;
class PlaylistController extends Controller
{
public function __construct(private DownloadService $downloadService)
{
}
public function show(Playlist $playlist)
{
$this->authorize('owner', $playlist);

View file

@ -2,19 +2,15 @@
namespace App\Http\Controllers\Download;
use App\Http\Controllers\Controller;
use App\Http\Requests\Download\SongRequest;
use App\Repositories\SongRepository;
use App\Services\DownloadService;
class SongController extends Controller
{
private SongRepository $songRepository;
public function __construct(DownloadService $downloadService, SongRepository $songRepository)
public function __construct(private DownloadService $downloadService, private SongRepository $songRepository)
{
parent::__construct($downloadService);
$this->songRepository = $songRepository;
}
public function show(SongRequest $request)

View file

@ -10,13 +10,8 @@ use Illuminate\Http\Response;
class ITunesController extends Controller
{
private ITunesService $iTunesService;
private TokenManager $tokenManager;
public function __construct(ITunesService $iTunesService, TokenManager $tokenManager)
public function __construct(private ITunesService $iTunesService, private TokenManager $tokenManager)
{
$this->iTunesService = $iTunesService;
$this->tokenManager = $tokenManager;
}
public function viewSong(ViewSongOnITunesRequest $request, Album $album)

View file

@ -11,17 +11,12 @@ use Illuminate\Http\Response;
class LastfmController extends Controller
{
private LastfmService $lastfm;
private TokenManager $tokenManager;
/** @var User */
private ?Authenticatable $currentUser;
public function __construct(LastfmService $lastfm, TokenManager $tokenManager, ?Authenticatable $currentUser)
{
$this->lastfm = $lastfm;
$this->tokenManager = $tokenManager;
$this->currentUser = $currentUser;
/** @param User $currentUser */
public function __construct(
private LastfmService $lastfm,
private TokenManager $tokenManager,
private ?Authenticatable $currentUser
) {
}
public function connect()

View file

@ -8,17 +8,14 @@ use App\Models\Song;
class PlayController extends Controller
{
private StreamerFactory $streamerFactory;
public function __construct(StreamerFactory $streamerFactory)
public function __construct(private StreamerFactory $streamerFactory)
{
$this->streamerFactory = $streamerFactory;
}
public function show(SongPlayRequest $request, Song $song, ?bool $transcode = null, ?int $bitRate = null)
{
return $this->streamerFactory
->createStreamer($song, $transcode, $bitRate, floatval($request->time))
->createStreamer($song, $transcode, $bitRate, (float) $request->time)
->stream();
}
}

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Http\Resources\AlbumResource;
use App\Models\Album;
use App\Models\User;

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Http\Resources\SongResource;
use App\Models\Album;
use App\Models\User;

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Http\Resources\ArtistResource;
use App\Models\Artist;
use App\Models\User;

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Http\Resources\SongResource;
use App\Models\Artist;
use App\Models\User;

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Http\Resources\UserResource;
use App\Models\User;
use App\Repositories\PlaylistRepository;

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Http\Controllers\V6\Requests\SearchRequest;
use App\Http\Resources\ExcerptSearchResource;
use App\Models\User;

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Http\Resources\SongResource;
use App\Models\User;
use App\Repositories\SongRepository;

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Models\Album;
use App\Services\MediaInformationService;

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Models\Artist;
use App\Services\MediaInformationService;

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Http\Resources\AlbumResource;
use App\Http\Resources\ArtistResource;
use App\Http\Resources\SongResource;

View file

@ -3,12 +3,20 @@
namespace App\Http\Controllers\V6\API;
use App\Events\SongStartedPlaying;
use App\Http\Controllers\API\Interaction\Controller;
use App\Http\Controllers\Controller;
use App\Http\Requests\API\Interaction\StorePlayCountRequest;
use App\Http\Resources\InteractionResource;
use App\Models\User;
use App\Services\InteractionService;
use Illuminate\Contracts\Auth\Authenticatable;
class PlayCountController extends Controller
{
/** @param User $user */
public function __construct(private InteractionService $interactionService, private ?Authenticatable $user)
{
}
public function store(StorePlayCountRequest $request)
{
$interaction = $this->interactionService->increasePlayCount($request->song, $this->user);

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Http\Controllers\V6\Requests\AddSongsToPlaylistRequest;
use App\Http\Controllers\V6\Requests\RemoveSongsFromPlaylistRequest;
use App\Http\Resources\SongResource;

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Http\Controllers\V6\Requests\QueueFetchSongRequest;
use App\Http\Resources\SongResource;
use App\Models\User;

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Http\Resources\SongResource;
use App\Models\User;
use App\Repositories\SongRepository;

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Http\Controllers\V6\Requests\SongListRequest;
use App\Http\Resources\SongResource;
use App\Models\Song;

View file

@ -2,7 +2,7 @@
namespace App\Http\Controllers\V6\API;
use App\Http\Controllers\API\Controller;
use App\Http\Controllers\Controller;
use App\Http\Controllers\V6\Requests\SearchRequest;
use App\Http\Resources\SongResource;
use App\Models\User;

View file

@ -8,11 +8,8 @@ use Illuminate\Http\Request;
class Authenticate
{
protected Guard $auth;
public function __construct(Guard $auth)
public function __construct(protected Guard $auth)
{
$this->auth = $auth;
}
public function handle(Request $request, Closure $next) // @phpcs:ignore

View file

@ -8,11 +8,8 @@ use Illuminate\Routing\UrlGenerator;
class ForceHttps
{
private UrlGenerator $url;
public function __construct(UrlGenerator $url)
public function __construct(private UrlGenerator $url)
{
$this->url = $url;
}
public function handle(Request $request, Closure $next) // @phpcs:ignore

View file

@ -4,6 +4,7 @@ namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Http\Response;
/**
* Authenticate requests from Object Storage services (like S3).
@ -13,9 +14,7 @@ class ObjectStorageAuthenticate
{
public function handle(Request $request, Closure $next) // @phpcs:ignore
{
if ($request->appKey !== config('app.key')) {
return response('Unauthorized.', 401);
}
abort_unless($request->get('appKey') === config('app.key'), Response::HTTP_UNAUTHORIZED);
return $next($request);
}

View file

@ -3,7 +3,7 @@
namespace App\Http\Requests\API;
/** @property string $cover */
class AlbumCoverUpdateRequest extends AbstractMediaImageUpdateRequest
class AlbumCoverUpdateRequest extends MediaImageUpdateRequest
{
protected function getImageFieldName(): string
{

View file

@ -3,7 +3,7 @@
namespace App\Http\Requests\API;
/** @property string $image */
class ArtistImageUpdateRequest extends AbstractMediaImageUpdateRequest
class ArtistImageUpdateRequest extends MediaImageUpdateRequest
{
protected function getImageFieldName(): string
{

View file

@ -4,6 +4,6 @@ namespace App\Http\Requests\API\Interaction;
use App\Http\Requests\API\Request as BaseRequest;
class Request extends BaseRequest
abstract class Request extends BaseRequest
{
}

View file

@ -4,7 +4,7 @@ namespace App\Http\Requests\API;
use App\Rules\ImageData;
abstract class AbstractMediaImageUpdateRequest extends Request
abstract class MediaImageUpdateRequest extends Request
{
public function authorize(): bool
{

View file

@ -2,8 +2,8 @@
namespace App\Http\Requests\API;
use App\Http\Requests\AbstractRequest;
use App\Http\Requests\Request as BaseRequest;
class Request extends AbstractRequest
abstract class Request extends BaseRequest
{
}

View file

@ -2,11 +2,11 @@
namespace App\Http\Requests\API;
use App\Http\Requests\AbstractRequest;
use App\Http\Requests\Request;
use Illuminate\Http\UploadedFile;
/** @property UploadedFile $file */
class UploadRequest extends AbstractRequest
class UploadRequest extends Request
{
/** @return array<mixed> */
public function rules(): array

View file

@ -4,7 +4,7 @@ namespace App\Http\Requests\Download;
use App\Http\Requests\API\Request as BaseRequest;
class Request extends BaseRequest
abstract class Request extends BaseRequest
{
public function authorize(): bool
{

View file

@ -4,7 +4,7 @@ namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
abstract class AbstractRequest extends FormRequest
abstract class Request extends FormRequest
{
public function authorize(): bool
{

View file

@ -3,9 +3,9 @@
namespace App\Http\Requests;
/**
* @property float $time
* @property float|string $time
* @property string $api_token
*/
class SongPlayRequest extends AbstractRequest
class SongPlayRequest extends Request
{
}

View file

@ -6,6 +6,6 @@ namespace App\Http\Requests;
* @property-read string $state
* @property-read string $code
*/
class SpotifyCallbackRequest extends AbstractRequest
class SpotifyCallbackRequest extends Request
{
}

View file

@ -9,18 +9,15 @@ use Illuminate\Contracts\Queue\ShouldQueue;
class LoveTrackOnLastfm implements ShouldQueue
{
private LastfmService $lastfm;
public function __construct(LastfmService $lastfm)
public function __construct(private LastfmService $lastfm)
{
$this->lastfm = $lastfm;
}
public function handle(SongLikeToggled $event): void
{
if (
!$this->lastfm->enabled() ||
!$event->user->lastfm_session_key ||
!$event->interaction->user->lastfm_session_key ||
$event->interaction->song->artist->is_unknown
) {
return;
@ -28,7 +25,7 @@ class LoveTrackOnLastfm implements ShouldQueue
$this->lastfm->toggleLoveTrack(
LastfmLoveTrackParameters::make($event->interaction->song->title, $event->interaction->song->artist->name),
$event->user->lastfm_session_key,
$event->interaction->user->lastfm_session_key,
$event->interaction->liked
);
}

View file

@ -17,16 +17,11 @@ class StreamerServiceProvider extends ServiceProvider
public function register(): void
{
$this->app->bind(DirectStreamerInterface::class, static function (): DirectStreamerInterface {
switch (config('koel.streaming.method')) {
case 'x-sendfile':
return new XSendFileStreamer();
case 'x-accel-redirect':
return new XAccelRedirectStreamer();
default:
return new PhpStreamer();
}
return match (config('koel.streaming.method')) {
'x-sendfile' => new XSendFileStreamer(),
'x-accel-redirect' => new XAccelRedirectStreamer(),
default => new PhpStreamer(),
};
});
$this->app->bind(TranscodingStreamerInterface::class, TranscodingStreamer::class);

View file

@ -7,7 +7,7 @@ use App\Models\User;
use App\Repositories\Traits\Searchable;
use Illuminate\Support\Collection;
class AlbumRepository extends AbstractRepository
class AlbumRepository extends Repository
{
use Searchable;

View file

@ -7,7 +7,7 @@ use App\Models\User;
use App\Repositories\Traits\Searchable;
use Illuminate\Database\Eloquent\Collection;
class ArtistRepository extends AbstractRepository
class ArtistRepository extends Repository
{
use Searchable;

View file

@ -8,7 +8,7 @@ use App\Repositories\Traits\ByCurrentUser;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Collection;
class InteractionRepository extends AbstractRepository
class InteractionRepository extends Repository
{
use ByCurrentUser;

View file

@ -6,7 +6,7 @@ use App\Models\Playlist;
use App\Repositories\Traits\ByCurrentUser;
use Illuminate\Support\Collection;
class PlaylistRepository extends AbstractRepository
class PlaylistRepository extends Repository
{
use ByCurrentUser;

View file

@ -7,7 +7,7 @@ use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use Throwable;
abstract class AbstractRepository implements RepositoryInterface
abstract class Repository implements RepositoryInterface
{
private string $modelClass;
protected Model $model;

View file

@ -4,7 +4,7 @@ namespace App\Repositories;
use App\Models\Setting;
class SettingRepository extends AbstractRepository
class SettingRepository extends Repository
{
/** @return array<mixed> */
public function getAllAsKeyValueArray(): array

View file

@ -14,7 +14,7 @@ use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Support\Collection;
use Webmozart\Assert\Assert;
class SongRepository extends AbstractRepository
class SongRepository extends Repository
{
use Searchable;

View file

@ -2,6 +2,6 @@
namespace App\Repositories;
class UserRepository extends AbstractRepository
class UserRepository extends Repository
{
}

View file

@ -26,7 +26,7 @@ use Webmozart\Assert\Assert;
* @method Promise headAsync($uri, array $data = [], bool $appendKey = true)
* @method Promise deleteAsync($uri, array $data = [], bool $appendKey = true)
*/
abstract class AbstractApiClient
abstract class ApiClient
{
private const MAGIC_METHODS = [
'get',

View file

@ -11,15 +11,8 @@ class ApplicationInformationService
{
private const CACHE_KEY = 'latestKoelVersion';
private Client $client;
private Cache $cache;
private Logger $logger;
public function __construct(Client $client, Cache $cache, Logger $logger)
public function __construct(private Client $client, private Cache $cache, private Logger $logger)
{
$this->client = $client;
$this->cache = $cache;
$this->logger = $logger;
}
/**

View file

@ -13,40 +13,33 @@ use InvalidArgumentException;
class DownloadService
{
private S3Service $s3Service;
public function __construct(S3Service $s3Service)
public function __construct(private S3Service $s3Service)
{
$this->s3Service = $s3Service;
}
/**
* Generic method to generate a download archive from various source types.
*
* @param Song|Collection|Album|Artist|Playlist $mixed
*
* @throws InvalidArgumentException
*
* @return string Full path to the generated archive
*/
public function from($mixed): string
public function from(Playlist|Song|Album|Artist|Collection $downloadable): string
{
switch (get_class($mixed)) {
switch (get_class($downloadable)) {
case Song::class:
return $this->fromSong($mixed);
return $this->fromSong($downloadable);
case Collection::class:
case EloquentCollection::class:
return $this->fromMultipleSongs($mixed);
return $this->fromMultipleSongs($downloadable);
case Album::class:
return $this->fromAlbum($mixed);
return $this->fromAlbum($downloadable);
case Artist::class:
return $this->fromArtist($mixed);
return $this->fromArtist($downloadable);
case Playlist::class:
return $this->fromPlaylist($mixed);
return $this->fromPlaylist($downloadable);
}
throw new InvalidArgumentException('Unsupported download type.');

View file

@ -4,7 +4,7 @@ namespace App\Services;
use Throwable;
class ITunesService extends AbstractApiClient implements ApiConsumerInterface
class ITunesService extends ApiClient implements ApiConsumerInterface
{
/**
* Determines whether to use iTunes services.

View file

@ -33,7 +33,7 @@ class InteractionService
}
/**
* Like or unlike a song on behalf of a user.
* Like or unlike a song as a user.
*
* @return Interaction the affected Interaction object
*/

View file

@ -13,7 +13,7 @@ use GuzzleHttp\Promise\Utils;
use Illuminate\Support\Collection;
use Throwable;
class LastfmService extends AbstractApiClient implements ApiConsumerInterface
class LastfmService extends ApiClient implements ApiConsumerInterface
{
/**
* Override the key param, since, again, Last.fm wants to be different.
@ -143,8 +143,8 @@ class LastfmService extends AbstractApiClient implements ApiConsumerInterface
{
try {
$this->post('/', $this->buildAuthCallParams([
'track' => $params->getTrackName(),
'artist' => $params->getArtistName(),
'track' => $params->trackName,
'artist' => $params->artistName,
'sk' => $sessionKey,
'method' => $love ? 'track.love' : 'track.unlove',
]), false);
@ -160,8 +160,8 @@ class LastfmService extends AbstractApiClient implements ApiConsumerInterface
{
$promises = $parameterCollection->map(
fn (LastfmLoveTrackParameters $params): Promise => $this->postAsync('/', $this->buildAuthCallParams([
'track' => $params->getTrackName(),
'artist' => $params->getArtistName(),
'track' => $params->trackName,
'artist' => $params->artistName,
'sk' => $sessionKey,
'method' => $love ? 'track.love' : 'track.unlove',
]), false)

View file

@ -11,11 +11,8 @@ class MediaCacheService
{
private const CACHE_KEY = 'media_cache';
private Cache $cache;
public function __construct(Cache $cache)
public function __construct(private Cache $cache)
{
$this->cache = $cache;
}
/**

View file

@ -31,4 +31,10 @@ class PlaylistService
{
$playlist->songs()->detach($songIds);
}
/** @deprecated */
public function populatePlaylist(Playlist $playlist, array $songIds): void
{
$playlist->songs()->sync($songIds);
}
}

View file

@ -16,18 +16,11 @@ class SearchService
{
public const DEFAULT_EXCERPT_RESULT_COUNT = 6;
private SongRepository $songRepository;
private AlbumRepository $albumRepository;
private ArtistRepository $artistRepository;
public function __construct(
SongRepository $songRepository,
AlbumRepository $albumRepository,
ArtistRepository $artistRepository
private SongRepository $songRepository,
private AlbumRepository $albumRepository,
private ArtistRepository $artistRepository
) {
$this->songRepository = $songRepository;
$this->albumRepository = $albumRepository;
$this->artistRepository = $artistRepository;
}
/** @return array<mixed> */

View file

@ -26,11 +26,9 @@ class SongService
/** @var Song|null $song */
$song = Song::with('album', 'album.artist', 'artist')->find($id);
if (!$song) {
continue;
if ($song) {
$updatedSongs->push($this->updateSong($song, $data));
}
$updatedSongs->push($this->updateSong($song, $data));
}
});

Some files were not shown because too many files have changed in this diff Show more