fix(build): fixing build errors

This commit is contained in:
Phan An 2024-07-07 15:29:37 +02:00
parent 781af8dc27
commit e3086422c7
14 changed files with 40 additions and 39 deletions

View file

@ -8,12 +8,15 @@ use App\Models\Song;
use App\Repositories\SongRepository;
use App\Services\DownloadService;
use Illuminate\Http\Response;
use Illuminate\Support\Collection;
class DownloadSongsController extends Controller
{
public function __invoke(DownloadSongsRequest $request, DownloadService $service, SongRepository $repository)
{
// Don't use SongRepository::findMany() because it'd have been already catered to the current user.
/** @var Array<Song>|Collection<array-key, Song> $songs */
$songs = Song::query()->findMany($request->songs);
$songs->each(fn ($song) => $this->authorize('download', $song));

View file

@ -18,7 +18,7 @@ use PhanAn\Poddle\Values\CategoryCollection;
use PhanAn\Poddle\Values\ChannelMetadata;
/**
* @property-read string $id
* @property string $id
* @property string $url
* @property string $title
* @property string $description

View file

@ -17,6 +17,7 @@ use App\Values\SongStorageMetadata\S3LambdaMetadata;
use App\Values\SongStorageMetadata\SftpMetadata;
use App\Values\SongStorageMetadata\SongStorageMetadata;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
@ -31,7 +32,7 @@ use Throwable;
/**
* @property string $path
* @property string $title
* @property Album $album
* @property ?Album $album
* @property User $uploader
* @property ?Artist $artist
* @property ?Artist $album_artist
@ -105,13 +106,12 @@ class Song extends Model
public static function query(?PlayableType $type = null, ?User $user = null): SongBuilder
{
return parent::query()
->when($type, static function (SongBuilder $query) use ($type): void {
match ($type) {
PlayableType::SONG => $query->whereNull('songs.podcast_id'),
PlayableType::PODCAST_EPISODE => $query->whereNotNull('songs.podcast_id'),
};
->when($type, static fn (Builder $query) => match ($type) { // @phpstan-ignore-line phpcs:ignore
PlayableType::SONG => $query->whereNull('songs.podcast_id'),
PlayableType::PODCAST_EPISODE => $query->whereNotNull('songs.podcast_id'),
default => $query,
})
->when($user, static fn (SongBuilder $query) => $query->forUser($user));
->when($user, static fn (SongBuilder $query) => $query->forUser($user)); // @phpstan-ignore-line
}
public function owner(): BelongsTo

View file

@ -1,14 +0,0 @@
<?php
namespace App\Policies;
use App\Models\Podcast\Song;
use App\Models\User;
class EpisodePolicy
{
public function access(User $user, Song $episode): bool
{
return $user->subscribedToPodcast($episode->podcast);
}
}

View file

@ -21,8 +21,9 @@ use Throwable;
class LicenseService implements LicenseServiceInterface
{
public function __construct(private readonly LemonSqueezyConnector $connector, private readonly string $hashSalt)
public function __construct(private readonly LemonSqueezyConnector $connector, private ?string $hashSalt = null)
{
$this->hashSalt ??= config('app.key');
}
public function activate(string $key): License

View file

@ -13,6 +13,7 @@ use App\Repositories\SongRepository;
use Carbon\Carbon;
use GuzzleHttp\Client;
use GuzzleHttp\RedirectMiddleware;
use GuzzleHttp\RequestOptions;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
@ -56,6 +57,7 @@ class PodcastService
$channel = $parser->getChannel();
return DB::transaction(function () use ($url, $podcast, $parser, $channel, $user) {
/** @var Podcast $podcast */
$podcast = Podcast::query()->create([
'url' => $url,
'title' => $channel->title,
@ -102,8 +104,8 @@ class PodcastService
'last_synced_at' => now(),
]);
$pubDate = $parser->xmlReader->value('rss.channel.pubDate')?->first()
?? $parser->xmlReader->value('rss.channel.lastBuildDate')?->first();
$pubDate = $parser->xmlReader->value('rss.channel.pubDate')->first()
?? $parser->xmlReader->value('rss.channel.lastBuildDate')->first();
if ($pubDate && Carbon::createFromFormat(Carbon::RFC1123, $pubDate)->isBefore($podcast->last_synced_at)) {
// The pubDate/lastBuildDate value indicates that there's no new content since last check.
@ -150,7 +152,7 @@ class PodcastService
// Since insert() doesn't trigger model events, Scout operations will not be called.
// We have to manually update the search index.
Episode::query()->whereIn('id', $ids)->searchable();
Episode::query()->whereIn('id', $ids)->searchable(); // @phpstan-ignore-line
}
private function subscribeUserToPodcast(User $user, Podcast $podcast): void
@ -206,16 +208,16 @@ class PodcastService
$url = $url->path;
}
$client ??= $this->client ?? new Client();
$client ??= new Client();
try {
$response = $client->request($method, $url, [
'headers' => [
RequestOptions::HEADERS => [
'User-Agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 14_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.4.1 Safari/605.1.15', // @phpcs-ignore-line
'Origin' => '*',
],
'http_errors' => false,
'allow_redirects' => ['track_redirects' => true],
RequestOptions::HTTP_ERRORS => false,
RequestOptions::ALLOW_REDIRECTS => ['track_redirects' => true],
]);
$redirects = Arr::wrap($response->getHeader(RedirectMiddleware::HISTORY_HEADER));

View file

@ -52,7 +52,7 @@ class SearchService
{
try {
return $repository->getMany(
ids: $repository->model::search($keywords)->get()->take($count)->pluck('id')->all(),
ids: $repository->model::search($keywords)->get()->take($count)->pluck('id')->all(), // @phpstan-ignore-line
preserveOrder: true,
);
} catch (Throwable $e) {

View file

@ -41,7 +41,7 @@ class SongService
return collect($ids)->reduce(function (Collection $updated, string $id) use ($data): Collection {
optional(
Song::query()->with('album.artist')->find($id),
fn (Song $song) => $updated->push($this->updateSong($song, clone $data))
fn (Song $song) => $updated->push($this->updateSong($song, clone $data)) // @phpstan-ignore-line
);
return $updated;

View file

@ -29,6 +29,7 @@ parameters:
- '#Method App\\Models\\.*::query\(\) should return App\\Builders\\.*Builder but returns Illuminate\\Database\\Eloquent\\Builder<Illuminate\\Database\\Eloquent\\Model>#'
- '#Parameter \#1 \$callback of method Illuminate\\Support\\Collection<int,Illuminate\\Database\\Eloquent\\Model>::each\(\) expects callable\(Illuminate\\Database\\Eloquent\\Model, int\)#'
- '#Access to an undefined property Illuminate\\Database\\Eloquent\\Model::#'
- '#Unknown parameter \$(type|user) in call to static method App\\Models\\Song::query\(\)#'
excludePaths:

View file

@ -1,7 +1,5 @@
<?php
use Illuminate\Support\Facades\Broadcast;
/*
|--------------------------------------------------------------------------
| Broadcast Channels
@ -12,4 +10,3 @@ use Illuminate\Support\Facades\Broadcast;
| used to check if an authenticated user can listen to the channel.
|
*/
Broadcast::channel('App.User.{id}', static fn ($user, $id) => (int) $user->id === (int) $id);

View file

@ -28,7 +28,9 @@ class ExcerptSearchTest extends TestCase
Album::factory(4)->create();
$user = create_user();
$user->subscribeToPodcast(Podcast::factory()->create(['title' => 'Foo Podcast']));
/** @var Podcast $podcast */
$podcast = Podcast::factory()->create(['title' => 'Foo Podcast']);
$user->subscribeToPodcast($podcast);
$this->getAs('api/search?q=foo', $user)
->assertJsonStructure([

View file

@ -212,6 +212,7 @@ class PlaylistServiceTest extends TestCase
$playlist = Playlist::factory()->create();
$playlist->addPlayables(Song::factory(3)->create());
/** @var Podcast $podcast */
$podcast = Podcast::factory()->create();
$episodes = Song::factory(2)->asEpisode()->for($podcast)->create();

View file

@ -1,6 +1,6 @@
<?php
namespace Integration\Services;
namespace Tests\Integration\Services;
use App\Exceptions\UserAlreadySubscribedToPodcast;
use App\Models\Podcast;
@ -8,11 +8,11 @@ use App\Models\PodcastUserPivot;
use App\Models\Song;
use App\Services\PodcastService;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Response;
use Illuminate\Support\Facades\Http;
use Psr\Http\Client\ClientInterface;
use Tests\TestCase;
use function Tests\create_user;
@ -59,6 +59,7 @@ class PodcastServiceTest extends TestCase
public function testSubscribeUserToPodcast(): void
{
/** @var Podcast $podcast */
$podcast = Podcast::factory()->create([
'url' => 'https://example.com/feed.xml',
'title' => 'My Cool Podcast',
@ -79,6 +80,7 @@ class PodcastServiceTest extends TestCase
{
self::expectException(UserAlreadySubscribedToPodcast::class);
/** @var Podcast $podcast */
$podcast = Podcast::factory()->create([
'url' => 'https://example.com/feed.xml',
]);
@ -97,6 +99,7 @@ class PodcastServiceTest extends TestCase
'https://example.com/feed.xml' => Http::response(headers: ['Last-Modified' => now()->toRfc1123String()]),
]);
/** @var Podcast $podcast */
$podcast = Podcast::factory()->create([
'url' => 'https://example.com/feed.xml',
'title' => 'Shall be changed very sad',
@ -116,6 +119,7 @@ class PodcastServiceTest extends TestCase
public function testUnsubscribeUserFromPodcast(): void
{
/** @var Podcast $podcast */
$podcast = Podcast::factory()->create();
$user = create_user();
$user->subscribeToPodcast($podcast);
@ -127,6 +131,7 @@ class PodcastServiceTest extends TestCase
public function testPodcastNotObsoleteIfSyncedRecently(): void
{
/** @var Podcast $podcast */
$podcast = Podcast::factory()->create([
'last_synced_at' => now()->subHours(6),
]);
@ -140,6 +145,7 @@ class PodcastServiceTest extends TestCase
'https://example.com/feed.xml' => Http::response(headers: ['Last-Modified' => now()->toRfc1123String()]),
]);
/** @var Podcast $podcast */
$podcast = Podcast::factory()->create([
'url' => 'https://example.com/feed.xml',
'last_synced_at' => now()->subDays(1),
@ -150,6 +156,7 @@ class PodcastServiceTest extends TestCase
public function testUpdateEpisodeProgress(): void
{
/** @var Song $episode */
$episode = Song::factory()->asEpisode()->create();
$user = create_user();
$user->subscribeToPodcast($episode->podcast);

View file

@ -1,6 +1,6 @@
<?php
namespace Integration\Values;
namespace Tests\Integration\Values;
use App\Models\Song;
use App\Values\Podcast\EpisodePlayable;
@ -16,6 +16,7 @@ class EpisodePlayableTest extends TestCase
'https://example.com/episode.mp3' => Http::response('foo'),
]);
/** @var Song $episode */
$episode = Song::factory()->asEpisode()->create([
'path' => 'https://example.com/episode.mp3',
]);