chore: make properties readonly

This commit is contained in:
Phan An 2024-04-18 16:36:28 +02:00
parent f5677a5b2f
commit 67186e8d3e
92 changed files with 180 additions and 335 deletions

View file

@ -11,7 +11,7 @@ class ActivateLicenseCommand extends Command
protected $signature = 'koel:license:activate {key : The license key to activate.}';
protected $description = 'Activate a Koel Plus license';
public function __construct(private LicenseServiceInterface $licenseService)
public function __construct(private readonly LicenseServiceInterface $licenseService)
{
parent::__construct();
}

View file

@ -15,7 +15,7 @@ class ChangePasswordCommand extends Command
{email? : The user's email. If empty, will get the default admin user.}";
protected $description = "Change a user's password";
public function __construct(private Hash $hash, private UserRepository $userRepository)
public function __construct(private readonly Hash $hash, private readonly UserRepository $userRepository)
{
parent::__construct();
}

View file

@ -12,7 +12,7 @@ class CheckLicenseStatusCommand extends Command
protected $signature = 'koel:license:status';
protected $description = 'Check the current Koel Plus license status';
public function __construct(private LicenseServiceInterface $licenseService)
public function __construct(private readonly LicenseServiceInterface $licenseService)
{
parent::__construct();
}

View file

@ -11,14 +11,14 @@ class DeactivateLicenseCommand extends Command
protected $signature = 'koel:license:deactivate';
protected $description = 'Deactivate the currently active Koel Plus license';
public function __construct(private LicenseServiceInterface $plusService)
public function __construct(private readonly LicenseServiceInterface $licenseService)
{
parent::__construct();
}
public function handle(): int
{
$status = $this->plusService->getStatus();
$status = $this->licenseService->getStatus();
if ($status->hasNoLicense()) {
$this->components->warn('No active Plus license found.');
@ -35,7 +35,7 @@ class DeactivateLicenseCommand extends Command
$this->components->info('Deactivating your license…');
try {
$this->plusService->deactivate($status->license);
$this->licenseService->deactivate($status->license);
$this->components->info('Koel Plus has been deactivated. Plus features are now disabled.');
return self::SUCCESS;

View file

@ -32,10 +32,10 @@ class InitCommand extends Command
private bool $adminSeeded = false;
public function __construct(
private Hash $hash,
private DotenvEditor $dotenvEditor,
private DB $db,
private LoggerInterface $logger
private readonly Hash $hash,
private readonly DotenvEditor $dotenvEditor,
private readonly DB $db,
private readonly LoggerInterface $logger
) {
parent::__construct();
}

View file

@ -10,7 +10,7 @@ class PruneLibraryCommand extends Command
protected $signature = 'koel:prune';
protected $description = 'Remove empty artists and albums';
public function __construct(private LibraryManager $libraryManager)
public function __construct(private readonly LibraryManager $libraryManager)
{
parent::__construct();
}

View file

@ -30,15 +30,17 @@ class ScanCommand extends Command
private ?string $mediaPath;
private ProgressBar $progressBar;
public function __construct(private MediaScanner $mediaScanner, private UserRepository $userRepository)
{
public function __construct(
private readonly MediaScanner $scanner,
private readonly UserRepository $userRepository
) {
parent::__construct();
$this->mediaScanner->on('paths-gathered', function (array $paths): void {
$this->scanner->on('paths-gathered', function (array $paths): void {
$this->progressBar = new ProgressBar($this->output, count($paths));
});
$this->mediaScanner->on('progress', [$this, 'onScanProgress']);
$this->scanner->on('progress', [$this, 'onScanProgress']);
}
protected function configure(): void
@ -88,7 +90,7 @@ class ScanCommand extends Command
$this->components->info('Ignoring tag(s): ' . implode(', ', $config->ignores));
}
$results = $this->mediaScanner->scan($config);
$results = $this->scanner->scan($config);
$this->newLine(2);
$this->components->info('Scanning completed!');
@ -112,7 +114,7 @@ class ScanCommand extends Command
*/
private function scanSingleRecord(string $record, ScanConfiguration $config): void
{
$this->mediaScanner->scanWatchRecord(new InotifyWatchRecord($record), $config);
$this->scanner->scanWatchRecord(new InotifyWatchRecord($record), $config);
}
public function onScanProgress(ScanResult $result): void
@ -129,7 +131,7 @@ class ScanCommand extends Command
$result->isSuccess() => "<fg=green>OK</>",
$result->isSkipped() => "<fg=yellow>SKIPPED</>",
$result->isError() => "<fg=red>ERROR</>",
default => throw new RuntimeException("Unknown scan result type: {$result->type}")
default => throw new RuntimeException("Unknown scan result type: {$result->type->value}")
});
if ($result->isError()) {

View file

@ -17,7 +17,7 @@ class SetupDropboxStorageCommand extends Command
protected $signature = 'koel:storage:dropbox';
protected $description = 'Set up Dropbox as the storage driver for Koel';
public function __construct(private DotenvEditor $dotenvEditor)
public function __construct(private readonly DotenvEditor $dotenvEditor)
{
parent::__construct();
}

View file

@ -13,7 +13,7 @@ class SetupLocalStorageCommand extends Command
protected $signature = 'koel:storage:local';
protected $description = 'Set up the local storage for Koel';
public function __construct(private DotenvEditor $dotenvEditor)
public function __construct(private readonly DotenvEditor $dotenvEditor)
{
parent::__construct();
}

View file

@ -14,7 +14,7 @@ class SetupS3StorageCommand extends Command
protected $signature = 'koel:storage:s3';
protected $description = 'Set up Amazon S3 or a compatible service as the storage driver for Koel';
public function __construct(private DotenvEditor $dotenvEditor)
public function __construct(private readonly DotenvEditor $dotenvEditor)
{
parent::__construct();
}

View file

@ -8,7 +8,7 @@ use Spatie\FlysystemDropbox\DropboxAdapter;
class DropboxFilesystem extends Filesystem
{
public function __construct(private DropboxAdapter $adapter)
public function __construct(private readonly DropboxAdapter $adapter)
{
parent::__construct($adapter, ['case_sensitive' => false]);
}

View file

@ -9,7 +9,7 @@ use App\Repositories\AlbumRepository;
class AlbumController extends Controller
{
public function __construct(private AlbumRepository $repository)
public function __construct(private readonly AlbumRepository $repository)
{
}

View file

@ -12,8 +12,10 @@ use Illuminate\Contracts\Auth\Authenticatable;
class AlbumSongController extends Controller
{
/** @param User $user */
public function __construct(private SongRepository $songRepository, private ?Authenticatable $user)
{
public function __construct(
private readonly SongRepository $songRepository,
private readonly ?Authenticatable $user
) {
}
public function index(Album $album)

View file

@ -9,7 +9,7 @@ use App\Repositories\AlbumRepository;
class ArtistAlbumController extends Controller
{
public function __construct(private AlbumRepository $albumRepository)
public function __construct(private readonly AlbumRepository $albumRepository)
{
}

View file

@ -9,7 +9,7 @@ use App\Repositories\ArtistRepository;
class ArtistController extends Controller
{
public function __construct(private ArtistRepository $repository)
public function __construct(private readonly ArtistRepository $repository)
{
}

View file

@ -12,8 +12,10 @@ use Illuminate\Contracts\Auth\Authenticatable;
class ArtistSongController extends Controller
{
/** @param User $user */
public function __construct(private SongRepository $songRepository, private ?Authenticatable $user)
{
public function __construct(
private readonly SongRepository $songRepository,
private readonly ?Authenticatable $user
) {
}
public function index(Artist $artist)

View file

@ -9,7 +9,7 @@ use Illuminate\Http\Response;
class GenreController extends Controller
{
public function __construct(private GenreRepository $repository)
public function __construct(private readonly GenreRepository $repository)
{
}

View file

@ -12,7 +12,7 @@ use Illuminate\Support\Arr;
class LambdaSongController extends Controller
{
public function __construct(private S3LambdaStorage $storage)
public function __construct(private readonly S3LambdaStorage $storage)
{
}

View file

@ -15,8 +15,10 @@ use Illuminate\Http\Response;
class PlaylistCollaboratorController extends Controller
{
public function __construct(private PlaylistCollaborationService $service, private UserRepository $userRepository)
{
public function __construct(
private readonly PlaylistCollaborationService $service,
private readonly UserRepository $userRepository
) {
}
public function index(Playlist $playlist)

View file

@ -23,10 +23,10 @@ class PlaylistController extends Controller
{
/** @param User $user */
public function __construct(
private PlaylistService $playlistService,
private PlaylistRepository $playlistRepository,
private PlaylistFolderRepository $folderRepository,
private ?Authenticatable $user
private readonly PlaylistService $playlistService,
private readonly PlaylistRepository $playlistRepository,
private readonly PlaylistFolderRepository $folderRepository,
private readonly ?Authenticatable $user
) {
}

View file

@ -14,8 +14,10 @@ use Illuminate\Contracts\Auth\Authenticatable;
class PlaylistFolderController extends Controller
{
/** @param User $user */
public function __construct(private PlaylistFolderService $service, private ?Authenticatable $user)
{
public function __construct(
private readonly PlaylistFolderService $service,
private readonly ?Authenticatable $user
) {
}
public function index()

View file

@ -11,7 +11,7 @@ use Illuminate\Support\Arr;
class PlaylistFolderPlaylistController extends Controller
{
public function __construct(private PlaylistFolderService $service)
public function __construct(private readonly PlaylistFolderService $service)
{
}

View file

@ -22,10 +22,10 @@ class PlaylistSongController extends Controller
{
/** @param User $user */
public function __construct(
private SongRepository $songRepository,
private PlaylistService $playlistService,
private SmartPlaylistService $smartPlaylistService,
private ?Authenticatable $user
private readonly SongRepository $songRepository,
private readonly PlaylistService $playlistService,
private readonly SmartPlaylistService $smartPlaylistService,
private readonly ?Authenticatable $user
) {
}
@ -49,7 +49,9 @@ class PlaylistSongController extends Controller
$songs = $this->songRepository->getMany(ids: $request->songs, scopedUser: $this->user);
return self::createResourceCollection($this->playlistService->addSongsToPlaylist($playlist, $songs, $this->user));
return self::createResourceCollection(
$this->playlistService->addSongsToPlaylist($playlist, $songs, $this->user)
);
}
private static function createResourceCollection(Collection $songs): ResourceCollection

View file

@ -18,10 +18,10 @@ class ProfileController extends Controller
{
/** @param User $user */
public function __construct(
private Hasher $hash,
private UserService $userService,
private TokenManager $tokenManager,
private ?Authenticatable $user
private readonly Hasher $hash,
private readonly UserService $userService,
private readonly TokenManager $tokenManager,
private readonly ?Authenticatable $user
) {
}

View file

@ -12,7 +12,7 @@ use Illuminate\Contracts\Auth\Authenticatable;
class QueueStateController extends Controller
{
/** @param User $user */
public function __construct(private QueueService $queueService, private ?Authenticatable $user)
public function __construct(private readonly QueueService $queueService, private readonly ?Authenticatable $user)
{
}

View file

@ -13,8 +13,10 @@ use Illuminate\Contracts\Auth\Authenticatable;
class SettingController extends Controller
{
/** @param User $user */
public function __construct(private MediaScanner $mediaSyncService, private ?Authenticatable $user)
{
public function __construct(
private readonly MediaScanner $mediaSyncService,
private readonly ?Authenticatable $user
) {
}
public function update(SettingRequest $request)

View file

@ -23,12 +23,12 @@ class SongController extends Controller
{
/** @param User $user */
public function __construct(
private SongService $songService,
private SongRepository $songRepository,
private AlbumRepository $albumRepository,
private ArtistRepository $artistRepository,
private LibraryManager $libraryManager,
private ?Authenticatable $user
private readonly SongService $songService,
private readonly SongRepository $songRepository,
private readonly AlbumRepository $albumRepository,
private readonly ArtistRepository $artistRepository,
private readonly LibraryManager $libraryManager,
private readonly ?Authenticatable $user
) {
}

View file

@ -14,8 +14,10 @@ use Illuminate\Http\Response;
class UserController extends Controller
{
public function __construct(private UserRepository $userRepository, private UserService $userService)
{
public function __construct(
private readonly UserRepository $userRepository,
private readonly UserService $userService
) {
}
public function index()

View file

@ -17,13 +17,11 @@ use Illuminate\Http\Response;
class UserInvitationController extends Controller
{
/**
* @param User $invitor
*/
/** @param User $invitor */
public function __construct(
private UserInvitationService $invitationService,
private AuthenticationService $auth,
private ?Authenticatable $invitor
private readonly UserInvitationService $invitationService,
private readonly AuthenticationService $auth,
private readonly ?Authenticatable $invitor
) {
}

View file

@ -13,9 +13,9 @@ class LastfmController extends Controller
{
/** @param User $currentUser */
public function __construct(
private LastfmService $lastfm,
private TokenManager $tokenManager,
private ?Authenticatable $currentUser
private readonly LastfmService $lastfm,
private readonly TokenManager $tokenManager,
private readonly ?Authenticatable $currentUser
) {
}

View file

@ -9,7 +9,7 @@ use Saloon\Repositories\Body\FormBodyRepository;
final class LastfmAuthenticator implements Authenticator
{
public function __construct(private string $key, private string $secret)
public function __construct(private readonly string $key, private readonly string $secret)
{
}

View file

@ -16,7 +16,7 @@ final class GetAlbumInfoRequest extends Request
protected Method $method = Method::GET;
public function __construct(private Album $album)
public function __construct(private readonly Album $album)
{
}

View file

@ -15,7 +15,7 @@ final class GetArtistInfoRequest extends Request
protected Method $method = Method::GET;
public function __construct(private Artist $artist)
public function __construct(private readonly Artist $artist)
{
}

View file

@ -10,7 +10,7 @@ final class GetSessionKeyRequest extends Request implements RequiresSignature
{
protected Method $method = Method::GET;
public function __construct(private string $token)
public function __construct(private readonly string $token)
{
}

View file

@ -17,8 +17,11 @@ final class ScrobbleRequest extends Request implements HasBody, RequiresSignatur
protected Method $method = Method::POST;
public function __construct(private Song $song, private User $user, private int $timestamp)
{
public function __construct(
private readonly Song $song,
private readonly User $user,
private readonly int $timestamp
) {
}
public function resolveEndpoint(): string

View file

@ -16,7 +16,7 @@ final class ToggleLoveTrackRequest extends Request implements HasBody, RequiresS
protected Method $method = Method::POST;
public function __construct(private Song $song, private User $user, private bool $love)
public function __construct(private readonly Song $song, private readonly User $user, private readonly bool $love)
{
}

View file

@ -17,7 +17,7 @@ final class UpdateNowPlayingRequest extends Request implements HasBody, Requires
protected Method $method = Method::POST;
public function __construct(private Song $song, private User $user)
public function __construct(private readonly Song $song, private readonly User $user)
{
}

View file

@ -13,7 +13,7 @@ class ActivateLicenseRequest extends Request implements HasBody
protected Method $method = Method::POST;
public function __construct(private string $key)
public function __construct(private readonly string $key)
{
}

View file

@ -14,7 +14,7 @@ class DeactivateLicenseRequest extends Request implements HasBody
protected Method $method = Method::POST;
public function __construct(private License $license)
public function __construct(private readonly License $license)
{
}

View file

@ -14,7 +14,7 @@ class ValidateLicenseRequest extends Request implements HasBody
protected Method $method = Method::POST;
public function __construct(private License $license)
public function __construct(private readonly License $license)
{
}

View file

@ -13,8 +13,11 @@ use SpotifyWebAPI\SpotifyWebAPI;
*/
class SpotifyClient
{
public function __construct(public SpotifyWebAPI $wrapped, private ?Session $session, private Cache $cache)
{
public function __construct(
public SpotifyWebAPI $wrapped,
private readonly ?Session $session,
private readonly Cache $cache
) {
if (SpotifyService::enabled()) {
$this->wrapped->setOptions(['return_assoc' => true]);
attempt(fn () => $this->setAccessToken());

View file

@ -10,7 +10,7 @@ class SearchVideosRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(private Song $song, private string $pageToken = '')
public function __construct(private readonly Song $song, private readonly string $pageToken = '')
{
}

View file

@ -11,7 +11,7 @@ class GetTrackRequest extends Request
{
protected Method $method = Method::GET;
public function __construct(private string $trackName, private Album $album)
public function __construct(private readonly string $trackName, private readonly Album $album)
{
}

View file

@ -36,7 +36,7 @@ class AlbumResource extends JsonResource
],
];
public function __construct(private Album $album)
public function __construct(private readonly Album $album)
{
parent::__construct($album);
}

View file

@ -34,7 +34,7 @@ class ArtistResource extends JsonResource
],
];
public function __construct(private Artist $artist)
public function __construct(private readonly Artist $artist)
{
parent::__construct($artist);
}

View file

@ -19,7 +19,7 @@ class ExcerptSearchResource extends JsonResource
],
];
public function __construct(private ExcerptSearchResult $result)
public function __construct(private readonly ExcerptSearchResult $result)
{
parent::__construct($result);
}

View file

@ -14,7 +14,7 @@ class GenreResource extends JsonResource
'length',
];
public function __construct(private Genre $genre)
public function __construct(private readonly Genre $genre)
{
parent::__construct($genre);
}

View file

@ -17,7 +17,7 @@ class InteractionResource extends JsonResource
'play_count',
];
public function __construct(private Interaction $interaction)
public function __construct(private readonly Interaction $interaction)
{
parent::__construct($interaction);
}

View file

@ -12,7 +12,7 @@ class PlaylistCollaborationTokenResource extends JsonResource
'token',
];
public function __construct(private PlaylistCollaborationToken $token)
public function __construct(private readonly PlaylistCollaborationToken $token)
{
parent::__construct($token);
}

View file

@ -14,7 +14,7 @@ class PlaylistCollaboratorResource extends JsonResource
'avatar',
];
public function __construct(private PlaylistCollaborator $collaborator)
public function __construct(private readonly PlaylistCollaborator $collaborator)
{
parent::__construct($collaborator);
}

View file

@ -15,7 +15,7 @@ class PlaylistFolderResource extends JsonResource
'created_at',
];
public function __construct(private PlaylistFolder $folder)
public function __construct(private readonly PlaylistFolder $folder)
{
parent::__construct($folder);
}

View file

@ -20,7 +20,7 @@ class PlaylistResource extends JsonResource
'created_at',
];
public function __construct(private Playlist $playlist)
public function __construct(private readonly Playlist $playlist)
{
parent::__construct($playlist);
}

View file

@ -15,7 +15,7 @@ class QueueStateResource extends JsonResource
'playback_position',
];
public function __construct(private QueueState $state)
public function __construct(private readonly QueueState $state)
{
parent::__construct($state);
}

View file

@ -17,7 +17,7 @@ class UserProspectResource extends JsonResource
'is_prospect',
];
public function __construct(private User $user)
public function __construct(private readonly User $user)
{
parent::__construct($user);
}

View file

@ -20,7 +20,7 @@ class UserResource extends JsonResource
'sso_id',
];
public function __construct(private User $user)
public function __construct(private readonly User $user)
{
parent::__construct($user);
}

View file

@ -9,7 +9,7 @@ use App\Values\ScanResult;
class DeleteNonExistingRecordsPostScan
{
public function __construct(private SongRepository $songRepository)
public function __construct(private readonly SongRepository $songRepository)
{
}

View file

@ -8,7 +8,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
class LoveMultipleTracksOnLastfm implements ShouldQueue
{
public function __construct(private LastfmService $lastfm)
public function __construct(private readonly LastfmService $lastfm)
{
}

View file

@ -8,7 +8,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
class LoveTrackOnLastfm implements ShouldQueue
{
public function __construct(private LastfmService $lastfm)
public function __construct(private readonly LastfmService $lastfm)
{
}

View file

@ -8,7 +8,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
class MakePlaylistSongsPublic implements ShouldQueue
{
public function __construct(private PlaylistService $service)
public function __construct(private readonly PlaylistService $service)
{
}

View file

@ -6,7 +6,7 @@ use App\Services\LibraryManager;
class PruneLibrary
{
public function __construct(private LibraryManager $libraryManager)
public function __construct(private readonly LibraryManager $libraryManager)
{
}

View file

@ -8,7 +8,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
class UnloveMultipleTracksOnLastfm implements ShouldQueue
{
public function __construct(private LastfmService $lastfm)
public function __construct(private readonly LastfmService $lastfm)
{
}

View file

@ -8,7 +8,7 @@ use Illuminate\Contracts\Queue\ShouldQueue;
class UpdateLastfmNowPlaying implements ShouldQueue
{
public function __construct(private LastfmService $lastfm)
public function __construct(private readonly LastfmService $lastfm)
{
}

View file

@ -14,7 +14,7 @@ class UserInvite extends Mailable
use Queueable;
use SerializesModels;
public function __construct(private User $invitee)
public function __construct(private readonly User $invitee)
{
}

View file

@ -9,7 +9,7 @@ use Illuminate\Support\Arr;
final class AllPlaylistsAreAccessibleBy implements Rule
{
public function __construct(private User $user)
public function __construct(private readonly User $user)
{
}

View file

@ -1,159 +0,0 @@
<?php
namespace App\Services\ApiClients;
use GuzzleHttp\Client as GuzzleHttpClient;
use GuzzleHttp\Promise\Promise;
use Illuminate\Support\Str;
use InvalidArgumentException;
use SimpleXMLElement;
use Webmozart\Assert\Assert;
/**
* @method mixed get(string $uri, array $data = [], bool $appendKey = true, array $headers = [])
* @method mixed post($uri, array $data = [], bool $appendKey = true, array $headers = [])
* @method mixed put($uri, array $data = [], bool $appendKey = true, array $headers = [])
* @method mixed patch($uri, array $data = [], bool $appendKey = true, array $headers = [])
* @method mixed head($uri, array $data = [], bool $appendKey = true, array $headers = [])
* @method mixed delete($uri, array $data = [], bool $appendKey = true, array $headers = [])
* @method Promise getAsync(string $uri, array $data = [], bool $appendKey = true)
* @method Promise postAsync($uri, array $data = [], bool $appendKey = true)
* @method Promise putAsync($uri, array $data = [], bool $appendKey = true)
* @method Promise patchAsync($uri, array $data = [], bool $appendKey = true)
* @method Promise headAsync($uri, array $data = [], bool $appendKey = true)
* @method Promise deleteAsync($uri, array $data = [], bool $appendKey = true)
*/
abstract class ApiClient
{
private const MAGIC_METHODS = [
'get',
'post',
'put',
'patch',
'head',
'delete',
'getAsync',
'postAsync',
'putAsync',
'patchAsync',
'headAsync',
'deleteAsync',
];
protected array $headers = [];
protected string $responseFormat = 'json';
/**
* The query parameter name for the key.
* For example, Last.fm use api_key, like this:
* https://ws.audioscrobbler.com/2.0?method=artist.getInfo&artist=Kamelot&api_key=API_KEY.
*/
protected string $keyParam = 'key';
public function __construct(protected GuzzleHttpClient $wrapped)
{
}
/**
* Make a request to the API.
*
* @param string $method The HTTP method
* @param string $uri The API URI (segment)
* @param bool $appendKey Whether to automatically append the API key into the URI.
* While it's usually the case, some services (like Last.fm) requires
* an "API signature" of the request. Appending an API key will break the request.
* @param array $params An array of parameters
*/
public function request(
string $method,
string $uri,
bool $appendKey = true,
array $params = [],
array $headers = []
): mixed {
$options = [
'headers' => array_merge($this->headers, $headers),
];
$body = (string) $this->wrapped
->$method($this->buildUrl($uri, $appendKey), ['form_params' => $params], $options)
->getBody();
if ($this->responseFormat === 'json') {
return json_decode($body);
}
if ($this->responseFormat === 'xml') {
return simplexml_load_string($body);
}
return $body;
}
public function requestAsync(string $method, string $uri, bool $appendKey = true, array $params = []): Promise
{
return $this->wrapped->$method($this->buildUrl($uri, $appendKey), ['form_params' => $params]);
}
/**
* Make an HTTP call to the external resource.
*
* @param string $method The HTTP method
* @param array<mixed> $args An array of parameters
*
* @return mixed|SimpleXMLElement|void
* @throws InvalidArgumentException
*
*/
public function __call(string $method, array $args) // @phpcs:ignore
{
Assert::inArray($method, self::MAGIC_METHODS);
if (count($args) < 1) {
throw new InvalidArgumentException('Magic request methods require a URI and optional options array');
}
$uri = $args[0];
$params = $args[1] ?? [];
$appendKey = $args[2] ?? true;
$headers = $args[3] ?? [];
if (Str::endsWith($method, 'Async')) {
return $this->requestAsync($method, $uri, $appendKey, $params);
} else {
return $this->request($method, $uri, $appendKey, $params, $headers);
}
}
/**
* Turn a URI segment into a full API URL.
*
* @param bool $appendKey whether to automatically append the API key into the URL
*/
public function buildUrl(string $uri, bool $appendKey = true): string
{
if (!starts_with($uri, ['http://', 'https://'])) {
if ($uri[0] !== '/') {
$uri = "/$uri";
}
$uri = rtrim($this->getEndpoint(), '/') . $uri;
}
if ($appendKey && $this->getKey()) {
if (parse_url($uri, PHP_URL_QUERY)) {
$uri .= "&$this->keyParam=" . $this->getKey();
} else {
$uri .= "?$this->keyParam=" . $this->getKey();
}
}
return $uri;
}
abstract public function getKey(): ?string;
abstract public function getSecret(): ?string;
abstract public function getEndpoint(): ?string;
}

View file

@ -1,21 +0,0 @@
<?php
namespace App\Services\ApiClients;
class ITunesClient extends ApiClient
{
public function getKey(): ?string
{
return null;
}
public function getSecret(): ?string
{
return null;
}
public function getEndpoint(): ?string
{
return config('koel.itunes.endpoint');
}
}

View file

@ -7,7 +7,7 @@ use Illuminate\Contracts\Cache\Repository as Cache;
class ApplicationInformationService
{
public function __construct(private Client $client, private Cache $cache)
public function __construct(private readonly Client $client, private readonly Cache $cache)
{
}

View file

@ -15,10 +15,10 @@ use Illuminate\Support\Facades\Password;
class AuthenticationService
{
public function __construct(
private UserRepository $userRepository,
private TokenManager $tokenManager,
private HashManager $hash,
private PasswordBroker $passwordBroker
private readonly UserRepository $userRepository,
private readonly TokenManager $tokenManager,
private readonly HashManager $hash,
private readonly PasswordBroker $passwordBroker
) {
}

View file

@ -28,12 +28,12 @@ class FileScanner
private ?string $syncError = null;
public function __construct(
private getID3 $getID3,
private MediaMetadataService $mediaMetadataService,
private SongRepository $songRepository,
private SimpleLrcReader $lrcReader,
private Cache $cache,
private Finder $finder
private readonly getID3 $getID3,
private readonly MediaMetadataService $mediaMetadataService,
private readonly SongRepository $songRepository,
private readonly SimpleLrcReader $lrcReader,
private readonly Cache $cache,
private readonly Finder $finder
) {
}

View file

@ -9,7 +9,7 @@ use Illuminate\Cache\Repository as Cache;
class ITunesService
{
public function __construct(private ITunesConnector $connector, private Cache $cache)
public function __construct(private readonly ITunesConnector $connector, private readonly Cache $cache)
{
}

View file

@ -11,7 +11,7 @@ class ImageWriter
private const DEFAULT_MAX_WIDTH = 500;
private const DEFAULT_QUALITY = 80;
public function __construct(private ImageManager $imageManager)
public function __construct(private readonly ImageManager $imageManager)
{
}

View file

@ -22,7 +22,7 @@ use Illuminate\Support\Collection;
class LastfmService implements MusicEncyclopedia
{
public function __construct(private LastfmConnector $connector, private Cache $cache)
public function __construct(private readonly LastfmConnector $connector, private readonly Cache $cache)
{
}

View file

@ -21,7 +21,7 @@ use Throwable;
class LicenseService implements LicenseServiceInterface
{
public function __construct(private LemonSqueezyConnector $connector, private string $hashSalt)
public function __construct(private readonly LemonSqueezyConnector $connector, private readonly string $hashSalt)
{
}

View file

@ -12,9 +12,9 @@ use Illuminate\Cache\Repository as Cache;
class MediaInformationService
{
public function __construct(
private MusicEncyclopedia $encyclopedia,
private MediaMetadataService $mediaMetadataService,
private Cache $cache
private readonly MusicEncyclopedia $encyclopedia,
private readonly MediaMetadataService $mediaMetadataService,
private readonly Cache $cache
) {
}

View file

@ -10,8 +10,10 @@ use Illuminate\Support\Str;
class MediaMetadataService
{
public function __construct(private SpotifyService $spotifyService, private ImageWriter $imageWriter)
{
public function __construct(
private readonly SpotifyService $spotifyService,
private readonly ImageWriter $imageWriter
) {
}
public function tryDownloadAlbumCover(Album $album): void

View file

@ -22,11 +22,11 @@ class MediaScanner
private array $events = [];
public function __construct(
private SettingRepository $settingRepository,
private SongRepository $songRepository,
private FileScanner $fileScanner,
private Finder $finder,
private LoggerInterface $logger
private readonly SettingRepository $settingRepository,
private readonly SongRepository $songRepository,
private readonly FileScanner $fileScanner,
private readonly Finder $finder,
private readonly LoggerInterface $logger
) {
}

View file

@ -18,7 +18,7 @@ use Webmozart\Assert\Assert;
class PlaylistService
{
public function __construct(private SongRepository $songRepository)
public function __construct(private readonly SongRepository $songRepository)
{
}

View file

@ -11,7 +11,7 @@ use Throwable;
class ProxyAuthService
{
public function __construct(private UserService $userService)
public function __construct(private readonly UserService $userService)
{
}

View file

@ -9,7 +9,7 @@ use App\Values\QueueState as QueueStateDTO;
class QueueService
{
public function __construct(private SongRepository $songRepository)
public function __construct(private readonly SongRepository $songRepository)
{
}

View file

@ -19,9 +19,9 @@ class SearchService
public const DEFAULT_MAX_SONG_RESULT_COUNT = 500;
public function __construct(
private SongRepository $songRepository,
private AlbumRepository $albumRepository,
private ArtistRepository $artistRepository
private readonly SongRepository $songRepository,
private readonly AlbumRepository $albumRepository,
private readonly ArtistRepository $artistRepository
) {
}

View file

@ -18,9 +18,9 @@ use Throwable;
class SongService
{
public function __construct(
private SongRepository $songRepository,
private SongStorage $songStorage,
private LoggerInterface $logger
private readonly SongRepository $songRepository,
private readonly SongStorage $songStorage,
private readonly LoggerInterface $logger
) {
}

View file

@ -13,7 +13,7 @@ use Illuminate\Support\Facades\Storage;
class S3CompatibleStorage extends CloudStorage
{
public function __construct(protected FileScanner $scanner, private string $bucket)
public function __construct(protected FileScanner $scanner, private readonly string $bucket)
{
parent::__construct($scanner);
}

View file

@ -21,9 +21,9 @@ use Illuminate\Http\UploadedFile;
final class S3LambdaStorage extends S3CompatibleStorage
{
public function __construct( // @phpcs:ignore
private MediaMetadataService $mediaMetadataService,
private SongRepository $songRepository,
private UserRepository $userRepository
private readonly MediaMetadataService $mediaMetadataService,
private readonly SongRepository $songRepository,
private readonly UserRepository $userRepository
) {
}

View file

@ -9,7 +9,7 @@ use Illuminate\Support\Arr;
class SpotifyService
{
public function __construct(private SpotifyClient $client)
public function __construct(private readonly SpotifyClient $client)
{
}

View file

@ -9,7 +9,7 @@ use Illuminate\Routing\Redirector;
class DropboxStreamerAdapter implements StreamerAdapter
{
public function __construct(private DropboxStorage $storage)
public function __construct(private readonly DropboxStorage $storage)
{
}

View file

@ -9,7 +9,7 @@ use Illuminate\Routing\Redirector;
class S3CompatibleStreamerAdapter implements StreamerAdapter
{
public function __construct(private S3CompatibleStorage $storage)
public function __construct(private readonly S3CompatibleStorage $storage)
{
}

View file

@ -19,8 +19,11 @@ class Streamer
{
private StreamerAdapter $adapter;
public function __construct(private Song $song, ?StreamerAdapter $adapter = null, private array $config = [])
{
public function __construct(
private readonly Song $song,
?StreamerAdapter $adapter = null,
private readonly array $config = []
) {
// Turn off error reporting to make sure our stream isn't interfered.
@error_reporting(0);

View file

@ -10,7 +10,7 @@ use Laravel\Sanctum\PersonalAccessToken;
class TokenManager
{
public function __construct(private Cache $cache)
public function __construct(private readonly Cache $cache)
{
}

View file

@ -14,7 +14,7 @@ use Illuminate\Support\Str;
class UserInvitationService
{
public function __construct(private Hash $hash, private UserRepository $userRepository)
public function __construct(private readonly Hash $hash, private readonly UserRepository $userRepository)
{
}

View file

@ -14,9 +14,9 @@ use Illuminate\Support\Str;
class UserService
{
public function __construct(
private UserRepository $repository,
private Hasher $hash,
private ImageWriter $imageWriter
private readonly UserRepository $repository,
private readonly Hasher $hash,
private readonly ImageWriter $imageWriter
) {
}

View file

@ -10,7 +10,7 @@ use Throwable;
class YouTubeService
{
public function __construct(private YouTubeConnector $connector, private Cache $cache)
public function __construct(private readonly YouTubeConnector $connector, private readonly Cache $cache)
{
}

View file

@ -8,7 +8,7 @@ final class ScanResult
{
private function __construct(
public string $path,
private readonly ScanResultType $type,
public ScanResultType $type,
public ?string $error = null
) {
}