clean: removed nova (#717)

This commit is contained in:
Kyrch
2024-07-29 13:07:36 -03:00
committed by GitHub
parent e1b25f46d4
commit c02840a580
300 changed files with 305 additions and 16684 deletions
-7
View File
@@ -214,13 +214,6 @@ MAIL_FROM_NAME="${APP_NAME}"
MAIL_SENDMAIL_PATH="/usr/sbin/sendmail -bs -i"
MAIL_LOG_CHANNEL=
# nova
NOVA_DOMAIN_NAME=null
NOVA_GUARD=null
NOVA_LICENSE_KEY=
NOVA_PASSWORDS=null
NOVA_PATH=/nova
# pennant
PENNANT_STORE=database
-7
View File
@@ -211,13 +211,6 @@ MAIL_FROM_NAME=AnimeThemes
MAIL_SENDMAIL_PATH="/usr/sbin/sendmail -bs -i"
MAIL_LOG_CHANNEL=
# nova
NOVA_DOMAIN_NAME=null
NOVA_GUARD=null
NOVA_LICENSE_KEY=
NOVA_PASSWORDS=null
NOVA_PATH=/admin
# pennant
PENNANT_STORE=database
-4
View File
@@ -16,11 +16,7 @@ jobs:
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"
- name: Install Dependencies
env:
NOVA_USERNAME: ${{ secrets.NOVA_USERNAME }}
NOVA_PASSWORD: ${{ secrets.NOVA_PASSWORD }}
run: |
composer config "http-basic.nova.laravel.com" "$NOVA_USERNAME" "$NOVA_PASSWORD"
composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
-4
View File
@@ -16,11 +16,7 @@ jobs:
- name: Copy .env
run: php -r "file_exists('.env') || copy('.env.example', '.env');"
- name: Install Dependencies
env:
NOVA_USERNAME: ${{ secrets.NOVA_USERNAME }}
NOVA_PASSWORD: ${{ secrets.NOVA_PASSWORD }}
run: |
composer config "http-basic.nova.laravel.com" "$NOVA_USERNAME" "$NOVA_PASSWORD"
composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
- name: Generate key
run: php artisan key:generate
@@ -1,35 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Contracts\Events;
use Illuminate\Support\Collection;
use Laravel\Nova\Notifications\NovaNotification;
/**
* Interface NovaNotificationEvent.
*/
interface NovaNotificationEvent
{
/**
* Determine if the notifications should be sent.
*
* @return bool
*/
public function shouldSendNovaNotification(): bool;
/**
* Get the nova notification.
*
* @return NovaNotification
*/
public function getNovaNotification(): NovaNotification;
/**
* Get the users to notify.
*
* @return Collection
*/
public function getNovaNotificationRecipients(): Collection;
}
-2
View File
@@ -17,8 +17,6 @@ enum SpecialPermission: string
case VIEW_HORIZON = 'view horizon';
case VIEW_NOVA = 'view nova';
case VIEW_TELESCOPE = 'view telescope';
case REVALIDATE_PAGES = 'revalidate pages';
+4 -51
View File
@@ -6,7 +6,6 @@ namespace App\Events\Base\Wiki;
use App\Constants\Config\ServiceConstants;
use App\Contracts\Events\FilamentNotificationEvent;
use App\Contracts\Events\NovaNotificationEvent;
use App\Enums\Auth\Role as RoleEnum;
use App\Events\Base\BaseDeletedEvent;
use App\Models\Auth\Role;
@@ -15,7 +14,6 @@ use Filament\Notifications\Actions\Action as NotificationAction;
use Filament\Notifications\Notification;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Config;
use Laravel\Nova\Notifications\NovaNotification;
/**
* Class WikiDeletedEvent.
@@ -24,7 +22,7 @@ use Laravel\Nova\Notifications\NovaNotification;
*
* @extends BaseDeletedEvent<TModel>
*/
abstract class WikiDeletedEvent extends BaseDeletedEvent implements NovaNotificationEvent, FilamentNotificationEvent
abstract class WikiDeletedEvent extends BaseDeletedEvent implements FilamentNotificationEvent
{
/**
* Get Discord channel the message will be sent to.
@@ -37,57 +35,12 @@ abstract class WikiDeletedEvent extends BaseDeletedEvent implements NovaNotifica
}
/**
* Determine if the notifications should be sent.
*
* @return bool
*/
public function shouldSendNovaNotification(): bool
{
$model = $this->getModel();
return !$model->isForceDeleting();
}
/**
* Get the nova notification.
*
* @return NovaNotification
*/
public function getNovaNotification(): NovaNotification
{
return NovaNotification::make()
->icon('flag')
->message($this->getNotificationMessage())
->type(NovaNotification::INFO_TYPE)
->url($this->getNovaNotificationUrl());
}
/**
* Get the users to notify.
*
* @return Collection
*/
public function getNovaNotificationRecipients(): Collection
{
return User::query()
->whereRelation(User::RELATION_ROLES, Role::ATTRIBUTE_NAME, RoleEnum::ADMIN->value)
->get();
}
/**
* Get the message for the nova/filament notification.
* Get the message for the filament notification.
*
* @return string
*/
abstract protected function getNotificationMessage(): string;
/**
* Get the URL for the nova notification.
*
* @return string
*/
abstract protected function getNovaNotificationUrl(): string;
/**
* Determine if the notifications should be sent.
*
@@ -101,7 +54,7 @@ abstract class WikiDeletedEvent extends BaseDeletedEvent implements NovaNotifica
}
/**
* Get the nova notification.
* Get the filament notification.
*
* @return Notification
*/
@@ -134,7 +87,7 @@ abstract class WikiDeletedEvent extends BaseDeletedEvent implements NovaNotifica
}
/**
* Get the URL for the nova notification.
* Get the URL for the filament notification.
*
* @return string
*/
+1 -14
View File
@@ -7,7 +7,6 @@ namespace App\Events\Document\Page;
use App\Events\Base\Wiki\WikiDeletedEvent;
use App\Filament\Resources\Document\Page as PageFilament;
use App\Models\Document\Page;
use App\Nova\Resources\Document\Page as PageResource;
/**
* Class PageDeleted.
@@ -47,7 +46,7 @@ class PageDeleted extends WikiDeletedEvent
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -56,18 +55,6 @@ class PageDeleted extends WikiDeletedEvent
return "Page '{$this->getModel()->getName()}' has been deleted. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = PageResource::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
+1 -14
View File
@@ -7,7 +7,6 @@ namespace App\Events\Wiki\Anime;
use App\Events\Base\Wiki\WikiDeletedEvent;
use App\Filament\Resources\Wiki\Anime as AnimeFilament;
use App\Models\Wiki\Anime;
use App\Nova\Resources\Wiki\Anime as AnimeResource;
/**
* Class AnimeDeleted.
@@ -47,7 +46,7 @@ class AnimeDeleted extends WikiDeletedEvent
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -56,18 +55,6 @@ class AnimeDeleted extends WikiDeletedEvent
return "Anime '{$this->getModel()->getName()}' has been deleted. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = AnimeResource::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
@@ -12,7 +12,6 @@ use App\Models\Wiki\Anime\AnimeSynonym;
use App\Models\Wiki\Anime\AnimeTheme;
use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
use App\Models\Wiki\Video;
use App\Nova\Resources\Wiki\Anime\Synonym as SynonymResource;
/**
* Class SynonymDeleted.
@@ -60,7 +59,7 @@ class SynonymDeleted extends WikiDeletedEvent implements UpdateRelatedIndicesEve
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -69,18 +68,6 @@ class SynonymDeleted extends WikiDeletedEvent implements UpdateRelatedIndicesEve
return "Synonym '{$this->getModel()->getName()}' has been deleted for Anime '{$this->anime->getName()}'. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = SynonymResource::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
@@ -9,7 +9,6 @@ use App\Events\Base\Wiki\WikiDeletedEvent;
use App\Filament\Resources\Wiki\Anime\Theme\Entry as EntryFilament;
use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
use App\Models\Wiki\Video;
use App\Nova\Resources\Wiki\Anime\Theme\Entry as EntryResource;
/**
* Class EntryDeleted.
@@ -49,7 +48,7 @@ class EntryDeleted extends WikiDeletedEvent implements UpdateRelatedIndicesEvent
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -58,18 +57,6 @@ class EntryDeleted extends WikiDeletedEvent implements UpdateRelatedIndicesEvent
return "Entry '{$this->getModel()->getName()}' has been deleted. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = EntryResource::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
+1 -14
View File
@@ -8,7 +8,6 @@ use App\Events\Base\Wiki\WikiDeletedEvent;
use App\Filament\Resources\Wiki\Anime\Theme as ThemeFilament;
use App\Models\Wiki\Anime;
use App\Models\Wiki\Anime\AnimeTheme;
use App\Nova\Resources\Wiki\Anime\Theme as ThemeResource;
/**
* Class ThemeDeleted.
@@ -56,7 +55,7 @@ class ThemeDeleted extends WikiDeletedEvent
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -65,18 +64,6 @@ class ThemeDeleted extends WikiDeletedEvent
return "Theme '{$this->getModel()->getName()}' has been deleted for Anime '{$this->anime->getName()}'. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = ThemeResource::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
+1 -14
View File
@@ -7,7 +7,6 @@ namespace App\Events\Wiki\Artist;
use App\Events\Base\Wiki\WikiDeletedEvent;
use App\Filament\Resources\Wiki\Artist as ArtistFilament;
use App\Models\Wiki\Artist;
use App\Nova\Resources\Wiki\Artist as ArtistResource;
/**
* Class ArtistDeleted.
@@ -47,7 +46,7 @@ class ArtistDeleted extends WikiDeletedEvent
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -56,18 +55,6 @@ class ArtistDeleted extends WikiDeletedEvent
return "Artist '{$this->getModel()->getName()}' has been deleted. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = ArtistResource::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
+1 -14
View File
@@ -7,7 +7,6 @@ namespace App\Events\Wiki\Audio;
use App\Events\Base\Wiki\WikiDeletedEvent;
use App\Filament\Resources\Wiki\Audio as AudioFilament;
use App\Models\Wiki\Audio;
use App\Nova\Resources\Wiki\Audio as AudioResource;
/**
* Class AudioDeleted.
@@ -47,7 +46,7 @@ class AudioDeleted extends WikiDeletedEvent
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -56,18 +55,6 @@ class AudioDeleted extends WikiDeletedEvent
return "Audio '{$this->getModel()->getName()}' has been deleted. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = AudioResource::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
@@ -7,7 +7,6 @@ namespace App\Events\Wiki\ExternalResource;
use App\Events\Base\Wiki\WikiDeletedEvent;
use App\Filament\Resources\Wiki\ExternalResource as ExternalResourceFilament;
use App\Models\Wiki\ExternalResource;
use App\Nova\Resources\Wiki\ExternalResource as ExternalResourceResource;
/**
* Class ExternalResourceDeleted.
@@ -47,7 +46,7 @@ class ExternalResourceDeleted extends WikiDeletedEvent
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -56,18 +55,6 @@ class ExternalResourceDeleted extends WikiDeletedEvent
return "Resource '{$this->getModel()->getName()}' has been deleted. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = ExternalResourceResource::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
+1 -14
View File
@@ -11,7 +11,6 @@ use App\Models\Wiki\Anime\AnimeTheme;
use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
use App\Models\Wiki\Group;
use App\Models\Wiki\Video;
use App\Nova\Resources\Wiki\Group as GroupResource;
/**
* Class GroupDeleted.
@@ -51,7 +50,7 @@ class GroupDeleted extends WikiDeletedEvent implements UpdateRelatedIndicesEvent
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -60,18 +59,6 @@ class GroupDeleted extends WikiDeletedEvent implements UpdateRelatedIndicesEvent
return "Group '{$this->getModel()->getName()}' has been deleted. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = GroupResource::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
+1 -14
View File
@@ -7,7 +7,6 @@ namespace App\Events\Wiki\Image;
use App\Events\Base\Wiki\WikiDeletedEvent;
use App\Filament\Resources\Wiki\Image as ImageFilament;
use App\Models\Wiki\Image;
use App\Nova\Resources\Wiki\Image as ImageResource;
/**
* Class ImageDeleted.
@@ -47,7 +46,7 @@ class ImageDeleted extends WikiDeletedEvent
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -56,18 +55,6 @@ class ImageDeleted extends WikiDeletedEvent
return "Image '{$this->getModel()->getName()}' has been deleted. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = ImageResource::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
+1 -14
View File
@@ -7,7 +7,6 @@ namespace App\Events\Wiki\Series;
use App\Events\Base\Wiki\WikiDeletedEvent;
use App\Filament\Resources\Wiki\Series as SeriesFilament;
use App\Models\Wiki\Series;
use App\Nova\Resources\Wiki\Series as SeriesResource;
/**
* Class SeriesDeleted.
@@ -47,7 +46,7 @@ class SeriesDeleted extends WikiDeletedEvent
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -56,18 +55,6 @@ class SeriesDeleted extends WikiDeletedEvent
return "Series '{$this->getModel()->getName()}' has been deleted. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = SeriesResource::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
+1 -14
View File
@@ -12,7 +12,6 @@ use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
use App\Models\Wiki\Artist;
use App\Models\Wiki\Song;
use App\Models\Wiki\Video;
use App\Nova\Resources\Wiki\Song as SongResource;
/**
* Class SongDeleted.
@@ -52,7 +51,7 @@ class SongDeleted extends WikiDeletedEvent implements UpdateRelatedIndicesEvent
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -61,18 +60,6 @@ class SongDeleted extends WikiDeletedEvent implements UpdateRelatedIndicesEvent
return "Song '{$this->getModel()->getName()}' has been deleted. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = SongResource::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
+1 -14
View File
@@ -7,7 +7,6 @@ namespace App\Events\Wiki\Studio;
use App\Events\Base\Wiki\WikiDeletedEvent;
use App\Filament\Resources\Wiki\Studio as StudioFilament;
use App\Models\Wiki\Studio;
use App\Nova\Resources\Wiki\Studio as StudioResource;
/**
* Class StudioDeleted.
@@ -47,7 +46,7 @@ class StudioDeleted extends WikiDeletedEvent
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -56,18 +55,6 @@ class StudioDeleted extends WikiDeletedEvent
return "Studio '{$this->getModel()->getName()}' has been deleted. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = StudioResource::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
@@ -7,7 +7,6 @@ namespace App\Events\Wiki\Video\Script;
use App\Events\Base\Wiki\WikiDeletedEvent;
use App\Filament\Resources\Wiki\Video\Script as VideoScriptFilament;
use App\Models\Wiki\Video\VideoScript;
use App\Nova\Resources\Wiki\Video\Script;
/**
* Class VideoScriptDeleted.
@@ -47,7 +46,7 @@ class VideoScriptDeleted extends WikiDeletedEvent
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -56,18 +55,6 @@ class VideoScriptDeleted extends WikiDeletedEvent
return "Script '**{$this->getModel()->getName()}**' has been deleted. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = Script::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
+1 -14
View File
@@ -7,7 +7,6 @@ namespace App\Events\Wiki\Video;
use App\Events\Base\Wiki\WikiDeletedEvent;
use App\Filament\Resources\Wiki\Video as VideoFilament;
use App\Models\Wiki\Video;
use App\Nova\Resources\Wiki\Video as VideoResource;
/**
* Class VideoDeleted.
@@ -47,7 +46,7 @@ class VideoDeleted extends WikiDeletedEvent
}
/**
* Get the message for the nova notification.
* Get the message for the filament notification.
*
* @return string
*/
@@ -56,18 +55,6 @@ class VideoDeleted extends WikiDeletedEvent
return "Video '{$this->getModel()->getName()}' has been deleted. It will be automatically pruned in one week. Please review.";
}
/**
* Get the URL for the nova notification.
*
* @return string
*/
protected function getNovaNotificationUrl(): string
{
$uriKey = VideoResource::uriKey();
return "/resources/$uriKey/{$this->getModel()->getKey()}";
}
/**
* Get the URL for the Filament notification.
*
-33
View File
@@ -1,33 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Listeners;
use App\Contracts\Events\NovaNotificationEvent;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
/**
* Class NotifiesNovaUsers.
*/
class NotifiesNovaUsers implements ShouldQueue
{
use InteractsWithQueue;
/**
* Handle the event.
*
* @param NovaNotificationEvent $event
* @return void
*/
public function handle(NovaNotificationEvent $event): void
{
if ($event->shouldSendNovaNotification()) {
$notification = $event->getNovaNotification();
foreach ($event->getNovaNotificationRecipients() as $user) {
$user->notify($notification);
}
}
}
}
-3
View File
@@ -10,7 +10,6 @@ use App\Events\Admin\Announcement\AnnouncementRestored;
use App\Events\Admin\Announcement\AnnouncementUpdated;
use App\Models\BaseModel;
use Database\Factories\Admin\AnnouncementFactory;
use Laravel\Nova\Actions\Actionable;
/**
* Class Announcement.
@@ -22,8 +21,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class Announcement extends BaseModel
{
use Actionable;
final public const TABLE = 'announcements';
final public const ATTRIBUTE_CONTENT = 'content';
-3
View File
@@ -10,7 +10,6 @@ use App\Events\Admin\Dump\DumpRestored;
use App\Events\Admin\Dump\DumpUpdated;
use App\Models\BaseModel;
use Database\Factories\Admin\DumpFactory;
use Laravel\Nova\Actions\Actionable;
/**
* Class Dump.
@@ -22,8 +21,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class Dump extends BaseModel
{
use Actionable;
final public const TABLE = 'dumps';
final public const ATTRIBUTE_ID = 'dump_id';
-2
View File
@@ -12,7 +12,6 @@ use Database\Factories\Admin\FeatureFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
use Laravel\Nova\Actions\Actionable;
/**
* Class Feature.
@@ -28,7 +27,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class Feature extends Model
{
use Actionable;
use HasFactory;
final public const TABLE = 'features';
-3
View File
@@ -17,7 +17,6 @@ use Database\Factories\Admin\FeaturedThemeFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Carbon;
use Illuminate\Support\Str;
use Laravel\Nova\Actions\Actionable;
/**
* Class FeaturedTheme.
@@ -36,8 +35,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class FeaturedTheme extends BaseModel
{
use Actionable;
final public const TABLE = 'featured_themes';
final public const ATTRIBUTE_END_AT = 'end_at';
-3
View File
@@ -6,7 +6,6 @@ namespace App\Models\Auth;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
use Laravel\Nova\Actions\Actionable;
use Spatie\Permission\Models\Permission as BasePermission;
/**
@@ -20,8 +19,6 @@ use Spatie\Permission\Models\Permission as BasePermission;
*/
class Permission extends BasePermission
{
use Actionable;
final public const TABLE = 'permissions';
final public const ATTRIBUTE_CREATED_AT = Model::CREATED_AT;
-3
View File
@@ -6,7 +6,6 @@ namespace App\Models\Auth;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Carbon;
use Laravel\Nova\Actions\Actionable;
use Spatie\Permission\Models\Role as BaseRole;
/**
@@ -23,8 +22,6 @@ use Spatie\Permission\Models\Role as BaseRole;
*/
class Role extends BaseRole
{
use Actionable;
final public const TABLE = 'roles';
final public const ATTRIBUTE_COLOR = 'color';
-4
View File
@@ -27,8 +27,6 @@ use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Nova\Actions\Actionable;
use Laravel\Nova\Auth\Impersonatable;
use Laravel\Sanctum\HasApiTokens;
use Laravel\Sanctum\PersonalAccessToken;
use Spatie\Permission\Traits\HasRoles;
@@ -56,11 +54,9 @@ use Spatie\Permission\Traits\HasRoles;
*/
class User extends Authenticatable implements MustVerifyEmail, Nameable, HasSubtitle, FilamentUser, HasAvatar
{
use Actionable;
use HasApiTokens;
use HasFactory;
use HasRoles;
use Impersonatable;
use Notifiable;
use SoftDeletes;
use TwoFactorAuthenticatable;
-3
View File
@@ -10,7 +10,6 @@ use App\Events\Document\Page\PageRestored;
use App\Events\Document\Page\PageUpdated;
use App\Models\BaseModel;
use Database\Factories\Document\PageFactory;
use Laravel\Nova\Actions\Actionable;
/**
* Class Page.
@@ -24,8 +23,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class Page extends BaseModel
{
use Actionable;
final public const TABLE = 'pages';
final public const ATTRIBUTE_BODY = 'body';
-2
View File
@@ -24,7 +24,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Actionable;
/**
* Class Playlist.
@@ -46,7 +45,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class Playlist extends BaseModel implements HasHashids, Viewable
{
use Actionable;
use Searchable;
use InteractsWithViews;
@@ -16,7 +16,6 @@ use App\Models\Wiki\Video;
use Database\Factories\List\Playlist\PlaylistTrackFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Support\Str;
use Laravel\Nova\Actions\Actionable;
use Staudenmeir\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships;
/**
@@ -38,7 +37,6 @@ use Staudenmeir\LaravelAdjacencyList\Eloquent\HasRecursiveRelationships;
*/
class PlaylistTrack extends BaseModel implements HasHashids
{
use Actionable;
use HasRecursiveRelationships;
final public const TABLE = 'playlist_tracks';
-2
View File
@@ -31,7 +31,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Actionable;
/**
* Class Anime.
@@ -56,7 +55,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class Anime extends BaseModel
{
use Actionable;
use Searchable;
final public const TABLE = 'anime';
-2
View File
@@ -14,7 +14,6 @@ use App\Models\Wiki\Anime;
use Database\Factories\Wiki\Anime\AnimeSynonymFactory;
use Elastic\ScoutDriverPlus\Searchable;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Laravel\Nova\Actions\Actionable;
/**
* Class AnimeSynonym.
@@ -29,7 +28,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class AnimeSynonym extends BaseModel
{
use Actionable;
use Searchable;
final public const TABLE = 'anime_synonyms';
-2
View File
@@ -22,7 +22,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Laravel\Nova\Actions\Actionable;
/**
* Class AnimeTheme.
@@ -43,7 +42,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class AnimeTheme extends BaseModel
{
use Actionable;
use Searchable;
final public const TABLE = 'anime_themes';
@@ -22,7 +22,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Laravel\Nova\Actions\Actionable;
use Znck\Eloquent\Relations\BelongsToThrough;
/**
@@ -43,7 +42,6 @@ use Znck\Eloquent\Relations\BelongsToThrough;
*/
class AnimeThemeEntry extends BaseModel
{
use Actionable;
use Searchable;
use \Znck\Eloquent\Traits\BelongsToThrough;
-2
View File
@@ -22,7 +22,6 @@ use Elastic\ScoutDriverPlus\Searchable;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Actionable;
/**
* Class Artist.
@@ -40,7 +39,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class Artist extends BaseModel
{
use Actionable;
use Searchable;
final public const TABLE = 'artists';
-2
View File
@@ -15,7 +15,6 @@ use CyrildeWit\EloquentViewable\InteractsWithViews;
use Database\Factories\Wiki\AudioFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Actionable;
/**
* Class Audio.
@@ -32,7 +31,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class Audio extends BaseModel implements Streamable, Viewable
{
use Actionable;
use InteractsWithViews;
final public const TABLE = 'audios';
-3
View File
@@ -21,7 +21,6 @@ use App\Pivots\Wiki\StudioResource;
use Database\Factories\Wiki\ExternalResourceFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Actionable;
/**
* Class Resource.
@@ -39,8 +38,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class ExternalResource extends BaseModel
{
use Actionable;
final public const TABLE = 'resources';
final public const ATTRIBUTE_EXTERNAL_ID = 'external_id';
-3
View File
@@ -14,7 +14,6 @@ use App\Models\Wiki\Anime\AnimeTheme;
use Database\Factories\Wiki\GroupFactory;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Actionable;
/**
* Class Group.
@@ -28,8 +27,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class Group extends BaseModel
{
use Actionable;
final public const TABLE = 'groups';
final public const ATTRIBUTE_ID = 'group_id';
-3
View File
@@ -23,7 +23,6 @@ use App\Pivots\Wiki\StudioImage;
use Database\Factories\Wiki\ImageFactory;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Actionable;
/**
* Class Image.
@@ -42,8 +41,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class Image extends BaseModel
{
use Actionable;
final public const TABLE = 'images';
final public const ATTRIBUTE_FACET = 'facet';
-2
View File
@@ -15,7 +15,6 @@ use Database\Factories\Wiki\SeriesFactory;
use Elastic\ScoutDriverPlus\Searchable;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Actionable;
/**
* Class Series.
@@ -29,7 +28,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class Series extends BaseModel
{
use Actionable;
use Searchable;
final public const TABLE = 'series';
-2
View File
@@ -20,7 +20,6 @@ use Elastic\ScoutDriverPlus\Searchable;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Actionable;
/**
* Class Song.
@@ -35,7 +34,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class Song extends BaseModel
{
use Actionable;
use Searchable;
final public const TABLE = 'songs';
-2
View File
@@ -19,7 +19,6 @@ use Database\Factories\Wiki\StudioFactory;
use Elastic\ScoutDriverPlus\Searchable;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Actionable;
/**
* Class Studio.
@@ -34,7 +33,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class Studio extends BaseModel
{
use Actionable;
use Searchable;
final public const TABLE = 'studios';
-2
View File
@@ -29,7 +29,6 @@ use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Actionable;
/**
* Class Video.
@@ -58,7 +57,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class Video extends BaseModel implements Streamable, Viewable
{
use Actionable;
use Searchable;
use InteractsWithViews;
-3
View File
@@ -12,7 +12,6 @@ use App\Models\BaseModel;
use App\Models\Wiki\Video;
use Database\Factories\Wiki\Video\VideoScriptFactory;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Laravel\Nova\Actions\Actionable;
/**
* Class VideoScript.
@@ -26,8 +25,6 @@ use Laravel\Nova\Actions\Actionable;
*/
class VideoScript extends BaseModel
{
use Actionable;
final public const TABLE = 'video_scripts';
final public const ATTRIBUTE_ID = 'script_id';
@@ -1,126 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Discord;
use App\Constants\Config\ServiceConstants;
use App\Enums\Discord\EmbedColor;
use App\Enums\Models\Wiki\AnimeSeason;
use App\Enums\Models\Wiki\ImageFacet;
use App\Models\Wiki\Image;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Http\Requests\NovaRequest;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\Http;
use Laravel\Nova\Fields\Text;
class DiscordThreadAction extends Action
{
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.anime.discord.thread.name');
}
/**
* Perform the action on the given models.
*
* @param \Laravel\Nova\Fields\ActionFields $fields
* @param \Illuminate\Support\Collection $models
* @return mixed
*/
public function handle(ActionFields $fields, Collection $models)
{
$anime = $models->first();
$name = $fields->get('name');
$imagePath = $anime->images()->where(Image::ATTRIBUTE_FACET, ImageFacet::COVER_LARGE)->first()->path;
/** @var \Illuminate\Filesystem\FilesystemAdapter */
$imageDisk = Storage::disk(Config::get('image.disk'));
$animepage = json_decode(file_get_contents(base_path('composer.json')), true)['homepage'].'anime/';
$description = '**Synopsis:** '.strip_tags($anime->synopsis)."\n\n".'**Link:** '.$animepage.$anime->slug;
Http::withToken(Config::get('services.discord.token'), 'Bot')
->asMultipart()
->attach('file', file_get_contents($imageDisk->url($imagePath)), 'image.jpg')
->post("https://discord.com/api/v10/channels/{$this->getDiscordChannel()}/threads", [
'payload_json' => json_encode([
'name' => $name,
'applied_tags' => $this->getAppliedTags($anime->season->value),
'message' => [
'embeds' => [
[
'color' => EmbedColor::PURPLE->value,
'title' => $anime->name,
'description' => $description,
]
],
]
])
])->throw();
return $models;
}
/**
* Get Discord forum channel the thread will be created to.
*
* @return string
*/
protected function getDiscordChannel(): string
{
return Config::get(ServiceConstants::SUBMISSIONS_DISCORD_CHANNEL_QUALIFIED);
}
/**
* Get the IDs of the tags applied to the thread.
*
* @param int $season
* @return array
*/
protected function getAppliedTags(int $season): array
{
return match ($season) {
AnimeSeason::WINTER->value => [Config::get('services.discord.submissions_forum_tags.winter')],
AnimeSeason::SPRING->value => [Config::get('services.discord.submissions_forum_tags.spring')],
AnimeSeason::SUMMER->value => [Config::get('services.discord.submissions_forum_tags.summer')],
AnimeSeason::FALL->value => [Config::get('services.discord.submissions_forum_tags.fall')],
default => [],
};
}
/**
* Get the fields available on the action.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request)
{
$anime = $request->findModelQuery()->first();
return array_merge(
parent::fields($request),
[
Text::make(__('nova.actions.discord.thread.name'), 'name')
->default($anime->name ?? '')
->required()
->rules(['required', 'max:100'])
->maxlength(100)
->enforceMaxlength()
->help(__('nova.actions.discord.thread.help'))
]
);
}
}
@@ -1,64 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models;
use App\Actions\Models\AssignHashidsAction as AssignHashids;
use App\Contracts\Models\HasHashids;
use App\Models\BaseModel;
use Exception;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
/**
* Class AssignHashidsAction.
*/
class AssignHashidsAction extends Action
{
/**
* Create a new action instance.
*
* @param string|null $connection
*/
public function __construct(protected readonly ?string $connection = null)
{
}
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.models.assign_hashids.name');
}
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection<int, HasHashids&BaseModel> $models
* @return Collection
*
* @noinspection PhpUnusedParameterInspection
*/
public function handle(ActionFields $fields, Collection $models): Collection
{
$action = new AssignHashids();
foreach ($models as $model) {
try {
$action->assign($model, $this->connection);
} catch (Exception $e) {
$this->markAsFailed($model, $e);
}
}
return $models;
}
}
@@ -1,75 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Auth\Permission;
use App\Models\Auth\Permission;
use App\Models\Auth\Role;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class GiveRoleAction.
*/
class GiveRoleAction extends Action
{
final public const FIELD_ROLE = 'role';
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.permission.give_role.name');
}
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection<int, Permission> $models
* @return Collection<int, Permission>
*/
public function handle(ActionFields $fields, Collection $models): Collection
{
$role = Role::findById(intval($fields->get(self::FIELD_ROLE)));
foreach ($models as $permission) {
$permission->assignRole($role);
}
return $models;
}
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
$roles = Role::all([Role::ATTRIBUTE_ID, Role::ATTRIBUTE_NAME])
->keyBy(Role::ATTRIBUTE_ID)
->map(fn (Role $role) => $role->name)
->toArray();
return [
Select::make(__('nova.resources.singularLabel.role'), self::FIELD_ROLE)
->searchable()
->required()
->options($roles)
->rules('required'),
];
}
}
@@ -1,75 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Auth\Permission;
use App\Models\Auth\Permission;
use App\Models\Auth\Role;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class RevokeRoleAction.
*/
class RevokeRoleAction extends Action
{
final public const FIELD_ROLE = 'role';
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.permission.revoke_role.name');
}
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection<int, Permission> $models
* @return Collection<int, Permission>
*/
public function handle(ActionFields $fields, Collection $models): Collection
{
$role = Role::findById(intval($fields->get(self::FIELD_ROLE)));
foreach ($models as $permission) {
$permission->removeRole($role);
}
return $models;
}
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
$roles = Role::all([Role::ATTRIBUTE_ID, Role::ATTRIBUTE_NAME])
->keyBy(Role::ATTRIBUTE_ID)
->map(fn (Role $role) => $role->name)
->toArray();
return [
Select::make(__('nova.resources.singularLabel.role'), self::FIELD_ROLE)
->searchable()
->required()
->options($roles)
->rules('required'),
];
}
}
@@ -1,75 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Auth\Role;
use App\Models\Auth\Permission;
use App\Models\Auth\Role;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class GivePermissionAction.
*/
class GivePermissionAction extends Action
{
final public const FIELD_PERMISSION = 'permission';
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.role.give_permission.name');
}
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection<int, Role> $models
* @return Collection<int, Role>
*/
public function handle(ActionFields $fields, Collection $models): Collection
{
$permission = Permission::findById(intval($fields->get(self::FIELD_PERMISSION)));
foreach ($models as $role) {
$role->givePermissionTo($permission);
}
return $models;
}
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
$permissions = Permission::all([Permission::ATTRIBUTE_ID, Permission::ATTRIBUTE_NAME])
->keyBy(Permission::ATTRIBUTE_ID)
->map(fn (Permission $permission) => $permission->name)
->toArray();
return [
Select::make(__('nova.resources.singularLabel.permission'), self::FIELD_PERMISSION)
->searchable()
->required()
->options($permissions)
->rules('required'),
];
}
}
@@ -1,75 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Auth\Role;
use App\Models\Auth\Permission;
use App\Models\Auth\Role;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class RevokePermissionAction.
*/
class RevokePermissionAction extends Action
{
final public const FIELD_PERMISSION = 'permission';
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.role.revoke_permission.name');
}
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection<int, Role> $models
* @return Collection<int, Role>
*/
public function handle(ActionFields $fields, Collection $models): Collection
{
$permission = Permission::findById(intval($fields->get(self::FIELD_PERMISSION)));
foreach ($models as $role) {
$role->revokePermissionTo($permission);
}
return $models;
}
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
$permissions = Permission::all([Permission::ATTRIBUTE_ID, Permission::ATTRIBUTE_NAME])
->keyBy(Permission::ATTRIBUTE_ID)
->map(fn (Permission $permission) => $permission->name)
->toArray();
return [
Select::make(__('nova.resources.singularLabel.permission'), self::FIELD_PERMISSION)
->searchable()
->required()
->options($permissions)
->rules('required'),
];
}
}
@@ -1,75 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Auth\User;
use App\Models\Auth\Permission;
use App\Models\Auth\User;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class GivePermissionAction.
*/
class GivePermissionAction extends Action
{
final public const FIELD_PERMISSION = 'permission';
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.user.give_permission.name');
}
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection<int, User> $models
* @return Collection<int, User>
*/
public function handle(ActionFields $fields, Collection $models): Collection
{
$permission = Permission::findById(intval($fields->get(self::FIELD_PERMISSION)));
foreach ($models as $user) {
$user->givePermissionTo($permission);
}
return $models;
}
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
$permissions = Permission::all([Permission::ATTRIBUTE_ID, Permission::ATTRIBUTE_NAME])
->keyBy(Permission::ATTRIBUTE_ID)
->map(fn (Permission $permission) => $permission->name)
->toArray();
return [
Select::make(__('nova.resources.singularLabel.permission'), self::FIELD_PERMISSION)
->searchable()
->required()
->options($permissions)
->rules('required'),
];
}
}
@@ -1,75 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Auth\User;
use App\Models\Auth\Role;
use App\Models\Auth\User;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class GiveRoleAction.
*/
class GiveRoleAction extends Action
{
final public const FIELD_ROLE = 'role';
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.user.give_role.name');
}
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection<int, User> $models
* @return Collection<int, User>
*/
public function handle(ActionFields $fields, Collection $models): Collection
{
$role = Role::findById(intval($fields->get(self::FIELD_ROLE)));
foreach ($models as $user) {
$user->assignRole($role);
}
return $models;
}
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
$roles = Role::all([Role::ATTRIBUTE_ID, Role::ATTRIBUTE_NAME])
->keyBy(Role::ATTRIBUTE_ID)
->map(fn (Role $role) => $role->name)
->toArray();
return [
Select::make(__('nova.resources.singularLabel.role'), self::FIELD_ROLE)
->searchable()
->required()
->options($roles)
->rules('required'),
];
}
}
@@ -1,75 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Auth\User;
use App\Models\Auth\Permission;
use App\Models\Auth\User;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class RevokePermissionAction.
*/
class RevokePermissionAction extends Action
{
final public const FIELD_PERMISSION = 'permission';
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.user.revoke_permission.name');
}
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection<int, User> $models
* @return Collection<int, User>
*/
public function handle(ActionFields $fields, Collection $models): Collection
{
$permission = Permission::findById(intval($fields->get(self::FIELD_PERMISSION)));
foreach ($models as $user) {
$user->revokePermissionTo($permission);
}
return $models;
}
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
$permissions = Permission::all([Permission::ATTRIBUTE_ID, Permission::ATTRIBUTE_NAME])
->keyBy(Permission::ATTRIBUTE_ID)
->map(fn (Permission $permission) => $permission->name)
->toArray();
return [
Select::make(__('nova.resources.singularLabel.permission'), self::FIELD_PERMISSION)
->searchable()
->required()
->options($permissions)
->rules('required'),
];
}
}
@@ -1,75 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Auth\User;
use App\Models\Auth\Role;
use App\Models\Auth\User;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class RevokeRoleAction.
*/
class RevokeRoleAction extends Action
{
final public const FIELD_ROLE = 'role';
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.user.revoke_role.name');
}
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection<int, User> $models
* @return Collection<int, User>
*/
public function handle(ActionFields $fields, Collection $models): Collection
{
$role = Role::findById(intval($fields->get(self::FIELD_ROLE)));
foreach ($models as $user) {
$user->removeRole($role);
}
return $models;
}
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
$roles = Role::all([Role::ATTRIBUTE_ID, Role::ATTRIBUTE_NAME])
->keyBy(Role::ATTRIBUTE_ID)
->map(fn (Role $role) => $role->name)
->toArray();
return [
Select::make(__('nova.resources.singularLabel.role'), self::FIELD_ROLE)
->searchable()
->required()
->options($roles)
->rules('required'),
];
}
}
@@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Wiki\Anime;
use App\Models\Wiki\Image;
use App\Nova\Actions\Models\Wiki\AttachImageAction;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
/**
* Class AttachAnimeImageAction.
*/
class AttachAnimeImageAction extends AttachImageAction
{
/**
* Get the relation to the action models.
*
* @param Image $image
* @return BelongsToMany
*/
protected function relation(Image $image): BelongsToMany
{
return $image->anime();
}
}
@@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Wiki\Anime;
use App\Enums\Models\Wiki\ResourceSite;
use App\Models\Wiki\ExternalResource;
use App\Nova\Actions\Models\Wiki\AttachResourceAction;
use App\Rules\Wiki\Resource\AnimeResourceLinkFormatRule;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
/**
* Class AttachAnimeResourceAction.
*/
class AttachAnimeResourceAction extends AttachResourceAction
{
/**
* Get the relation to the action models.
*
* @param ExternalResource $resource
* @return BelongsToMany
*/
protected function relation(ExternalResource $resource): BelongsToMany
{
return $resource->anime();
}
/**
* Get the format validation rule.
*
* @param ResourceSite $site
* @return ValidationRule
*/
protected function getFormatRule(ResourceSite $site): ValidationRule
{
return new AnimeResourceLinkFormatRule($site);
}
}
@@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Wiki\Artist;
use App\Models\Wiki\Image;
use App\Nova\Actions\Models\Wiki\AttachImageAction;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
/**
* Class AttachArtistImageAction.
*/
class AttachArtistImageAction extends AttachImageAction
{
/**
* Get the relation to the action models.
*
* @param Image $image
* @return BelongsToMany
*/
protected function relation(Image $image): BelongsToMany
{
return $image->artists();
}
}
@@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Wiki\Artist;
use App\Enums\Models\Wiki\ResourceSite;
use App\Models\Wiki\ExternalResource;
use App\Nova\Actions\Models\Wiki\AttachResourceAction;
use App\Rules\Wiki\Resource\ArtistResourceLinkFormatRule;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
/**
* Class AttachArtistResourceAction.
*/
class AttachArtistResourceAction extends AttachResourceAction
{
/**
* Get the relation to the action models.
*
* @param ExternalResource $resource
* @return BelongsToMany
*/
protected function relation(ExternalResource $resource): BelongsToMany
{
return $resource->artists();
}
/**
* Get the format validation rule.
*
* @param ResourceSite $site
* @return ValidationRule
*/
protected function getFormatRule(ResourceSite $site): ValidationRule
{
return new ArtistResourceLinkFormatRule($site);
}
}
@@ -1,155 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Wiki;
use App\Enums\Models\Wiki\ImageFacet;
use App\Models\Wiki\Anime;
use App\Models\Wiki\Artist;
use App\Models\Wiki\Image;
use App\Models\Wiki\Studio;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Image as NovaImage;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class AttachImageAction.
*/
abstract class AttachImageAction extends Action
{
/**
* Create a new action instance.
*
* @param ImageFacet[] $facets
*/
public function __construct(protected array $facets)
{
}
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.models.wiki.attach_image.name');
}
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection $models
* @return Collection
*/
public function handle(ActionFields $fields, Collection $models): Collection
{
$images = $this->createImages($fields, $models->first());
foreach ($images as $image) {
if (in_array($image->facet, [ImageFacet::GRILL, ImageFacet::DOCUMENT])) continue;
$relation = $this->relation($image);
$relation->attach($models);
}
return $models;
}
/**
* Create the images.
*
* @param ActionFields $fields
* @param Model|null $model
* @return Image[]
*/
protected function createImages(ActionFields $fields, ?Model $model): array
{
$images = [];
foreach ($this->facets as $facet) {
$image = $fields->get($facet->name);
if (empty($image)) continue;
$fs = Storage::disk(Config::get('image.disk'));
$fsFile = $fs->putFile($this->path($facet, $model), $image);
$image = Image::query()->create([
Image::ATTRIBUTE_FACET => $facet->value,
Image::ATTRIBUTE_PATH => $fsFile,
]);
$images[] = $image;
}
return $images;
}
/**
* Path to storage image in filesystem.
*
* @param ImageFacet $facet
* @param Model|null $model
* @return string
*/
protected function path(ImageFacet $facet, ?Model $model): string
{
if (in_array($facet, [ImageFacet::GRILL, ImageFacet::DOCUMENT])) {
return Str::of(Str::kebab($facet->localize()))
->__toString();
}
return Str::of(Str::kebab(class_basename($model)))
->append(DIRECTORY_SEPARATOR)
->append(Str::kebab($facet->localize()))
->__toString();
}
/**
* Get the relation to the action models.
*
* @param Image $image
* @return BelongsToMany|Image
*/
abstract protected function relation(Image $image): BelongsToMany|Image;
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request): array
{
$fields = [];
$model = $request->findModelQuery()->first();
foreach ($this->facets as $facet) {
if ($model instanceof Anime || $model instanceof Artist || $model instanceof Studio) {
$images = $model->images();
if ($images->where(Image::ATTRIBUTE_FACET, $facet->value)->exists()) continue;
}
$fields[] = NovaImage::make($facet->localize(), $facet->name);
}
return array_merge(
parent::fields($request),
$fields
);
}
}
@@ -1,150 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Wiki;
use App\Enums\Models\Wiki\ResourceSite;
use App\Models\Wiki\Anime;
use App\Models\Wiki\Artist;
use App\Models\Wiki\ExternalResource;
use App\Models\Wiki\Song;
use App\Models\Wiki\Studio;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class AttachResourceAction.
*/
abstract class AttachResourceAction extends Action
{
/**
* Create a new action instance.
*
* @param ResourceSite[] $sites
* @param string|null $actionName
*/
public function __construct(protected array $sites, protected ?string $actionName)
{
}
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return $this->actionName ?? __('nova.actions.models.wiki.attach_resource.name');
}
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection $models
* @return Collection
*/
public function handle(ActionFields $fields, Collection $models): Collection
{
$resources = $this->getOrCreateResource($fields);
foreach ($resources as $resource) {
$relation = $this->relation($resource);
$relation->attach($models);
}
return $models;
}
/**
* Get or Create Resource from link field.
*
* @param ActionFields $fields
* @return ExternalResource[]
*/
protected function getOrCreateResource(ActionFields $fields): array
{
$resources = [];
foreach ($this->sites as $resourceSite) {
$link = $fields->get($resourceSite->name);
if (empty($link)) continue;
$resource = ExternalResource::query()
->where(ExternalResource::ATTRIBUTE_LINK, $link)
->first();
if ($resource === null) {
$resource = ExternalResource::query()->create([
ExternalResource::ATTRIBUTE_EXTERNAL_ID => ResourceSite::parseIdFromLink($link),
ExternalResource::ATTRIBUTE_LINK => $link,
ExternalResource::ATTRIBUTE_SITE => $resourceSite->value,
]);
}
$resources[] = $resource;
}
return $resources;
}
/**
* Get the relation to the action models.
*
* @param ExternalResource $resource
* @return BelongsToMany
*/
abstract protected function relation(ExternalResource $resource): BelongsToMany;
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request): array
{
$fields = [];
$model = $request->findModelQuery()->first();
foreach ($this->sites as $resourceSite) {
if ($model instanceof Anime || $model instanceof Artist || $model instanceof Song || $model instanceof Studio) {
$resources = $model->resources();
if ($resources->where(ExternalResource::ATTRIBUTE_SITE, $resourceSite->value)->exists()) continue;
}
$resourceSiteLower = strtolower($resourceSite->name);
$fields[] = Text::make($resourceSite->localize(), $resourceSite->name)
->help(__("nova.actions.models.wiki.attach_resource.fields.{$resourceSiteLower}.help"))
->rules(fn ($request) => [
'max:192',
empty($request->input($resourceSite->name)) ? '' : 'url',
empty($request->input($resourceSite->name)) ? '' : $this->getFormatRule($resourceSite),
]);
}
return array_merge(
parent::fields($request),
$fields
);
}
/**
* Get the format validation rule.
*
* @param ResourceSite $site
* @return ValidationRule
*/
abstract protected function getFormatRule(ResourceSite $site): ValidationRule;
}
@@ -1,65 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Wiki\Audio;
use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
use App\Models\Wiki\Audio;
use App\Models\Wiki\Video;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Log;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
/**
* Class AttachAudioToRelatedVideosAction.
*/
class AttachAudioToRelatedVideosAction extends Action implements ShouldQueue
{
/**
* Create a new action instance.
*/
public function __construct()
{
}
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.audio.attach_related_videos.name');
}
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection<int, Audio> $models
* @return Collection
*/
public function handle(ActionFields $fields, Collection $models): Collection
{
$audio = $models->first();
$video = $audio->videos()->first();
$video->animethemeentries()->each(function (AnimeThemeEntry $firstEntry) use ($audio) {
$theme = $firstEntry->animetheme()->first();
$theme->animethemeentries()->each(function (AnimeThemeEntry $entry) use ($audio) {
$entry->videos()->each(function (Video $video) use ($audio) {
Log::info("Associating Audio '{$audio->filename}' with Video '{$video->filename}'");
$video->audio()->associate($audio)->save();
});
});
});
return $models;
}
}
@@ -1,25 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Wiki\Image;
use App\Models\Wiki\Image;
use App\Nova\Actions\Models\Wiki\AttachImageAction as AttachImageActionAction;
/**
* Class AttachImageAction.
*/
class AttachImageAction extends AttachImageActionAction
{
/**
* Get the relation to the action models.
*
* @param Image $image
* @return Image
*/
protected function relation(Image $image): Image
{
return $image;
}
}
@@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Wiki\Song;
use App\Enums\Models\Wiki\ResourceSite;
use App\Models\Wiki\ExternalResource;
use App\Nova\Actions\Models\Wiki\AttachResourceAction;
use App\Rules\Wiki\Resource\SongResourceLinkFormatRule;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
/**
* Class AttachSongResourceAction.
*/
class AttachSongResourceAction extends AttachResourceAction
{
/**
* Get the relation to the action models.
*
* @param ExternalResource $resource
* @return BelongsToMany
*/
protected function relation(ExternalResource $resource): BelongsToMany
{
return $resource->songs();
}
/**
* Get the format validation rule.
*
* @param ResourceSite $site
* @return ValidationRule
*/
protected function getFormatRule(ResourceSite $site): ValidationRule
{
return new SongResourceLinkFormatRule($site);
}
}
@@ -1,26 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Wiki\Studio;
use App\Models\Wiki\Image;
use App\Nova\Actions\Models\Wiki\AttachImageAction;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
/**
* Class AttachStudioImageAction.
*/
class AttachStudioImageAction extends AttachImageAction
{
/**
* Get the relation to the action models.
*
* @param Image $image
* @return BelongsToMany
*/
protected function relation(Image $image): BelongsToMany
{
return $image->studios();
}
}
@@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Wiki\Studio;
use App\Enums\Models\Wiki\ResourceSite;
use App\Models\Wiki\ExternalResource;
use App\Nova\Actions\Models\Wiki\AttachResourceAction;
use App\Rules\Wiki\Resource\StudioResourceLinkFormatRule;
use Illuminate\Contracts\Validation\ValidationRule;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
/**
* Class AttachStudioResourceAction.
*/
class AttachStudioResourceAction extends AttachResourceAction
{
/**
* Get the relation to the action models.
*
* @param ExternalResource $resource
* @return BelongsToMany
*/
protected function relation(ExternalResource $resource): BelongsToMany
{
return $resource->studios();
}
/**
* Get the format validation rule.
*
* @param ResourceSite $site
* @return ValidationRule
*/
protected function getFormatRule(ResourceSite $site): ValidationRule
{
return new StudioResourceLinkFormatRule($site);
}
}
@@ -1,119 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Models\Wiki\Video;
use App\Actions\Models\Wiki\Video\Audio\BackfillAudioAction as BackfillAudio;
use App\Enums\Actions\Models\Wiki\Video\DeriveSourceVideo;
use App\Enums\Actions\Models\Wiki\Video\OverwriteAudio;
use App\Models\Auth\User;
use App\Models\Wiki\Video;
use App\Nova\Resources\Wiki\Video as VideoResource;
use Exception;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Collection;
use Illuminate\Validation\Rules\Enum;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Http\Requests\NovaRequest;
use Laravel\Nova\Notifications\NovaNotification;
/**
* Class BackfillAudioAction.
*/
class BackfillAudioAction extends Action implements ShouldQueue
{
use InteractsWithQueue;
use Queueable;
final public const DERIVE_SOURCE_VIDEO = 'derive_source_video';
final public const OVERWRITE_AUDIO = 'overwrite_audio';
/**
* Create a new action instance.
*
* @param User $user
*/
public function __construct(protected User $user)
{
}
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.video.backfill.name');
}
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection<int, Video> $models
* @return Collection
*/
public function handle(ActionFields $fields, Collection $models): Collection
{
$uriKey = VideoResource::uriKey();
$deriveSourceVideo = DeriveSourceVideo::from(intval($fields->get(self::DERIVE_SOURCE_VIDEO)));
$overwriteAudio = OverwriteAudio::from(intval($fields->get(self::OVERWRITE_AUDIO)));
foreach ($models as $video) {
$action = new BackfillAudio($video, $deriveSourceVideo, $overwriteAudio);
try {
$result = $action->handle();
if ($result->hasFailed()) {
$this->user->notify(
NovaNotification::make()
->icon('flag')
->message($result->getMessage())
->type(NovaNotification::WARNING_TYPE)
->url("/resources/$uriKey/{$video->getKey()}")
);
}
} catch (Exception $e) {
$this->markAsFailed($video, $e);
}
}
return $models;
}
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
return [
Select::make(__('nova.actions.video.backfill.fields.derive_source.name'), self::DERIVE_SOURCE_VIDEO)
->options(DeriveSourceVideo::asSelectArray())
->displayUsing(fn (?int $enumValue) => DeriveSourceVideo::tryFrom($enumValue)?->localize())
->rules(['required', new Enum(DeriveSourceVideo::class)])
->default(DeriveSourceVideo::YES)
->help(__('nova.actions.video.backfill.fields.derive_source.help')),
Select::make(__('nova.actions.video.backfill.fields.overwrite.name'), self::OVERWRITE_AUDIO)
->options(OverwriteAudio::asSelectArray())
->displayUsing(fn (?int $enumValue) => OverwriteAudio::tryFrom($enumValue)?->localize())
->rules(['required', new Enum(OverwriteAudio::class)])
->default(OverwriteAudio::NO)
->help(__('nova.actions.video.backfill.fields.overwrite.help')),
];
}
}
@@ -1,44 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Repositories;
use App\Concerns\Repositories\ReconcilesRepositories;
use Exception;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Actions\ActionResponse;
use Laravel\Nova\Fields\ActionFields;
/**
* Class ReconcileAction.
*/
abstract class ReconcileAction extends Action
{
use ReconcilesRepositories;
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection $models
* @return ActionResponse
*
* @throws Exception
*
* @noinspection PhpUnusedParameterInspection
*/
public function handle(ActionFields $fields, Collection $models): ActionResponse
{
$result = $this->reconcileRepositories($fields->toArray());
$result->toLog();
if ($result->hasFailed()) {
return Action::danger($result->getMessage());
}
return Action::message($result->getMessage());
}
}
@@ -1,54 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Repositories\Storage\Admin\Dump;
use App\Concerns\Repositories\Admin\ReconcilesDumpRepositories;
use App\Constants\Config\DumpConstants;
use App\Nova\Actions\Repositories\Storage\ReconcileStorageAction;
use Illuminate\Support\Facades\Config;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class ReconcileDumpAction.
*/
class ReconcileDumpAction extends ReconcileStorageAction
{
use ReconcilesDumpRepositories;
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
return [];
}
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.repositories.name', ['label' => __('nova.resources.label.dumps')]);
}
/**
* The name of the disk.
*
* @return string
*/
public function disk(): string
{
return Config::get(DumpConstants::DISK_QUALIFIED);
}
}
@@ -1,62 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Repositories\Storage;
use App\Contracts\Repositories\RepositoryInterface;
use App\Contracts\Storage\InteractsWithDisk;
use App\Nova\Actions\Repositories\ReconcileAction;
use App\Rules\Storage\StorageDirectoryExistsRule;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Storage;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class ReconcileStorageAction.
*/
abstract class ReconcileStorageAction extends ReconcileAction implements InteractsWithDisk
{
/**
* Apply filters to repositories before reconciliation.
*
* @param RepositoryInterface $sourceRepository
* @param RepositoryInterface $destinationRepository
* @param array $data
* @return void
*/
protected function handleFilters(
RepositoryInterface $sourceRepository,
RepositoryInterface $destinationRepository,
array $data = []
): void {
parent::handleFilters($sourceRepository, $destinationRepository, $data);
$path = Arr::get($data, 'path');
if ($path !== null) {
$sourceRepository->handleFilter('path', $path);
$destinationRepository->handleFilter('path', $path);
}
}
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
$fs = Storage::disk($this->disk());
return [
Text::make(__('nova.actions.repositories.storage.fields.path.name'), 'path')
->required()
->rules(['required', 'string', 'doesnt_start_with:/', new StorageDirectoryExistsRule($fs)])
->help(__('nova.actions.repositories.storage.fields.path.help')),
];
}
}
@@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Repositories\Storage\Wiki\Audio;
use App\Concerns\Repositories\Wiki\ReconcilesAudioRepositories;
use App\Constants\Config\AudioConstants;
use App\Nova\Actions\Repositories\Storage\ReconcileStorageAction;
use Illuminate\Support\Facades\Config;
/**
* Class ReconcileAudioAction.
*/
class ReconcileAudioAction extends ReconcileStorageAction
{
use ReconcilesAudioRepositories;
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.repositories.name', ['label' => __('nova.resources.label.audios')]);
}
/**
* The name of the disk.
*
* @return string
*/
public function disk(): string
{
return Config::get(AudioConstants::DEFAULT_DISK_QUALIFIED);
}
}
@@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Repositories\Storage\Wiki\Video;
use App\Concerns\Repositories\Wiki\ReconcilesVideoRepositories;
use App\Constants\Config\VideoConstants;
use App\Nova\Actions\Repositories\Storage\ReconcileStorageAction;
use Illuminate\Support\Facades\Config;
/**
* Class ReconcileVideoAction.
*/
class ReconcileVideoAction extends ReconcileStorageAction
{
use ReconcilesVideoRepositories;
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.repositories.name', ['label' => __('nova.resources.label.videos')]);
}
/**
* The name of the disk.
*
* @return string
*/
public function disk(): string
{
return Config::get(VideoConstants::DEFAULT_DISK_QUALIFIED);
}
}
@@ -1,40 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Repositories\Storage\Wiki\Video\Script;
use App\Concerns\Repositories\Wiki\Video\ReconcilesScriptRepositories;
use App\Constants\Config\VideoConstants;
use App\Nova\Actions\Repositories\Storage\ReconcileStorageAction;
use Illuminate\Support\Facades\Config;
/**
* Class ReconcileScriptAction.
*/
class ReconcileScriptAction extends ReconcileStorageAction
{
use ReconcilesScriptRepositories;
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.repositories.name', ['label' => __('nova.resources.label.video_scripts')]);
}
/**
* The name of the disk.
*
* @return string
*/
public function disk(): string
{
return Config::get(VideoConstants::SCRIPT_DISK_QUALIFIED);
}
}
@@ -1,157 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Admin;
use App\Actions\Storage\Admin\Dump\DumpAction as DumpDatabase;
use Exception;
use Illuminate\Database\MySqlConnection;
use Illuminate\Database\PostgresConnection;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\Rule;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Actions\ActionResponse;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Boolean;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class DatabaseDumpAction.
*/
abstract class DumpAction extends Action
{
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection $models
* @return ActionResponse
*
* @throws Exception
*
* @noinspection PhpUnusedParameterInspection
*/
public function handle(ActionFields $fields, Collection $models): ActionResponse
{
$action = $this->action($fields);
$result = $action->handle();
$result->toLog();
if ($result->hasFailed()) {
return Action::danger($result->getMessage());
}
return Action::message($result->getMessage());
}
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
$connection = DB::connection();
return match (get_class($connection)) {
MySqlConnection::class => $this->fieldsForMySql(),
PostgresConnection::class => $this->fieldsForPostgreSql(),
default => [],
};
}
/**
* Get the fields available on the action for a MySql db connection.
*
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fieldsForMySql(): array
{
return [
Boolean::make(__('nova.actions.dump.dump.fields.mysql.comments.name'), 'comments')
->help(__('nova.actions.dump.dump.fields.mysql.comments.help')),
Boolean::make(__('nova.actions.dump.dump.fields.mysql.skip_comments.name'), 'skip-comments')
->help(__('nova.actions.dump.dump.fields.mysql.skip_comments.help')),
Boolean::make(__('nova.actions.dump.dump.fields.mysql.extended_insert.name'), 'extended-insert')
->help(__('nova.actions.dump.dump.fields.mysql.extended_insert.help')),
Boolean::make(__('nova.actions.dump.dump.fields.mysql.skip_extended_insert.name'), 'skip-extended-insert')
->help(__('nova.actions.dump.dump.fields.mysql.skip_extended_insert.help')),
Boolean::make(__('nova.actions.dump.dump.fields.mysql.single_transaction.name'), 'single-transaction')
->help(__('nova.actions.dump.dump.fields.mysql.single_transaction.help')),
Boolean::make(__('nova.actions.dump.dump.fields.mysql.lock_tables.name'), 'lock-tables')
->help(__('nova.actions.dump.dump.fields.mysql.lock_tables.help')),
Boolean::make(__('nova.actions.dump.dump.fields.mysql.skip_lock_tables.name'), 'skip-lock-tables')
->help(__('nova.actions.dump.dump.fields.mysql.skip_lock_tables.help')),
Boolean::make(__('nova.actions.dump.dump.fields.mysql.skip_column_statistics.name'), 'skip-column-statistics')
->help(__('nova.actions.dump.dump.fields.mysql.skip_column_statistics.help')),
Boolean::make(__('nova.actions.dump.dump.fields.mysql.quick.name'), 'quick')
->help(__('nova.actions.dump.dump.fields.mysql.quick.help')),
Boolean::make(__('nova.actions.dump.dump.fields.mysql.skip_quick.name'), 'skip-quick')
->help(__('nova.actions.dump.dump.fields.mysql.skip_quick.help')),
Text::make(__('nova.actions.dump.dump.fields.mysql.default_character_set.name'), 'default-character-set')
->nullable()
->rules(['nullable', 'string', 'max:192'])
->help(__('nova.actions.dump.dump.fields.mysql.default_character_set.help')),
Select::make(__('nova.actions.dump.dump.fields.mysql.set_gtid_purged.name'), 'set-gtid-purged')
->options([
'OFF' => __('nova.actions.dump.dump.fields.mysql.set_gtid_purged.options.off'),
'ON' => __('nova.actions.dump.dump.fields.mysql.set_gtid_purged.options.on'),
'AUTO' => __('nova.actions.dump.dump.fields.mysql.set_gtid_purged.options.auto'),
])
->nullable()
->rules(['nullable', Rule::in(['OFF', 'ON', 'AUTO'])->__toString()])
->help(__('nova.actions.dump.dump.fields.mysql.set_gtid_purged.help')),
Boolean::make(__('nova.actions.dump.dump.fields.mysql.no_create_info.name'), 'no-create-info')
->help(__('nova.actions.dump.dump.fields.mysql.no_create_info.help')),
];
}
/**
* Get the fields available on the action for a PostgreSql db connection.
*
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fieldsForPostgreSql(): array
{
return [
Boolean::make(__('nova.actions.dump.dump.fields.postgresql.inserts.name'), 'inserts')
->help(__('nova.actions.dump.dump.fields.postgresql.inserts.help')),
Boolean::make(__('nova.actions.dump.dump.fields.postgresql.data_only.name'), 'data-only')
->help(__('nova.actions.dump.dump.fields.postgresql.data_only.help')),
];
}
/**
* Get the underlying action.
*
* @param ActionFields $fields
* @return DumpDatabase
*/
abstract protected function action(ActionFields $fields): DumpDatabase;
}
@@ -1,38 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Admin;
use App\Actions\Storage\Admin\Dump\DumpAction as DumpDatabase;
use App\Actions\Storage\Admin\Dump\DumpDocumentAction as DumpDocumentDatabase;
use Laravel\Nova\Fields\ActionFields;
/**
* Class DumpDocumentAction.
*/
class DumpDocumentAction extends DumpAction
{
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.dump.dump.name.document');
}
/**
* Get the underlying action.
*
* @param ActionFields $fields
* @return DumpDatabase
*/
protected function action(ActionFields $fields): DumpDatabase
{
return new DumpDocumentDatabase($fields->toArray());
}
}
@@ -1,38 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Admin;
use App\Actions\Storage\Admin\Dump\DumpAction as DumpDatabase;
use App\Actions\Storage\Admin\Dump\DumpWikiAction as DumpWikiDatabase;
use Laravel\Nova\Fields\ActionFields;
/**
* Class DumpWikiAction.
*/
class DumpWikiAction extends DumpAction
{
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.dump.dump.name.wiki');
}
/**
* Get the underlying action.
*
* @param ActionFields $fields
* @return DumpDatabase
*/
protected function action(ActionFields $fields): DumpDatabase
{
return new DumpWikiDatabase($fields->toArray());
}
}
@@ -1,42 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Admin;
use App\Actions\Storage\Admin\Dump\PruneDumpAction as PruneDump;
use App\Nova\Actions\Storage\Base\PruneAction;
use Illuminate\Support\Collection;
use Laravel\Nova\Fields\ActionFields;
/**
* Class PruneDumpAction.
*/
class PruneDumpAction extends PruneAction
{
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.dump.prune.name');
}
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection $models
* @return PruneDump
*/
protected function action(ActionFields $fields, Collection $models): PruneDump
{
$hours = $fields->get('hours');
return new PruneDump(intval($hours));
}
}
@@ -1,25 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Base;
use App\Actions\Storage\Base\DeleteAction as BaseDeleteAction;
use App\Nova\Actions\Storage\StorageAction;
use Illuminate\Support\Collection;
use Laravel\Nova\Fields\ActionFields;
/**
* Class DeleteAction.
*/
abstract class DeleteAction extends StorageAction
{
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection $models
* @return BaseDeleteAction
*/
abstract protected function action(ActionFields $fields, Collection $models): BaseDeleteAction;
}
@@ -1,68 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Base;
use App\Actions\Storage\Base\MoveAction as BaseMoveAction;
use App\Contracts\Storage\InteractsWithDisk;
use App\Nova\Actions\Storage\StorageAction;
use App\Rules\Storage\StorageFileDirectoryExistsRule;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class MoveAction.
*/
abstract class MoveAction extends StorageAction implements InteractsWithDisk
{
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
$defaultPath = $this->defaultPath($request);
$fs = Storage::disk($this->disk());
return [
Text::make(__('nova.actions.storage.move.fields.path.name'), 'path')
->required()
->rules(['required', 'string', 'doesnt_start_with:/', "ends_with:{$this->allowedFileExtension()}", new StorageFileDirectoryExistsRule($fs)])
->default(fn () => $defaultPath)
->help(__('nova.actions.storage.move.fields.path.help')),
];
}
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection $models
* @return BaseMoveAction
*/
abstract protected function action(ActionFields $fields, Collection $models): BaseMoveAction;
/**
* Resolve the default value for the path field.
*
* @param NovaRequest $request
* @return string|null
*/
abstract protected function defaultPath(NovaRequest $request): ?string;
/**
* The file extension that the path must end with.
*
* @return string
*/
abstract protected function allowedFileExtension(): string;
}
@@ -1,43 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Base;
use App\Actions\Storage\Base\PruneAction as BasePruneAction;
use App\Nova\Actions\Storage\StorageAction;
use Illuminate\Support\Collection;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Number;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class PruneAction.
*/
abstract class PruneAction extends StorageAction
{
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection $models
* @return BasePruneAction
*/
abstract protected function action(ActionFields $fields, Collection $models): BasePruneAction;
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
return [
Number::make(__('nova.actions.storage.prune.fields.hours.name'), 'hours')
->help(__('nova.actions.storage.prune.fields.hours.help')),
];
}
}
@@ -1,67 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Base;
use App\Actions\Storage\Base\UploadAction as BaseUploadAction;
use App\Contracts\Storage\InteractsWithDisk;
use App\Nova\Actions\Storage\StorageAction;
use App\Rules\Storage\StorageDirectoryExistsRule;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\File;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class UploadAction.
*/
abstract class UploadAction extends StorageAction implements InteractsWithDisk
{
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function fields(NovaRequest $request): array
{
$fs = Storage::disk($this->disk());
return [
File::make(__('nova.actions.storage.upload.fields.file.name'), 'file')
->required()
->rules($this->fileRules())
->help(__('nova.actions.storage.upload.fields.file.help')),
Text::make(__('nova.actions.storage.upload.fields.path.name'), 'path')
->rules(fn ($request) => [
'doesnt_start_with:/',
'doesnt_end_with:/',
empty($request->input('path')) ? '' : 'string',
empty($request->input('path')) ? '' : new StorageDirectoryExistsRule($fs),
])
->help(__('nova.actions.storage.upload.fields.path.help')),
];
}
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection $models
* @return BaseUploadAction
*/
abstract protected function action(ActionFields $fields, Collection $models): BaseUploadAction;
/**
* Get the file validation rules.
*
* @return array
*/
abstract protected function fileRules(): array;
}
@@ -1,52 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage;
use App\Contracts\Actions\Storage\StorageAction as BaseStorageAction;
use Illuminate\Support\Collection;
use Laravel\Nova\Actions\Action;
use Laravel\Nova\Actions\ActionResponse;
use Laravel\Nova\Fields\ActionFields;
/**
* Class StorageAction.
*/
abstract class StorageAction extends Action
{
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection $models
* @return BaseStorageAction
*/
abstract protected function action(ActionFields $fields, Collection $models): BaseStorageAction;
/**
* Perform the action on the given models.
*
* @param ActionFields $fields
* @param Collection $models
* @return ActionResponse
*/
public function handle(ActionFields $fields, Collection $models): ActionResponse
{
$action = $this->action($fields, $models);
$storageResults = $action->handle();
$storageResults->toLog();
$action->then($storageResults);
$actionResult = $storageResults->toActionResult();
if ($actionResult->hasFailed()) {
return Action::danger($actionResult->getMessage());
}
return Action::message($actionResult->getMessage());
}
}
@@ -1,43 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Wiki\Audio;
use App\Actions\Storage\Wiki\Audio\DeleteAudioAction as DeleteAudio;
use App\Models\Wiki\Audio;
use App\Nova\Actions\Storage\Base\DeleteAction;
use Illuminate\Support\Collection;
use Laravel\Nova\Fields\ActionFields;
/**
* Class DeleteAudioAction.
*/
class DeleteAudioAction extends DeleteAction
{
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.audio.delete.name');
}
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection<int, Audio> $models
* @return DeleteAudio
*/
protected function action(ActionFields $fields, Collection $models): DeleteAudio
{
$audio = $models->first();
return new DeleteAudio($audio);
}
}
@@ -1,84 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Wiki\Audio;
use App\Actions\Storage\Wiki\Audio\MoveAudioAction as MoveAudio;
use App\Constants\Config\AudioConstants;
use App\Models\Wiki\Audio;
use App\Nova\Actions\Storage\Base\MoveAction;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Config;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class MoveAudioAction.
*/
class MoveAudioAction extends MoveAction
{
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.audio.move.name');
}
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection<int, Audio> $models
* @return MoveAudio
*/
protected function action(ActionFields $fields, Collection $models): MoveAudio
{
/** @var string $path */
$path = $fields->get('path');
$audio = $models->first();
return new MoveAudio($audio, $path);
}
/**
* The name of the disk.
*
* @return string
*/
public function disk(): string
{
return Config::get(AudioConstants::DEFAULT_DISK_QUALIFIED);
}
/**
* Resolve the default value for the path field.
*
* @param NovaRequest $request
* @return string|null
*/
protected function defaultPath(NovaRequest $request): ?string
{
$audio = $request->findModelQuery()->first();
return $audio instanceof Audio
? $audio->path
: null;
}
/**
* The file extension that the path must end with.
*
* @return string
*/
protected function allowedFileExtension(): string
{
return '.ogg';
}
}
@@ -1,101 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Wiki\Audio;
use App\Actions\Storage\Wiki\Audio\UploadAudioAction as UploadAudio;
use App\Constants\Config\AudioConstants;
use App\Nova\Actions\Storage\Base\UploadAction;
use App\Rules\Wiki\Submission\Audio\AudioChannelLayoutStreamRule;
use App\Rules\Wiki\Submission\Audio\AudioChannelsStreamRule;
use App\Rules\Wiki\Submission\Audio\AudioCodecStreamRule;
use App\Rules\Wiki\Submission\Audio\AudioIndexStreamRule;
use App\Rules\Wiki\Submission\Audio\AudioLoudnessIntegratedTargetStreamRule;
use App\Rules\Wiki\Submission\Audio\AudioLoudnessTruePeakStreamRule;
use App\Rules\Wiki\Submission\Audio\AudioSampleRateStreamRule;
use App\Rules\Wiki\Submission\Format\AudioBitrateRestrictionFormatRule;
use App\Rules\Wiki\Submission\Format\EncoderNameFormatRule;
use App\Rules\Wiki\Submission\Format\EncoderVersionFormatRule;
use App\Rules\Wiki\Submission\Format\ExtraneousChaptersFormatRule;
use App\Rules\Wiki\Submission\Format\ExtraneousMetadataFormatRule;
use App\Rules\Wiki\Submission\Format\FormatNameFormatRule;
use App\Rules\Wiki\Submission\Format\TotalStreamsFormatRule;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Config;
use Illuminate\Validation\Rules\File as FileRule;
use Laravel\Nova\Fields\ActionFields;
/**
* Class UploadAudioAction.
*/
class UploadAudioAction extends UploadAction
{
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.audio.upload.name');
}
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection $models
* @return UploadAudio
*/
protected function action(ActionFields $fields, Collection $models): UploadAudio
{
/** @var UploadedFile $file */
$file = $fields->get('file');
/** @var string $path */
$path = $fields->get('path');
return new UploadAudio($file, $path);
}
/**
* The name of the disk.
*
* @return string
*/
public function disk(): string
{
return Config::get(AudioConstants::DEFAULT_DISK_QUALIFIED);
}
/**
* Get the file validation rules.
*
* @return array
*/
protected function fileRules(): array
{
return [
'required',
FileRule::types('ogg')->max(200 * 1024),
new TotalStreamsFormatRule(1),
new EncoderNameFormatRule(),
new EncoderVersionFormatRule(),
new FormatNameFormatRule('ogg'),
new AudioBitrateRestrictionFormatRule(),
new ExtraneousMetadataFormatRule(),
new ExtraneousChaptersFormatRule(),
new AudioIndexStreamRule(0),
new AudioCodecStreamRule(),
new AudioSampleRateStreamRule(),
new AudioChannelsStreamRule(),
new AudioChannelLayoutStreamRule(),
new AudioLoudnessTruePeakStreamRule(),
new AudioLoudnessIntegratedTargetStreamRule(),
];
}
}
@@ -1,43 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Wiki\Video;
use App\Actions\Storage\Wiki\Video\DeleteVideoAction as DeleteVideo;
use App\Models\Wiki\Video;
use App\Nova\Actions\Storage\Base\DeleteAction;
use Illuminate\Support\Collection;
use Laravel\Nova\Fields\ActionFields;
/**
* Class DeleteVideoAction.
*/
class DeleteVideoAction extends DeleteAction
{
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.video.delete.name');
}
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection<int, Video> $models
* @return DeleteVideo
*/
protected function action(ActionFields $fields, Collection $models): DeleteVideo
{
$video = $models->first();
return new DeleteVideo($video);
}
}
@@ -1,84 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Wiki\Video;
use App\Actions\Storage\Wiki\Video\MoveVideoAction as MoveVideo;
use App\Constants\Config\VideoConstants;
use App\Models\Wiki\Video;
use App\Nova\Actions\Storage\Base\MoveAction;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Config;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class MoveVideoAction.
*/
class MoveVideoAction extends MoveAction
{
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.video.move.name');
}
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection<int, Video> $models
* @return MoveVideo
*/
protected function action(ActionFields $fields, Collection $models): MoveVideo
{
/** @var string $path */
$path = $fields->get('path');
$video = $models->first();
return new MoveVideo($video, $path);
}
/**
* The name of the disk.
*
* @return string
*/
public function disk(): string
{
return Config::get(VideoConstants::DEFAULT_DISK_QUALIFIED);
}
/**
* Resolve the default value for the path field.
*
* @param NovaRequest $request
* @return string|null
*/
protected function defaultPath(NovaRequest $request): ?string
{
$video = $request->findModelQuery()->first();
return $video instanceof Video
? $video->path
: null;
}
/**
* The file extension that the path must end with.
*
* @return string
*/
protected function allowedFileExtension(): string
{
return '.webm';
}
}
@@ -1,43 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Wiki\Video\Script;
use App\Actions\Storage\Wiki\Video\Script\DeleteScriptAction as DeleteScript;
use App\Models\Wiki\Video\VideoScript;
use App\Nova\Actions\Storage\Base\DeleteAction;
use Illuminate\Support\Collection;
use Laravel\Nova\Fields\ActionFields;
/**
* Class DeleteScriptAction.
*/
class DeleteScriptAction extends DeleteAction
{
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.video_script.delete.name');
}
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection<int, VideoScript> $models
* @return DeleteScript
*/
protected function action(ActionFields $fields, Collection $models): DeleteScript
{
$script = $models->first();
return new DeleteScript($script);
}
}
@@ -1,84 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Wiki\Video\Script;
use App\Actions\Storage\Wiki\Video\Script\MoveScriptAction as MoveScript;
use App\Constants\Config\VideoConstants;
use App\Models\Wiki\Video\VideoScript;
use App\Nova\Actions\Storage\Base\MoveAction;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Config;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class MoveScriptAction.
*/
class MoveScriptAction extends MoveAction
{
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.video_script.move.name');
}
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection<int, VideoScript> $models
* @return MoveScript
*/
protected function action(ActionFields $fields, Collection $models): MoveScript
{
/** @var string $path */
$path = $fields->get('path');
$script = $models->first();
return new MoveScript($script, $path);
}
/**
* The name of the disk.
*
* @return string
*/
public function disk(): string
{
return Config::get(VideoConstants::SCRIPT_DISK_QUALIFIED);
}
/**
* Resolve the default value for the path field.
*
* @param NovaRequest $request
* @return string|null
*/
protected function defaultPath(NovaRequest $request): ?string
{
$script = $request->findModelQuery()->first();
return $script instanceof VideoScript
? $script->path
: null;
}
/**
* The file extension that the path must end with.
*
* @return string
*/
protected function allowedFileExtension(): string
{
return '.txt';
}
}
@@ -1,98 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Wiki\Video\Script;
use App\Actions\Storage\Wiki\Video\Script\UploadScriptAction as UploadScript;
use App\Constants\Config\VideoConstants;
use App\Models\Wiki\Video;
use App\Nova\Actions\Storage\Base\UploadAction;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Config;
use Illuminate\Validation\Rules\File as FileRule;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Hidden;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class UploadScriptAction.
*/
class UploadScriptAction extends UploadAction
{
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.video_script.upload.name');
}
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request): array
{
$model = $request->findModelQuery()->first();
return array_merge(
parent::fields($request),
[
Hidden::make(__('nova.resources.singularLabel.video'), Video::ATTRIBUTE_ID)
->default(fn () => $model instanceof Video ? $model->getKey() : null),
],
);
}
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection $models
* @return UploadScript
*/
protected function action(ActionFields $fields, Collection $models): UploadScript
{
/** @var UploadedFile $file */
$file = $fields->get('file');
/** @var string $path */
$path = $fields->get('path');
/** @var Video|null $video */
$video = Video::query()->find($fields->get(Video::ATTRIBUTE_ID));
return new UploadScript($file, $path, $video);
}
/**
* The name of the disk.
*
* @return string
*/
public function disk(): string
{
return Config::get(VideoConstants::SCRIPT_DISK_QUALIFIED);
}
/**
* Get the file validation rules.
*
* @return array
*/
protected function fileRules(): array
{
return [
'required',
FileRule::types('txt')->max(2 * 1024),
];
}
}
@@ -1,220 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Actions\Storage\Wiki\Video;
use App\Actions\Storage\Wiki\Video\UploadVideoAction as UploadVideo;
use App\Constants\Config\VideoConstants;
use App\Enums\Models\Wiki\AnimeSeason;
use App\Enums\Models\Wiki\VideoOverlap;
use App\Enums\Models\Wiki\VideoSource;
use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
use App\Models\Wiki\Video;
use App\Nova\Actions\Storage\Base\UploadAction;
use App\Rules\Wiki\Submission\Audio\AudioChannelLayoutStreamRule;
use App\Rules\Wiki\Submission\Audio\AudioChannelsStreamRule;
use App\Rules\Wiki\Submission\Audio\AudioCodecStreamRule;
use App\Rules\Wiki\Submission\Audio\AudioIndexStreamRule;
use App\Rules\Wiki\Submission\Audio\AudioLoudnessIntegratedTargetStreamRule;
use App\Rules\Wiki\Submission\Audio\AudioLoudnessTruePeakStreamRule;
use App\Rules\Wiki\Submission\Audio\AudioSampleRateStreamRule;
use App\Rules\Wiki\Submission\Format\EncoderNameFormatRule;
use App\Rules\Wiki\Submission\Format\EncoderVersionFormatRule;
use App\Rules\Wiki\Submission\Format\ExtraneousChaptersFormatRule;
use App\Rules\Wiki\Submission\Format\ExtraneousMetadataFormatRule;
use App\Rules\Wiki\Submission\Format\FormatNameFormatRule;
use App\Rules\Wiki\Submission\Format\TotalStreamsFormatRule;
use App\Rules\Wiki\Submission\Format\VideoBitrateRestrictionFormatRule;
use App\Rules\Wiki\Submission\Video\VideoCodecStreamRule;
use App\Rules\Wiki\Submission\Video\VideoColorPrimariesStreamRule;
use App\Rules\Wiki\Submission\Video\VideoColorSpaceStreamRule;
use App\Rules\Wiki\Submission\Video\VideoColorTransferStreamRule;
use App\Rules\Wiki\Submission\Video\VideoIndexStreamRule;
use App\Rules\Wiki\Submission\Video\VideoPixelFormatStreamRule;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Config;
use Illuminate\Validation\Rules\Enum;
use Illuminate\Validation\Rules\File as FileRule;
use Laravel\Nova\Fields\ActionFields;
use Laravel\Nova\Fields\Boolean;
use Laravel\Nova\Fields\File;
use Laravel\Nova\Fields\Heading;
use Laravel\Nova\Fields\Hidden;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class UploadVideoAction.
*/
class UploadVideoAction extends UploadAction
{
/**
* Get the displayable name of the action.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.actions.video.upload.name');
}
/**
* Get the fields available on the action.
*
* @param NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request): array
{
$parent = $request->findParentModel();
return array_merge(
[
Heading::make(__('nova.resources.singularLabel.video')),
],
parent::fields($request),
[
Hidden::make(__('nova.resources.singularLabel.anime_theme_entry'), AnimeThemeEntry::ATTRIBUTE_ID)
->default(fn () => $parent instanceof AnimeThemeEntry ? $parent->getKey() : null),
Boolean::make(__('nova.fields.video.nc.name'), Video::ATTRIBUTE_NC)
->nullable()
->rules(['nullable', 'boolean'])
->help(__('nova.fields.video.nc.help')),
Boolean::make(__('nova.fields.video.subbed.name'), Video::ATTRIBUTE_SUBBED)
->nullable()
->rules(['nullable', 'boolean'])
->help(__('nova.fields.video.subbed.help')),
Boolean::make(__('nova.fields.video.lyrics.name'), Video::ATTRIBUTE_LYRICS)
->nullable()
->rules(['nullable', 'boolean'])
->help(__('nova.fields.video.lyrics.help')),
Boolean::make(__('nova.fields.video.uncen.name'), Video::ATTRIBUTE_UNCEN)
->nullable()
->rules(['nullable', 'boolean'])
->help(__('nova.fields.video.uncen.help')),
Select::make(__('nova.fields.video.overlap.name'), Video::ATTRIBUTE_OVERLAP)
->options(VideoOverlap::asSelectArray())
->displayUsing(fn (?int $enumValue) => VideoOverlap::tryFrom($enumValue)?->localize())
->nullable()
->rules(['nullable', new Enum(VideoOverlap::class)])
->help(__('nova.fields.video.overlap.help')),
Select::make(__('nova.fields.video.source.name'), Video::ATTRIBUTE_SOURCE)
->options(VideoSource::asSelectArray())
->displayUsing(fn (?int $enumValue) => VideoSource::tryFrom($enumValue)?->localize())
->nullable()
->rules(['nullable', new Enum(VideoSource::class)])
->help(__('nova.fields.video.source.help')),
Heading::make(__('nova.resources.singularLabel.video_script')),
File::make(__('nova.resources.singularLabel.video_script'), 'script')
->nullable()
->rules(['nullable', FileRule::types('txt')->max(2 * 1024)])
->help(__('nova.actions.storage.upload.fields.file.help')),
],
);
}
/**
* Get the underlying storage action.
*
* @param ActionFields $fields
* @param Collection $models
* @return UploadVideo
*/
protected function action(ActionFields $fields, Collection $models): UploadVideo
{
/** @var string|null $path */
$path = $fields->get('path');
/** @var UploadedFile $file */
$file = $fields->get('file');
/** @var AnimeThemeEntry|null $entry */
$entry = AnimeThemeEntry::query()->find($fields->get(AnimeThemeEntry::ATTRIBUTE_ID));
/** @var UploadedFile|null $script */
$script = $fields->get('script');
if ($path === null && $entry !== null) {
$anime = $entry->animetheme->anime;
$year = $anime->year;
$path = $year >= 2000 ?
Str::of(strval($year))
->append('/')
->append(AnimeSeason::tryFrom($anime->season->value)->localize())
->__toString()
: floor($year % 100 / 10).'0s';
}
if ($path === null) {
$video = Video::query()->firstWhere(Video::ATTRIBUTE_BASENAME, $file->getClientOriginalName());
$path = $video instanceof Video ? Str::match('/(\d{4}\/\w+)|(\d{2}+s)/', $video->path) : null;
}
$attributes = [
Video::ATTRIBUTE_NC => $fields->get(Video::ATTRIBUTE_NC),
Video::ATTRIBUTE_SUBBED => $fields->get(Video::ATTRIBUTE_SUBBED),
Video::ATTRIBUTE_LYRICS => $fields->get(Video::ATTRIBUTE_LYRICS),
Video::ATTRIBUTE_UNCEN => $fields->get(Video::ATTRIBUTE_UNCEN),
Video::ATTRIBUTE_OVERLAP => $fields->get(Video::ATTRIBUTE_OVERLAP),
Video::ATTRIBUTE_SOURCE => $fields->get(Video::ATTRIBUTE_SOURCE),
];
return new UploadVideo($file, $path, $attributes, $entry, $script);
}
/**
* The name of the disk.
*
* @return string
*/
public function disk(): string
{
return Config::get(VideoConstants::DEFAULT_DISK_QUALIFIED);
}
/**
* Get the file validation rules.
*
* @return array
*/
protected function fileRules(): array
{
return [
'required',
FileRule::types('webm')->max(200 * 1024),
new TotalStreamsFormatRule(2),
new EncoderNameFormatRule(),
new EncoderVersionFormatRule(),
new FormatNameFormatRule('matroska,webm'),
new VideoBitrateRestrictionFormatRule(),
new ExtraneousMetadataFormatRule(),
new ExtraneousChaptersFormatRule(),
new AudioIndexStreamRule(1),
new AudioCodecStreamRule(),
new AudioSampleRateStreamRule(),
new AudioChannelsStreamRule(),
new AudioChannelLayoutStreamRule(),
new AudioLoudnessTruePeakStreamRule(),
new AudioLoudnessIntegratedTargetStreamRule(),
new VideoIndexStreamRule(),
new VideoCodecStreamRule(),
new VideoPixelFormatStreamRule(),
new VideoColorSpaceStreamRule(),
new VideoColorTransferStreamRule(),
new VideoColorPrimariesStreamRule(),
];
}
}
-46
View File
@@ -1,46 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Dashboards;
use App\Nova\Metrics\Anime\AnimePerDay;
use App\Nova\Metrics\Anime\NewAnime;
use App\Nova\Metrics\Artist\ArtistsPerDay;
use App\Nova\Metrics\Artist\NewArtists;
use App\Nova\Metrics\Series\NewSeries;
use App\Nova\Metrics\Series\SeriesPerDay;
use App\Nova\Metrics\Video\NewVideos;
use App\Nova\Metrics\Video\VideosPerDay;
use Laravel\Nova\Card;
use Laravel\Nova\Dashboards\Main as Dashboard;
/**
* Class Main.
*/
class Main extends Dashboard
{
/**
* Get the cards that should be displayed on the Nova dashboard.
*
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function cards(): array
{
return [
(new NewAnime())->width(Card::ONE_HALF_WIDTH),
(new AnimePerDay())->width(Card::ONE_HALF_WIDTH),
(new NewArtists())->width(Card::ONE_HALF_WIDTH),
(new ArtistsPerDay())->width(Card::ONE_HALF_WIDTH),
(new NewSeries())->width(Card::ONE_HALF_WIDTH),
(new SeriesPerDay())->width(Card::ONE_HALF_WIDTH),
(new NewVideos())->width(Card::ONE_HALF_WIDTH),
(new VideosPerDay())->width(Card::ONE_HALF_WIDTH),
];
}
}
-69
View File
@@ -1,69 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Lenses\Anime;
use App\Enums\Models\Wiki\ImageFacet;
use App\Models\Wiki\Anime;
use App\Models\Wiki\Image;
use App\Nova\Actions\Models\Wiki\Anime\AttachAnimeImageAction;
use Illuminate\Database\Eloquent\Builder;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class AnimeImageLens.
*/
abstract class AnimeImageLens extends AnimeLens
{
/**
* The image facet.
*
* @return ImageFacet
*/
abstract protected static function facet(): ImageFacet;
/**
* Get the displayable name of the lens.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.lenses.anime.images.name', ['facet' => static::facet()->localize()]);
}
/**
* The criteria used to refine the models for the lens.
*
* @param Builder $query
* @return Builder
*/
public static function criteria(Builder $query): Builder
{
return $query->whereDoesntHave(Anime::RELATION_IMAGES, function (Builder $imageQuery) {
$imageQuery->where(Image::ATTRIBUTE_FACET, static::facet()->value);
});
}
/**
* Get the actions available on the lens.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function actions(NovaRequest $request): array
{
return [
(new AttachAnimeImageAction([static::facet()]))
->confirmButtonText(__('nova.actions.models.wiki.attach_image.confirmButtonText'))
->cancelButtonText(__('nova.actions.base.cancelButtonText'))
->exceptOnIndex()
->canSeeWhen('create', Image::class),
];
}
}
-85
View File
@@ -1,85 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Lenses\Anime;
use App\Enums\Models\Wiki\AnimeMediaFormat;
use App\Enums\Models\Wiki\AnimeSeason;
use App\Models\BaseModel;
use App\Models\Wiki\Anime;
use App\Models\Wiki\Anime as AnimeModel;
use App\Nova\Lenses\BaseLens;
use Exception;
use Laravel\Nova\Fields\DateTime;
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Number;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Fields\Textarea;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class AnimeLens.
*/
abstract class AnimeLens extends BaseLens
{
/**
* Get the fields available to the lens.
*
* @param NovaRequest $request
* @return array
*
* @throws Exception
*/
public function fields(NovaRequest $request): array
{
return [
ID::make(__('nova.fields.base.id'), Anime::ATTRIBUTE_ID)
->sortable()
->showOnPreview(),
Text::make(__('nova.fields.anime.name.name'), Anime::ATTRIBUTE_NAME)
->sortable()
->copyable()
->showOnPreview()
->filterable(),
Text::make(__('nova.fields.anime.slug.name'), Anime::ATTRIBUTE_SLUG)
->sortable()
->copyable()
->showOnPreview(),
Number::make(__('nova.fields.anime.year.name'), Anime::ATTRIBUTE_YEAR)
->sortable()
->showOnPreview()
->filterable(),
Select::make(__('nova.fields.anime.season.name'), Anime::ATTRIBUTE_SEASON)
->options(AnimeSeason::asSelectArray())
->displayUsing(fn (?int $enumValue) => AnimeSeason::tryFrom($enumValue)?->localize())
->sortable()
->showOnPreview()
->filterable(),
Select::make(__('nova.fields.anime.media_format.name'), Anime::ATTRIBUTE_MEDIA_FORMAT)
->options(AnimeMediaFormat::asSelectArray())
->displayUsing(fn (?int $enumValue) => AnimeMediaFormat::tryFrom($enumValue ?? 0)?->localize())
->sortable()
->showOnPreview()
->filterable(),
Textarea::make(__('nova.fields.anime.synopsis.name'), AnimeModel::ATTRIBUTE_SYNOPSIS)
->onlyOnPreview(),
DateTime::make(__('nova.fields.base.created_at'), BaseModel::ATTRIBUTE_CREATED_AT)
->onlyOnPreview(),
DateTime::make(__('nova.fields.base.updated_at'), BaseModel::ATTRIBUTE_UPDATED_AT)
->onlyOnPreview(),
DateTime::make(__('nova.fields.base.deleted_at'), BaseModel::ATTRIBUTE_DELETED_AT)
->onlyOnPreview(),
];
}
}
@@ -1,69 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Lenses\Anime;
use App\Enums\Models\Wiki\ResourceSite;
use App\Models\Wiki\Anime;
use App\Models\Wiki\ExternalResource;
use App\Nova\Actions\Models\Wiki\Anime\AttachAnimeResourceAction;
use Illuminate\Database\Eloquent\Builder;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class AnimeResourceLens.
*/
abstract class AnimeResourceLens extends AnimeLens
{
/**
* The resource site.
*
* @return ResourceSite
*/
abstract protected static function site(): ResourceSite;
/**
* Get the displayable name of the lens.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.lenses.anime.resources.name', ['site' => static::site()->localize()]);
}
/**
* The criteria used to refine the models for the lens.
*
* @param Builder $query
* @return Builder
*/
public static function criteria(Builder $query): Builder
{
return $query->whereDoesntHave(Anime::RELATION_RESOURCES, function (Builder $resourceQuery) {
$resourceQuery->where(ExternalResource::ATTRIBUTE_SITE, static::site()->value);
});
}
/**
* Get the actions available on the lens.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function actions(NovaRequest $request): array
{
return [
(new AttachAnimeResourceAction([static::site()], null))
->confirmButtonText(__('nova.actions.models.wiki.attach_resource.confirmButtonText'))
->cancelButtonText(__('nova.actions.base.cancelButtonText'))
->showInline()
->canSeeWhen('create', ExternalResource::class),
];
}
}
@@ -1,95 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Lenses\Anime;
use App\Enums\Models\Wiki\ResourceSite;
use App\Models\Wiki\Anime;
use App\Models\Wiki\ExternalResource;
use App\Nova\Actions\Models\Wiki\Anime\AttachAnimeResourceAction;
use Illuminate\Database\Eloquent\Builder;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Class AnimeStreamingResourceLens.
*/
class AnimeStreamingResourceLens extends AnimeLens
{
/**
* The resources site.
*
* @return ResourceSite[]
*/
protected static function sites(): array
{
return [
ResourceSite::CRUNCHYROLL,
ResourceSite::HIDIVE,
ResourceSite::NETFLIX,
ResourceSite::DISNEY_PLUS,
ResourceSite::HULU,
ResourceSite::AMAZON_PRIME_VIDEO,
];
}
/**
* Get the displayable name of the lens.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function name(): string
{
return __('nova.lenses.anime.streaming_resources.name');
}
/**
* The criteria used to refine the models for the lens.
*
* @param Builder $query
* @return Builder
*/
public static function criteria(Builder $query): Builder
{
return $query->whereDoesntHave(Anime::RELATION_RESOURCES, function (Builder $resourceQuery) {
$resourceQuery->where(function (Builder $query) {
foreach (static::sites() as $site) {
$query->orWhere(ExternalResource::ATTRIBUTE_SITE, $site->value);
}
});
});
}
/**
* Get the actions available on the lens.
*
* @param NovaRequest $request
* @return array
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function actions(NovaRequest $request): array
{
return [
(new AttachAnimeResourceAction(static::sites(), __('nova.actions.models.wiki.attach_streaming_resource.name')))
->confirmButtonText(__('nova.actions.models.wiki.attach_resource.confirmButtonText'))
->cancelButtonText(__('nova.actions.base.cancelButtonText'))
->showInline()
->canSeeWhen('create', ExternalResource::class),
];
}
/**
* Get the URI key for the lens.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function uriKey(): string
{
return 'anime-streaming-resources-lens';
}
}
@@ -1,36 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Lenses\Anime\Image;
use App\Enums\Models\Wiki\ImageFacet;
use App\Nova\Lenses\Anime\AnimeImageLens;
/**
* Class AnimeCoverLargeLens.
*/
class AnimeCoverLargeLens extends AnimeImageLens
{
/**
* The image facet.
*
* @return ImageFacet
*/
protected static function facet(): ImageFacet
{
return ImageFacet::COVER_LARGE;
}
/**
* Get the URI key for the lens.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function uriKey(): string
{
return 'anime-cover-large-lens';
}
}
@@ -1,36 +0,0 @@
<?php
declare(strict_types=1);
namespace App\Nova\Lenses\Anime\Image;
use App\Enums\Models\Wiki\ImageFacet;
use App\Nova\Lenses\Anime\AnimeImageLens;
/**
* Class AnimeCoverSmallLens.
*/
class AnimeCoverSmallLens extends AnimeImageLens
{
/**
* The image facet.
*
* @return ImageFacet
*/
protected static function facet(): ImageFacet
{
return ImageFacet::COVER_SMALL;
}
/**
* Get the URI key for the lens.
*
* @return string
*
* @noinspection PhpMissingParentCallCommonInspection
*/
public function uriKey(): string
{
return 'anime-cover-small-lens';
}
}

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