mirror of
https://github.com/AnimeThemes/animethemes-server.git
synced 2026-07-11 01:24:46 +02:00
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Events\Wiki\Group;
|
||||
|
||||
use App\Contracts\Events\UpdateRelatedIndicesEvent;
|
||||
use App\Events\Base\Wiki\WikiCreatedEvent;
|
||||
use App\Models\Wiki\Anime\AnimeTheme;
|
||||
use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
|
||||
use App\Models\Wiki\Group;
|
||||
use App\Models\Wiki\Video;
|
||||
|
||||
/**
|
||||
* Class GroupCreated.
|
||||
*
|
||||
* @extends WikiCreatedEvent<Group>
|
||||
*/
|
||||
class GroupCreated extends WikiCreatedEvent implements UpdateRelatedIndicesEvent
|
||||
{
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param Group $group
|
||||
*/
|
||||
public function __construct(Group $group)
|
||||
{
|
||||
parent::__construct($group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the model that has fired this event.
|
||||
*
|
||||
* @return Group
|
||||
*/
|
||||
public function getModel(): Group
|
||||
{
|
||||
return $this->model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the description for the Discord message payload.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getDiscordMessageDescription(): string
|
||||
{
|
||||
return "Group '**{$this->getModel()->getName()}**' has been created.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform updates on related indices.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updateRelatedIndices(): void
|
||||
{
|
||||
$group = $this->getModel()->load(Group::RELATION_VIDEOS);
|
||||
|
||||
$group->animethemes->each(function (AnimeTheme $theme) {
|
||||
$theme->searchable();
|
||||
$theme->animethemeentries->each(function (AnimeThemeEntry $entry) {
|
||||
$entry->searchable();
|
||||
$entry->videos->each(fn (Video $video) => $video->searchable());
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Events\Wiki\Group;
|
||||
|
||||
use App\Contracts\Events\UpdateRelatedIndicesEvent;
|
||||
use App\Events\Base\Wiki\WikiDeletedEvent;
|
||||
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.
|
||||
*
|
||||
* @extends WikiDeletedEvent<Group>
|
||||
*/
|
||||
class GroupDeleted extends WikiDeletedEvent implements UpdateRelatedIndicesEvent
|
||||
{
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param Group $group
|
||||
*/
|
||||
public function __construct(Group $group)
|
||||
{
|
||||
parent::__construct($group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the model that has fired this event.
|
||||
*
|
||||
* @return Group
|
||||
*/
|
||||
public function getModel(): Group
|
||||
{
|
||||
return $this->model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the description for the Discord message payload.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getDiscordMessageDescription(): string
|
||||
{
|
||||
return "Group '**{$this->getModel()->getName()}**' has been deleted.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the message for the nova notification.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getNotificationMessage(): string
|
||||
{
|
||||
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()}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform updates on related indices.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updateRelatedIndices(): void
|
||||
{
|
||||
$group = $this->getModel()->load(Group::RELATION_VIDEOS);
|
||||
|
||||
$group->animethemes->each(function (AnimeTheme $theme) {
|
||||
$theme->searchable();
|
||||
$theme->animethemeentries->each(function (AnimeThemeEntry $entry) {
|
||||
$entry->searchable();
|
||||
$entry->videos->each(fn (Video $video) => $video->searchable());
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Events\Wiki\Group;
|
||||
|
||||
use App\Contracts\Events\UpdateRelatedIndicesEvent;
|
||||
use App\Events\BaseEvent;
|
||||
use App\Models\Wiki\Anime\AnimeTheme;
|
||||
use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
|
||||
use App\Models\Wiki\Group;
|
||||
use App\Models\Wiki\Video;
|
||||
|
||||
/**
|
||||
* Class GroupDeleting.
|
||||
*
|
||||
* @extends BaseEvent<Group>
|
||||
*/
|
||||
class GroupDeleting extends BaseEvent implements UpdateRelatedIndicesEvent
|
||||
{
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param Group $group
|
||||
*/
|
||||
public function __construct(Group $group)
|
||||
{
|
||||
parent::__construct($group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the model that has fired this event.
|
||||
*
|
||||
* @return Group
|
||||
*/
|
||||
public function getModel(): Group
|
||||
{
|
||||
return $this->model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform cascading deletes.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updateRelatedIndices(): void
|
||||
{
|
||||
$group = $this->getModel()->load(Group::RELATION_VIDEOS);
|
||||
|
||||
if ($group->isForceDeleting()) {
|
||||
$group->animethemes->each(function (AnimeTheme $theme) {
|
||||
AnimeTheme::withoutEvents(function () use ($theme) {
|
||||
$theme->theme_group()->dissociate();
|
||||
$theme->save();
|
||||
});
|
||||
$theme->searchable();
|
||||
$theme->animethemeentries->each(function (AnimeThemeEntry $entry) {
|
||||
$entry->searchable();
|
||||
$entry->videos->each(fn (Video $video) => $video->searchable());
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Events\Wiki\Group;
|
||||
|
||||
use App\Contracts\Events\UpdateRelatedIndicesEvent;
|
||||
use App\Events\Base\Wiki\WikiRestoredEvent;
|
||||
use App\Models\Wiki\Anime\AnimeTheme;
|
||||
use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
|
||||
use App\Models\Wiki\Group;
|
||||
use App\Models\Wiki\Video;
|
||||
|
||||
/**
|
||||
* Class GroupRestored.
|
||||
*
|
||||
* @extends WikiRestoredEvent<Group>
|
||||
*/
|
||||
class GroupRestored extends WikiRestoredEvent implements UpdateRelatedIndicesEvent
|
||||
{
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param Group $group
|
||||
*/
|
||||
public function __construct(Group $group)
|
||||
{
|
||||
parent::__construct($group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the model that has fired this event.
|
||||
*
|
||||
* @return Group
|
||||
*/
|
||||
public function getModel(): Group
|
||||
{
|
||||
return $this->model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the description for the Discord message payload.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getDiscordMessageDescription(): string
|
||||
{
|
||||
return "Group '**{$this->getModel()->getName()}**' has been restored.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform cascading deletes.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updateRelatedIndices(): void
|
||||
{
|
||||
$group = $this->getModel()->load(Group::RELATION_VIDEOS);
|
||||
|
||||
$group->animethemes->each(function (AnimeTheme $theme) {
|
||||
$theme->searchable();
|
||||
$theme->animethemeentries->each(function (AnimeThemeEntry $entry) {
|
||||
$entry->searchable();
|
||||
$entry->videos->each(fn (Video $video) => $video->searchable());
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Events\Wiki\Group;
|
||||
|
||||
use App\Contracts\Events\UpdateRelatedIndicesEvent;
|
||||
use App\Events\Base\Wiki\WikiUpdatedEvent;
|
||||
use App\Models\Wiki\Anime\AnimeTheme;
|
||||
use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
|
||||
use App\Models\Wiki\Group;
|
||||
use App\Models\Wiki\Video;
|
||||
|
||||
/**
|
||||
* Class GroupUpdated.
|
||||
*
|
||||
* @extends WikiUpdatedEvent<Group>
|
||||
*/
|
||||
class GroupUpdated extends WikiUpdatedEvent implements UpdateRelatedIndicesEvent
|
||||
{
|
||||
/**
|
||||
* Create a new event instance.
|
||||
*
|
||||
* @param Group $group
|
||||
*/
|
||||
public function __construct(Group $group)
|
||||
{
|
||||
parent::__construct($group);
|
||||
$this->initializeEmbedFields($group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the model that has fired this event.
|
||||
*
|
||||
* @return Group
|
||||
*/
|
||||
public function getModel(): Group
|
||||
{
|
||||
return $this->model;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the description for the Discord message payload.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getDiscordMessageDescription(): string
|
||||
{
|
||||
return "Group '**{$this->getModel()->getName()}**' has been updated.";
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform updates on related indices.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function updateRelatedIndices(): void
|
||||
{
|
||||
$group = $this->getModel()->load(Group::RELATION_VIDEOS);
|
||||
|
||||
$group->animethemes->each(function (AnimeTheme $theme) {
|
||||
$theme->searchable();
|
||||
$theme->animethemeentries->each(function (AnimeThemeEntry $entry) {
|
||||
$entry->searchable();
|
||||
$entry->videos->each(fn (Video $video) => $video->searchable());
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Api\Field\Wiki\Anime\Theme;
|
||||
|
||||
use App\Contracts\Http\Api\Field\CreatableField;
|
||||
use App\Contracts\Http\Api\Field\SelectableField;
|
||||
use App\Http\Api\Field\Field;
|
||||
use App\Http\Api\Query\Query;
|
||||
use App\Http\Api\Schema\Schema;
|
||||
use App\Models\Wiki\Anime\AnimeTheme;
|
||||
use App\Models\Wiki\Group;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
/**
|
||||
* Class ThemeGroupIdField.
|
||||
*/
|
||||
class ThemeGroupIdField extends Field implements CreatableField, SelectableField
|
||||
{
|
||||
/**
|
||||
* Create a new field instance.
|
||||
*
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function __construct(Schema $schema)
|
||||
{
|
||||
parent::__construct($schema, AnimeTheme::ATTRIBUTE_THEME_GROUP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the creation validation rules for the field.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function getCreationRules(Request $request): array
|
||||
{
|
||||
return [
|
||||
'required',
|
||||
'integer',
|
||||
Rule::exists(Group::class, Group::ATTRIBUTE_ID),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the field should be included in the select clause of our query.
|
||||
*
|
||||
* @param Query $query
|
||||
* @param Schema $schema
|
||||
* @return bool
|
||||
*/
|
||||
public function shouldSelect(Query $query, Schema $schema): bool
|
||||
{
|
||||
// Needed to match anime relation.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ use App\Models\Wiki\Anime\AnimeTheme;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class ThemeGroupField.
|
||||
* Class ThemeSlugField.
|
||||
*/
|
||||
class ThemeSlugField extends StringField implements CreatableField, UpdatableField
|
||||
{
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Api\Field\Wiki\Group;
|
||||
|
||||
use App\Contracts\Http\Api\Field\CreatableField;
|
||||
use App\Contracts\Http\Api\Field\UpdatableField;
|
||||
use App\Http\Api\Field\StringField;
|
||||
use App\Http\Api\Schema\Schema;
|
||||
use App\Models\Wiki\Group;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class GroupNameField.
|
||||
*/
|
||||
class GroupNameField extends StringField implements CreatableField, UpdatableField
|
||||
{
|
||||
/**
|
||||
* Create a new field instance.
|
||||
*
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function __construct(Schema $schema)
|
||||
{
|
||||
parent::__construct($schema, Group::ATTRIBUTE_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the creation validation rules for the field.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function getCreationRules(Request $request): array
|
||||
{
|
||||
return [
|
||||
'required',
|
||||
'string',
|
||||
'max:192',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the update validation rules for the field.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function getUpdateRules(Request $request): array
|
||||
{
|
||||
return [
|
||||
'sometimes',
|
||||
'required',
|
||||
'string',
|
||||
'max:192',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Api\Field\Wiki\Group;
|
||||
|
||||
use App\Contracts\Http\Api\Field\CreatableField;
|
||||
use App\Contracts\Http\Api\Field\UpdatableField;
|
||||
use App\Http\Api\Field\StringField;
|
||||
use App\Http\Api\Schema\Schema;
|
||||
use App\Models\Wiki\Group;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class GroupSlugField.
|
||||
*/
|
||||
class GroupSlugField extends StringField implements CreatableField, UpdatableField
|
||||
{
|
||||
/**
|
||||
* Create a new field instance.
|
||||
*
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function __construct(Schema $schema)
|
||||
{
|
||||
parent::__construct($schema, Group::ATTRIBUTE_SLUG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the creation validation rules for the field.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function getCreationRules(Request $request): array
|
||||
{
|
||||
return [
|
||||
'required',
|
||||
'string',
|
||||
'max:192',
|
||||
'alpha_dash',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the update validation rules for the field.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function getUpdateRules(Request $request): array
|
||||
{
|
||||
return [
|
||||
'sometimes',
|
||||
'required',
|
||||
'string',
|
||||
'max:192',
|
||||
'alpha_dash',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Api\Field\Wiki\Group;
|
||||
|
||||
use App\Contracts\Http\Api\Field\CreatableField;
|
||||
use App\Contracts\Http\Api\Field\UpdatableField;
|
||||
use App\Http\Api\Field\StringField;
|
||||
use App\Http\Api\Schema\Schema;
|
||||
use App\Models\Wiki\Group;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class GroupVideoFilenameField.
|
||||
*/
|
||||
class GroupVideoFilenameField extends StringField implements CreatableField, UpdatableField
|
||||
{
|
||||
/**
|
||||
* Create a new field instance.
|
||||
*
|
||||
* @param Schema $schema
|
||||
*/
|
||||
public function __construct(Schema $schema)
|
||||
{
|
||||
parent::__construct($schema, Group::ATTRIBUTE_VIDEO_FILENAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the creation validation rules for the field.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function getCreationRules(Request $request): array
|
||||
{
|
||||
return [
|
||||
'required',
|
||||
'string',
|
||||
'max:192',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the update validation rules for the field.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*/
|
||||
public function getUpdateRules(Request $request): array
|
||||
{
|
||||
return [
|
||||
'sometimes',
|
||||
'required',
|
||||
'string',
|
||||
'max:192',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ use App\Http\Api\Field\Base\IdField;
|
||||
use App\Http\Api\Field\Field;
|
||||
use App\Http\Api\Field\Wiki\Anime\Theme\ThemeAnimeIdField;
|
||||
use App\Http\Api\Field\Wiki\Anime\Theme\ThemeGroupField;
|
||||
use App\Http\Api\Field\Wiki\Anime\Theme\ThemeGroupIdField;
|
||||
use App\Http\Api\Field\Wiki\Anime\Theme\ThemeSequenceField;
|
||||
use App\Http\Api\Field\Wiki\Anime\Theme\ThemeSlugField;
|
||||
use App\Http\Api\Field\Wiki\Anime\Theme\ThemeSongIdField;
|
||||
@@ -19,6 +20,7 @@ use App\Http\Api\Schema\Wiki\Anime\Theme\EntrySchema;
|
||||
use App\Http\Api\Schema\Wiki\AnimeSchema;
|
||||
use App\Http\Api\Schema\Wiki\ArtistSchema;
|
||||
use App\Http\Api\Schema\Wiki\AudioSchema;
|
||||
use App\Http\Api\Schema\Wiki\GroupSchema;
|
||||
use App\Http\Api\Schema\Wiki\ImageSchema;
|
||||
use App\Http\Api\Schema\Wiki\SongSchema;
|
||||
use App\Http\Api\Schema\Wiki\VideoSchema;
|
||||
@@ -58,6 +60,7 @@ class ThemeSchema extends EloquentSchema implements SearchableSchema
|
||||
new AllowedInclude(new AnimeSchema(), AnimeTheme::RELATION_ANIME),
|
||||
new AllowedInclude(new ArtistSchema(), AnimeTheme::RELATION_ARTISTS),
|
||||
new AllowedInclude(new EntrySchema(), AnimeTheme::RELATION_ENTRIES),
|
||||
new AllowedInclude(new GroupSchema(), AnimeTheme::RELATION_GROUP),
|
||||
new AllowedInclude(new ImageSchema(), AnimeTheme::RELATION_IMAGES),
|
||||
new AllowedInclude(new SongSchema(), AnimeTheme::RELATION_SONG),
|
||||
new AllowedInclude(new VideoSchema(), AnimeTheme::RELATION_VIDEOS),
|
||||
@@ -83,6 +86,7 @@ class ThemeSchema extends EloquentSchema implements SearchableSchema
|
||||
new ThemeSlugField($this),
|
||||
new ThemeTypeField($this),
|
||||
new ThemeAnimeIdField($this),
|
||||
new ThemeGroupIdField($this),
|
||||
new ThemeSongIdField($this),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -63,6 +63,7 @@ class AnimeSchema extends EloquentSchema implements InteractsWithPivots, Searcha
|
||||
return [
|
||||
new AllowedInclude(new ArtistSchema(), Anime::RELATION_ARTISTS),
|
||||
new AllowedInclude(new AudioSchema(), Anime::RELATION_AUDIO),
|
||||
new AllowedInclude(new GroupSchema(), Anime::RELATION_GROUPS),
|
||||
new AllowedInclude(new EntrySchema(), Anime::RELATION_ENTRIES),
|
||||
new AllowedInclude(new ExternalResourceSchema(), Anime::RELATION_RESOURCES),
|
||||
new AllowedInclude(new ImageSchema(), Anime::RELATION_IMAGES),
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Api\Schema\Wiki;
|
||||
|
||||
use App\Contracts\Http\Api\Schema\SearchableSchema;
|
||||
use App\Http\Api\Field\Base\IdField;
|
||||
use App\Http\Api\Field\Field;
|
||||
use App\Http\Api\Field\Wiki\Group\GroupNameField;
|
||||
use App\Http\Api\Field\Wiki\Group\GroupSlugField;
|
||||
use App\Http\Api\Field\Wiki\Group\GroupVideoFilenameField;
|
||||
use App\Http\Api\Include\AllowedInclude;
|
||||
use App\Http\Api\Schema\EloquentSchema;
|
||||
use App\Http\Api\Schema\Wiki\Anime\ThemeSchema;
|
||||
use App\Http\Api\Schema\Wiki\AnimeSchema;
|
||||
use App\Http\Api\Schema\Wiki\VideoSchema;
|
||||
use App\Http\Resources\Wiki\Resource\GroupResource;
|
||||
use App\Models\Wiki\Group;
|
||||
|
||||
/**
|
||||
* Class GroupSchema.
|
||||
*/
|
||||
class GroupSchema extends EloquentSchema implements SearchableSchema
|
||||
{
|
||||
/**
|
||||
* Get the type of the resource.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function type(): string
|
||||
{
|
||||
return GroupResource::$wrap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the allowed includes.
|
||||
*
|
||||
* @return AllowedInclude[]
|
||||
*/
|
||||
public function allowedIncludes(): array
|
||||
{
|
||||
return [
|
||||
new AllowedInclude(new AnimeSchema(), Group::RELATION_ANIME),
|
||||
new AllowedInclude(new ThemeSchema(), Group::RELATION_THEMES),
|
||||
new AllowedInclude(new VideoSchema(), Group::RELATION_VIDEOS),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the direct fields of the resource.
|
||||
*
|
||||
* @return Field[]
|
||||
*/
|
||||
public function fields(): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::fields(),
|
||||
[
|
||||
new IdField($this, Group::ATTRIBUTE_ID),
|
||||
new GroupNameField($this),
|
||||
new GroupSlugField($this),
|
||||
new GroupVideoFilenameField($this),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Controllers\Api\Wiki;
|
||||
|
||||
use App\Actions\Http\Api\DestroyAction;
|
||||
use App\Actions\Http\Api\ForceDeleteAction;
|
||||
use App\Actions\Http\Api\IndexAction;
|
||||
use App\Actions\Http\Api\RestoreAction;
|
||||
use App\Actions\Http\Api\ShowAction;
|
||||
use App\Actions\Http\Api\StoreAction;
|
||||
use App\Actions\Http\Api\UpdateAction;
|
||||
use App\Http\Api\Query\Query;
|
||||
use App\Http\Controllers\Api\BaseController;
|
||||
use App\Http\Requests\Api\IndexRequest;
|
||||
use App\Http\Requests\Api\ShowRequest;
|
||||
use App\Http\Requests\Api\StoreRequest;
|
||||
use App\Http\Requests\Api\UpdateRequest;
|
||||
use App\Http\Resources\Wiki\Collection\GroupCollection;
|
||||
use App\Http\Resources\Wiki\Resource\GroupResource;
|
||||
use App\Models\Wiki\Group;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
|
||||
/**
|
||||
* Class GroupController.
|
||||
*/
|
||||
class GroupController extends BaseController
|
||||
{
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(Group::class, 'group');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param IndexRequest $request
|
||||
* @param IndexAction $action
|
||||
* @return GroupCollection
|
||||
*/
|
||||
public function index(IndexRequest $request, IndexAction $action): GroupCollection
|
||||
{
|
||||
$query = new Query($request->validated());
|
||||
|
||||
$groups = $query->hasSearchCriteria()
|
||||
? $action->search($query, $request->schema())
|
||||
: $action->index(Group::query(), $query, $request->schema());
|
||||
|
||||
return new GroupCollection($groups, $query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource.
|
||||
*
|
||||
* @param StoreRequest $request
|
||||
* @param StoreAction $action
|
||||
* @return GroupResource
|
||||
*/
|
||||
public function store(StoreRequest $request, StoreAction $action): GroupResource
|
||||
{
|
||||
$group = $action->store(Group::query(), $request->validated());
|
||||
|
||||
return new GroupResource($group, new Query());
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param ShowRequest $request
|
||||
* @param Group $group
|
||||
* @param ShowAction $action
|
||||
* @return GroupResource
|
||||
*/
|
||||
public function show(ShowRequest $request, Group $group, ShowAction $action): GroupResource
|
||||
{
|
||||
$query = new Query($request->validated());
|
||||
|
||||
$show = $action->show($group, $query, $request->schema());
|
||||
|
||||
return new GroupResource($show, $query);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource.
|
||||
*
|
||||
* @param UpdateRequest $request
|
||||
* @param Group $group
|
||||
* @param UpdateAction $action
|
||||
* @return GroupResource
|
||||
*/
|
||||
public function update(UpdateRequest $request, Group $group, UpdateAction $action): GroupResource
|
||||
{
|
||||
$updated = $action->update($group, $request->validated());
|
||||
|
||||
return new GroupResource($updated, new Query());
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource.
|
||||
*
|
||||
* @param Group $group
|
||||
* @param DestroyAction $action
|
||||
* @return GroupResource
|
||||
*/
|
||||
public function destroy(Group $group, DestroyAction $action): GroupResource
|
||||
{
|
||||
$deleted = $action->destroy($group);
|
||||
|
||||
return new GroupResource($deleted, new Query());
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore the specified resource.
|
||||
*
|
||||
* @param Group $group
|
||||
* @param RestoreAction $action
|
||||
* @return GroupResource
|
||||
*/
|
||||
public function restore(Group $group, RestoreAction $action): GroupResource
|
||||
{
|
||||
$restored = $action->restore($group);
|
||||
|
||||
return new GroupResource($restored, new Query());
|
||||
}
|
||||
|
||||
/**
|
||||
* Hard-delete the specified resource.
|
||||
*
|
||||
* @param Group $group
|
||||
* @param ForceDeleteAction $action
|
||||
* @return JsonResponse
|
||||
*/
|
||||
public function forceDelete(Group $group, ForceDeleteAction $action): JsonResponse
|
||||
{
|
||||
$message = $action->forceDelete($group);
|
||||
|
||||
return new JsonResponse([
|
||||
'message' => $message,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Resources\Wiki\Collection;
|
||||
|
||||
use App\Http\Resources\BaseCollection;
|
||||
use App\Http\Resources\Wiki\Resource\GroupResource;
|
||||
use App\Models\Wiki\Group;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
/**
|
||||
* Class GroupCollection.
|
||||
*/
|
||||
class GroupCollection extends BaseCollection
|
||||
{
|
||||
/**
|
||||
* The "data" wrapper that should be applied.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public static $wrap = 'groups';
|
||||
|
||||
/**
|
||||
* Transform the resource into a JSON array.
|
||||
*
|
||||
* @param Request $request
|
||||
* @return array
|
||||
*
|
||||
* @noinspection PhpMissingParentCallCommonInspection
|
||||
*/
|
||||
public function toArray(Request $request): array
|
||||
{
|
||||
return $this->collection->map(fn (Group $group) => new GroupResource($group, $this->query))->all();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Http\Resources\Wiki\Resource;
|
||||
|
||||
use App\Http\Api\Schema\Schema;
|
||||
use App\Http\Api\Schema\Wiki\GroupSchema;
|
||||
use App\Http\Resources\BaseResource;
|
||||
|
||||
/**
|
||||
* Class GroupResource.
|
||||
*/
|
||||
class GroupResource extends BaseResource
|
||||
{
|
||||
/**
|
||||
* The "data" wrapper that should be applied.
|
||||
*
|
||||
* @var string|null
|
||||
*/
|
||||
public static $wrap = 'group';
|
||||
|
||||
/**
|
||||
* Get the resource schema.
|
||||
*
|
||||
* @return Schema
|
||||
*/
|
||||
protected function schema(): Schema
|
||||
{
|
||||
return new GroupSchema();
|
||||
}
|
||||
}
|
||||
@@ -67,6 +67,7 @@ class Anime extends BaseModel
|
||||
final public const RELATION_ARTISTS = 'animethemes.song.artists';
|
||||
final public const RELATION_AUDIO = 'animethemes.animethemeentries.videos.audio';
|
||||
final public const RELATION_ENTRIES = 'animethemes.animethemeentries';
|
||||
final public const RELATION_GROUPS = 'animethemes.theme_group';
|
||||
final public const RELATION_IMAGES = 'images';
|
||||
final public const RELATION_RESOURCES = 'resources';
|
||||
final public const RELATION_SCRIPTS = 'animethemes.animethemeentries.videos.videoscript';
|
||||
|
||||
@@ -13,6 +13,7 @@ use App\Events\Wiki\Anime\Theme\ThemeUpdated;
|
||||
use App\Models\BaseModel;
|
||||
use App\Models\Wiki\Anime;
|
||||
use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
|
||||
use App\Models\Wiki\Group;
|
||||
use App\Models\Wiki\Song;
|
||||
use Database\Factories\Wiki\Anime\AnimeThemeFactory;
|
||||
use Elastic\ScoutDriverPlus\Searchable;
|
||||
@@ -29,6 +30,8 @@ use Laravel\Nova\Actions\Actionable;
|
||||
* @property int $anime_id
|
||||
* @property Collection<int, AnimeThemeEntry> $animethemeentries
|
||||
* @property string|null $group
|
||||
* @property Group|null $theme_group
|
||||
* @property int|null $group_id
|
||||
* @property int|null $sequence
|
||||
* @property string $slug
|
||||
* @property Song|null $song
|
||||
@@ -51,12 +54,14 @@ class AnimeTheme extends BaseModel
|
||||
final public const ATTRIBUTE_SEQUENCE = 'sequence';
|
||||
final public const ATTRIBUTE_SLUG = 'slug';
|
||||
final public const ATTRIBUTE_SONG = 'song_id';
|
||||
final public const ATTRIBUTE_THEME_GROUP = 'group_id';
|
||||
final public const ATTRIBUTE_TYPE = 'type';
|
||||
|
||||
final public const RELATION_ANIME = 'anime';
|
||||
final public const RELATION_ARTISTS = 'song.artists';
|
||||
final public const RELATION_AUDIO = 'animethemeentries.videos.audio';
|
||||
final public const RELATION_ENTRIES = 'animethemeentries';
|
||||
final public const RELATION_GROUP = 'theme_group';
|
||||
final public const RELATION_IMAGES = 'anime.images';
|
||||
final public const RELATION_SONG = 'song';
|
||||
final public const RELATION_SYNONYMS = 'anime.animesynonyms';
|
||||
@@ -70,6 +75,7 @@ class AnimeTheme extends BaseModel
|
||||
protected $fillable = [
|
||||
AnimeTheme::ATTRIBUTE_ANIME,
|
||||
AnimeTheme::ATTRIBUTE_GROUP,
|
||||
AnimeTheme::ATTRIBUTE_THEME_GROUP,
|
||||
AnimeTheme::ATTRIBUTE_SEQUENCE,
|
||||
AnimeTheme::ATTRIBUTE_SLUG,
|
||||
AnimeTheme::ATTRIBUTE_SONG,
|
||||
@@ -165,6 +171,16 @@ class AnimeTheme extends BaseModel
|
||||
return $this->belongsTo(Anime::class, AnimeTheme::ATTRIBUTE_ANIME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the group that the theme uses.
|
||||
*
|
||||
* @return BelongsTo
|
||||
*/
|
||||
public function theme_group(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Group::class, AnimeTheme::ATTRIBUTE_THEME_GROUP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the song that the theme uses.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Models\Wiki;
|
||||
|
||||
use App\Events\Wiki\Group\GroupCreated;
|
||||
use App\Events\Wiki\Group\GroupDeleted;
|
||||
use App\Events\Wiki\Group\GroupDeleting;
|
||||
use App\Events\Wiki\Group\GroupRestored;
|
||||
use App\Events\Wiki\Group\GroupUpdated;
|
||||
use App\Models\BaseModel;
|
||||
use App\Models\Wiki\Anime\AnimeTheme;
|
||||
use Database\Factories\Wiki\GroupFactory;
|
||||
use Elastic\ScoutDriverPlus\Searchable;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Support\Collection;
|
||||
use Laravel\Nova\Actions\Actionable;
|
||||
|
||||
/**
|
||||
* Class Group.
|
||||
*
|
||||
* @property Collection<int, AnimeTheme> $animethemes
|
||||
* @property int $group_id
|
||||
* @property string $name
|
||||
* @property string $slug
|
||||
* @property string|null $video_filename
|
||||
*
|
||||
* @method static GroupFactory factory(...$parameters)
|
||||
*/
|
||||
class Group extends BaseModel
|
||||
{
|
||||
use Actionable;
|
||||
use Searchable;
|
||||
|
||||
final public const TABLE = 'groups';
|
||||
|
||||
final public const ATTRIBUTE_ID = 'group_id';
|
||||
final public const ATTRIBUTE_NAME = 'name';
|
||||
final public const ATTRIBUTE_SLUG = 'slug';
|
||||
final public const ATTRIBUTE_VIDEO_FILENAME = 'video_filename';
|
||||
|
||||
final public const RELATION_ANIME = 'animethemes.anime';
|
||||
final public const RELATION_THEMES = 'animethemes';
|
||||
final public const RELATION_VIDEOS = 'animethemes.animethemeentries.videos';
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var string[]
|
||||
*/
|
||||
protected $fillable = [
|
||||
Group::ATTRIBUTE_NAME,
|
||||
Group::ATTRIBUTE_SLUG,
|
||||
Group::ATTRIBUTE_VIDEO_FILENAME,
|
||||
];
|
||||
|
||||
/**
|
||||
* The event map for the model.
|
||||
*
|
||||
* Allows for object-based events for native Eloquent events.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $dispatchesEvents = [
|
||||
'created' => GroupCreated::class,
|
||||
'deleted' => GroupDeleted::class,
|
||||
'deleting' => GroupDeleting::class,
|
||||
'restored' => GroupRestored::class,
|
||||
'updated' => GroupUpdated::class,
|
||||
];
|
||||
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = Group::TABLE;
|
||||
|
||||
/**
|
||||
* The primary key associated with the table.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $primaryKey = Group::ATTRIBUTE_ID;
|
||||
|
||||
/**
|
||||
* Get name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the themes for the group.
|
||||
*
|
||||
* @return HasMany
|
||||
*/
|
||||
public function animethemes(): HasMany
|
||||
{
|
||||
return $this->hasMany(AnimeTheme::class, AnimeTheme::ATTRIBUTE_THEME_GROUP);
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ use App\Models\Wiki\Anime\AnimeTheme;
|
||||
use App\Nova\Resources\BaseResource;
|
||||
use App\Nova\Resources\Wiki\Anime;
|
||||
use App\Nova\Resources\Wiki\Anime\Theme\Entry;
|
||||
use App\Nova\Resources\Wiki\Group;
|
||||
use App\Nova\Resources\Wiki\Song;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Str;
|
||||
@@ -232,6 +233,15 @@ class Theme extends BaseResource
|
||||
}
|
||||
),
|
||||
|
||||
BelongsTo::make(__('nova.resources.singularLabel.group'), AnimeTheme::RELATION_GROUP, Group::class)
|
||||
->sortable()
|
||||
->filterable()
|
||||
->searchable()
|
||||
->withSubtitles()
|
||||
->nullable()
|
||||
->showCreateRelationButton()
|
||||
->showOnPreview(),
|
||||
|
||||
BelongsTo::make(__('nova.resources.singularLabel.song'), AnimeTheme::RELATION_SONG, Song::class)
|
||||
->sortable()
|
||||
->filterable()
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Nova\Resources\Wiki;
|
||||
|
||||
use App\Models\Wiki\Anime\AnimeTheme;
|
||||
use App\Models\Wiki\Group as GroupModel;
|
||||
use App\Nova\Resources\BaseResource;
|
||||
use App\Nova\Resources\Wiki\Anime\Theme;
|
||||
use Exception;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Laravel\Nova\Fields\HasMany;
|
||||
use Laravel\Nova\Fields\ID;
|
||||
use Laravel\Nova\Fields\Text;
|
||||
use Laravel\Nova\Http\Requests\NovaRequest;
|
||||
use Laravel\Nova\Panel;
|
||||
use Laravel\Nova\Query\Search\Column;
|
||||
|
||||
/**
|
||||
* Class Group.
|
||||
*/
|
||||
class Group extends BaseResource
|
||||
{
|
||||
/**
|
||||
* The model the resource corresponds to.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static string $model = GroupModel::class;
|
||||
|
||||
/**
|
||||
* The single value that should be used to represent the resource when being displayed.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $title = GroupModel::ATTRIBUTE_NAME;
|
||||
|
||||
/**
|
||||
* Get the search result subtitle for the resource.
|
||||
*
|
||||
* @return string|null
|
||||
*
|
||||
* @noinspection PhpMissingParentCallCommonInspection
|
||||
*/
|
||||
public function subtitle(): ?string
|
||||
{
|
||||
$group = $this->model();
|
||||
if ($group instanceof GroupModel) {
|
||||
$theme = $group->animethemes->first();
|
||||
if ($theme instanceof AnimeTheme) {
|
||||
return $theme->anime->getName();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a "relatable" query for the given resource.
|
||||
*
|
||||
* This query determines which instances of the model may be attached to other resources.
|
||||
*
|
||||
* @param NovaRequest $request
|
||||
* @param Builder $query
|
||||
* @return Builder
|
||||
*
|
||||
* @noinspection PhpMissingParentCallCommonInspection
|
||||
*/
|
||||
public static function relatableQuery(NovaRequest $request, $query): Builder
|
||||
{
|
||||
return $query->with(GroupModel::RELATION_ANIME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an "index" query for the given resource.
|
||||
*
|
||||
* @param NovaRequest $request
|
||||
* @param Builder $query
|
||||
* @return Builder
|
||||
*
|
||||
* @noinspection PhpMissingParentCallCommonInspection
|
||||
*/
|
||||
public static function indexQuery(NovaRequest $request, $query): Builder
|
||||
{
|
||||
return $query->with(GroupModel::RELATION_ANIME);
|
||||
}
|
||||
|
||||
/**
|
||||
* The logical group associated with the resource.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @noinspection PhpMissingParentCallCommonInspection
|
||||
*/
|
||||
public static function group(): string
|
||||
{
|
||||
return __('nova.resources.group.wiki');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the displayable label of the resource.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @noinspection PhpMissingParentCallCommonInspection
|
||||
*/
|
||||
public static function label(): string
|
||||
{
|
||||
return __('nova.resources.label.groups');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the displayable singular label of the resource.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @noinspection PhpMissingParentCallCommonInspection
|
||||
*/
|
||||
public static function singularLabel(): string
|
||||
{
|
||||
return __('nova.resources.singularLabel.group');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the URI key for the resource.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @noinspection PhpMissingParentCallCommonInspection
|
||||
*/
|
||||
public static function uriKey(): string
|
||||
{
|
||||
return 'groups';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the searchable columns for the resource.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @noinspection PhpMissingParentCallCommonInspection
|
||||
*/
|
||||
public static function searchableColumns(): array
|
||||
{
|
||||
return [
|
||||
new Column(GroupModel::ATTRIBUTE_NAME),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this resource uses Laravel Scout.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @noinspection PhpMissingParentCallCommonInspection
|
||||
*/
|
||||
public static function usesScout(): bool
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the fields displayed by the resource.
|
||||
*
|
||||
* @param NovaRequest $request
|
||||
* @return array
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
public function fields(NovaRequest $request): array
|
||||
{
|
||||
return [
|
||||
ID::make(__('nova.fields.base.id'), GroupModel::ATTRIBUTE_ID)
|
||||
->sortable()
|
||||
->showOnPreview()
|
||||
->showWhenPeeking(),
|
||||
|
||||
Text::make(__('nova.fields.group.name.name'), GroupModel::ATTRIBUTE_NAME)
|
||||
->sortable()
|
||||
->copyable()
|
||||
->required()
|
||||
->rules(['required', 'max:192'])
|
||||
->help(__('nova.fields.group.name.help'))
|
||||
->showOnPreview()
|
||||
->filterable()
|
||||
->maxlength(192)
|
||||
->enforceMaxlength()
|
||||
->showWhenPeeking(),
|
||||
|
||||
Text::make(__('nova.fields.group.slug.name'), GroupModel::ATTRIBUTE_SLUG)
|
||||
->sortable()
|
||||
->copyable()
|
||||
->required()
|
||||
->rules(['required', 'max:192'])
|
||||
->help(__('nova.fields.group.slug.help'))
|
||||
->showOnPreview()
|
||||
->filterable()
|
||||
->maxlength(192)
|
||||
->enforceMaxlength()
|
||||
->showWhenPeeking(),
|
||||
|
||||
Text::make(__('nova.fields.group.video_filename.name'), GroupModel::ATTRIBUTE_VIDEO_FILENAME)
|
||||
->sortable()
|
||||
->copyable()
|
||||
->nullable()
|
||||
->rules(['nullable', 'max:192'])
|
||||
->help(__('nova.fields.group.video_filename.help'))
|
||||
->showOnPreview()
|
||||
->filterable()
|
||||
->maxlength(192)
|
||||
->enforceMaxlength()
|
||||
->showWhenPeeking(),
|
||||
|
||||
HasMany::make(__('nova.resources.label.anime_themes'), GroupModel::RELATION_THEMES, Theme::class),
|
||||
|
||||
Panel::make(__('nova.fields.base.timestamps'), $this->timestamps())
|
||||
->collapsable(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the actions available for the resource.
|
||||
*
|
||||
* @param NovaRequest $request
|
||||
* @return array
|
||||
*/
|
||||
public function actions(NovaRequest $request): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::actions($request),
|
||||
[]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the lenses available for the resource.
|
||||
*
|
||||
* @param NovaRequest $request
|
||||
* @return array
|
||||
*/
|
||||
public function lenses(NovaRequest $request): array
|
||||
{
|
||||
return array_merge(
|
||||
parent::lenses($request),
|
||||
[]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Policies\Wiki;
|
||||
|
||||
use App\Enums\Auth\CrudPermission;
|
||||
use App\Enums\Auth\ExtendedCrudPermission;
|
||||
use App\Models\Auth\User;
|
||||
use App\Models\Wiki\Group;
|
||||
use Illuminate\Auth\Access\HandlesAuthorization;
|
||||
use Laravel\Nova\Nova;
|
||||
|
||||
/**
|
||||
* Class GroupPolicy.
|
||||
*/
|
||||
class GroupPolicy
|
||||
{
|
||||
use HandlesAuthorization;
|
||||
|
||||
/**
|
||||
* Determine whether the user can view any models.
|
||||
*
|
||||
* @param User|null $user
|
||||
* @return bool
|
||||
*/
|
||||
public function viewAny(?User $user): bool
|
||||
{
|
||||
return Nova::whenServing(
|
||||
fn (): bool => $user !== null && $user->can(CrudPermission::VIEW->format(Group::class)),
|
||||
fn (): bool => true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can view the model.
|
||||
*
|
||||
* @param User|null $user
|
||||
* @return bool
|
||||
*/
|
||||
public function view(?User $user): bool
|
||||
{
|
||||
return Nova::whenServing(
|
||||
fn (): bool => $user !== null && $user->can(CrudPermission::VIEW->format(Group::class)),
|
||||
fn (): bool => true
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can create models.
|
||||
*
|
||||
* @param User $user
|
||||
* @return bool
|
||||
*/
|
||||
public function create(User $user): bool
|
||||
{
|
||||
return $user->can(CrudPermission::CREATE->format(Group::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can update the model.
|
||||
*
|
||||
* @param User $user
|
||||
* @param Group $group
|
||||
* @return bool
|
||||
*/
|
||||
public function update(User $user, Group $group): bool
|
||||
{
|
||||
return ! $group->trashed() && $user->can(CrudPermission::UPDATE->format(Group::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can delete the model.
|
||||
*
|
||||
* @param User $user
|
||||
* @param Group $group
|
||||
* @return bool
|
||||
*/
|
||||
public function delete(User $user, Group $group): bool
|
||||
{
|
||||
return ! $group->trashed() && $user->can(CrudPermission::DELETE->format(Group::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can restore the model.
|
||||
*
|
||||
* @param User $user
|
||||
* @param Group $group
|
||||
* @return bool
|
||||
*/
|
||||
public function restore(User $user, Group $group): bool
|
||||
{
|
||||
return $group->trashed() && $user->can(ExtendedCrudPermission::RESTORE->format(Group::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can permanently delete the model.
|
||||
*
|
||||
* @param User $user
|
||||
* @return bool
|
||||
*/
|
||||
public function forceDelete(User $user): bool
|
||||
{
|
||||
return $user->can(ExtendedCrudPermission::FORCE_DELETE->format(Group::class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the user can add a theme to the group.
|
||||
*
|
||||
* @param User $user
|
||||
* @return bool
|
||||
*/
|
||||
public function addAnimeTheme(User $user): bool
|
||||
{
|
||||
return $user->can(CrudPermission::UPDATE->format(Group::class));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Database\Factories\Wiki;
|
||||
|
||||
use App\Models\Wiki\Group;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
/**
|
||||
* Class GroupFactory.
|
||||
*
|
||||
* @method Group createOne($attributes = [])
|
||||
* @method Group makeOne($attributes = [])
|
||||
*
|
||||
* @extends Factory<Group>
|
||||
*/
|
||||
class GroupFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var class-string<Group>
|
||||
*/
|
||||
protected $model = Group::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition(): array
|
||||
{
|
||||
return [
|
||||
Group::ATTRIBUTE_NAME => fake()->words(3, true),
|
||||
Group::ATTRIBUTE_SLUG => Str::slug(fake()->text(191), '_'),
|
||||
Group::ATTRIBUTE_VIDEO_FILENAME => fake()->words(3, true),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Models\BaseModel;
|
||||
use App\Models\Wiki\Group;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
if (! Schema::hasTable(Group::TABLE)) {
|
||||
Schema::create(Group::TABLE, function (Blueprint $table) {
|
||||
$table->id(Group::ATTRIBUTE_ID);
|
||||
$table->timestamps(6);
|
||||
$table->softDeletes(BaseModel::ATTRIBUTE_DELETED_AT, 6);
|
||||
$table->string(Group::ATTRIBUTE_NAME);
|
||||
$table->string(Group::ATTRIBUTE_SLUG);
|
||||
$table->string(Group::ATTRIBUTE_VIDEO_FILENAME)->nullable();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists(Group::TABLE);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\Models\Wiki\Anime\AnimeTheme;
|
||||
use App\Models\Wiki\Group;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
if (! Schema::hasColumn(AnimeTheme::TABLE, AnimeTheme::ATTRIBUTE_THEME_GROUP)) {
|
||||
Schema::table(AnimeTheme::TABLE, function (Blueprint $table) {
|
||||
$table->unsignedBigInteger(AnimeTheme::ATTRIBUTE_THEME_GROUP)->nullable();
|
||||
$table->foreign(AnimeTheme::ATTRIBUTE_THEME_GROUP)->references(Group::ATTRIBUTE_ID)->on(Group::TABLE)->nullOnDelete();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
if (Schema::hasColumn(AnimeTheme::TABLE, AnimeTheme::ATTRIBUTE_THEME_GROUP)) {
|
||||
Schema::table(AnimeTheme::TABLE, function (Blueprint $table) {
|
||||
$table->dropConstrainedForeignId(AnimeTheme::ATTRIBUTE_THEME_GROUP);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -24,6 +24,7 @@ use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
|
||||
use App\Models\Wiki\Artist;
|
||||
use App\Models\Wiki\Audio;
|
||||
use App\Models\Wiki\ExternalResource;
|
||||
use App\Models\Wiki\Group;
|
||||
use App\Models\Wiki\Image;
|
||||
use App\Models\Wiki\Series;
|
||||
use App\Models\Wiki\Song;
|
||||
@@ -71,6 +72,7 @@ class PermissionSeeder extends Seeder
|
||||
$this->registerResource(AnimeThemeEntry::class, $extendedCrudPermissions);
|
||||
$this->registerResource(Artist::class, $extendedCrudPermissions);
|
||||
$this->registerResource(Audio::class, $extendedCrudPermissions);
|
||||
$this->registerResource(Group::class, $extendedCrudPermissions);
|
||||
$this->registerResource(ExternalResource::class, $extendedCrudPermissions);
|
||||
$this->registerResource(Image::class, $extendedCrudPermissions);
|
||||
$this->registerResource(Page::class, $extendedCrudPermissions);
|
||||
|
||||
@@ -24,6 +24,7 @@ use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
|
||||
use App\Models\Wiki\Artist;
|
||||
use App\Models\Wiki\Audio;
|
||||
use App\Models\Wiki\ExternalResource;
|
||||
use App\Models\Wiki\Group;
|
||||
use App\Models\Wiki\Image;
|
||||
use App\Models\Wiki\Series;
|
||||
use App\Models\Wiki\Song;
|
||||
@@ -75,6 +76,7 @@ class AdminSeeder extends RoleSeeder
|
||||
$this->configureResource($role, AnimeThemeEntry::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, Artist::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, Audio::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, Group::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, ExternalResource::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, Image::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, Page::class, $extendedCrudPermissions);
|
||||
|
||||
@@ -18,6 +18,7 @@ use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
|
||||
use App\Models\Wiki\Artist;
|
||||
use App\Models\Wiki\Audio;
|
||||
use App\Models\Wiki\ExternalResource;
|
||||
use App\Models\Wiki\Group;
|
||||
use App\Models\Wiki\Image;
|
||||
use App\Models\Wiki\Series;
|
||||
use App\Models\Wiki\Song;
|
||||
@@ -58,6 +59,7 @@ class DeveloperRoleSeeder extends RoleSeeder
|
||||
$this->configureResource($role, AnimeThemeEntry::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Artist::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Audio::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Group::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, ExternalResource::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Image::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Page::class, [CrudPermission::VIEW]);
|
||||
|
||||
@@ -18,6 +18,7 @@ use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
|
||||
use App\Models\Wiki\Artist;
|
||||
use App\Models\Wiki\Audio;
|
||||
use App\Models\Wiki\ExternalResource;
|
||||
use App\Models\Wiki\Group;
|
||||
use App\Models\Wiki\Image;
|
||||
use App\Models\Wiki\Series;
|
||||
use App\Models\Wiki\Song;
|
||||
@@ -65,6 +66,7 @@ class EncoderRoleSeeder extends RoleSeeder
|
||||
$this->configureResource($role, AnimeThemeEntry::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, Artist::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, Audio::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, Group::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, ExternalResource::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, Image::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, Page::class, $extendedCrudPermissions);
|
||||
|
||||
@@ -18,6 +18,7 @@ use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
|
||||
use App\Models\Wiki\Artist;
|
||||
use App\Models\Wiki\Audio;
|
||||
use App\Models\Wiki\ExternalResource;
|
||||
use App\Models\Wiki\Group;
|
||||
use App\Models\Wiki\Image;
|
||||
use App\Models\Wiki\Series;
|
||||
use App\Models\Wiki\Song;
|
||||
@@ -58,6 +59,7 @@ class PatronRoleSeeder extends RoleSeeder
|
||||
$this->configureResource($role, AnimeThemeEntry::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Artist::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Audio::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Group::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, ExternalResource::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Image::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Page::class, [CrudPermission::VIEW]);
|
||||
|
||||
@@ -18,6 +18,7 @@ use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
|
||||
use App\Models\Wiki\Artist;
|
||||
use App\Models\Wiki\Audio;
|
||||
use App\Models\Wiki\ExternalResource;
|
||||
use App\Models\Wiki\Group;
|
||||
use App\Models\Wiki\Image;
|
||||
use App\Models\Wiki\Series;
|
||||
use App\Models\Wiki\Song;
|
||||
@@ -65,6 +66,7 @@ class WikiEditorRoleSeeder extends RoleSeeder
|
||||
$this->configureResource($role, AnimeThemeEntry::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, Artist::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, Audio::class, [CrudPermission::VIEW, CrudPermission::UPDATE]);
|
||||
$this->configureResource($role, Group::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, ExternalResource::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, Image::class, $extendedCrudPermissions);
|
||||
$this->configureResource($role, Page::class, $extendedCrudPermissions);
|
||||
|
||||
@@ -18,6 +18,7 @@ use App\Models\Wiki\Anime\Theme\AnimeThemeEntry;
|
||||
use App\Models\Wiki\Artist;
|
||||
use App\Models\Wiki\Audio;
|
||||
use App\Models\Wiki\ExternalResource;
|
||||
use App\Models\Wiki\Group;
|
||||
use App\Models\Wiki\Image;
|
||||
use App\Models\Wiki\Series;
|
||||
use App\Models\Wiki\Song;
|
||||
@@ -58,6 +59,7 @@ class WikiViewerRoleSeeder extends RoleSeeder
|
||||
$this->configureResource($role, AnimeThemeEntry::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Artist::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Audio::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Group::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, ExternalResource::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Image::class, [CrudPermission::VIEW]);
|
||||
$this->configureResource($role, Page::class, [CrudPermission::VIEW]);
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Database\Seeders\Wiki\Group;
|
||||
|
||||
use App\Models\Wiki\Anime\AnimeTheme;
|
||||
use App\Models\Wiki\Group;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
/**
|
||||
* Class GroupMigratingSeeder.
|
||||
*/
|
||||
class GroupMigratingSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Seed the application's database.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$this->englishVersionGroup();
|
||||
$this->tvVersionGroup();
|
||||
$this->bdVersionGroup();
|
||||
$this->koreanVersionGroup();
|
||||
$this->hdRemasterGroup();
|
||||
$this->gintamaYorinukiGroup();
|
||||
}
|
||||
|
||||
protected function englishVersionGroup()
|
||||
{
|
||||
$dubbedGroupThemes = AnimeTheme::query()
|
||||
->where(AnimeTheme::ATTRIBUTE_GROUP, 'Dubbed Version')
|
||||
->orWhere(AnimeTheme::ATTRIBUTE_GROUP, 'Dubbed Version - Funimation')
|
||||
->orWhere(AnimeTheme::ATTRIBUTE_GROUP, 'English Version')
|
||||
->get();
|
||||
|
||||
$dubbedGroup = Group::query()->where(Group::ATTRIBUTE_NAME, 'English Version')->get();
|
||||
$dubbedGroupThemes->each(fn (AnimeTheme $theme) => $theme->theme_group()->associate($dubbedGroup)->save());
|
||||
}
|
||||
|
||||
protected function tvVersionGroup()
|
||||
{
|
||||
$tvVersionThemes = AnimeTheme::query()
|
||||
->where(AnimeTheme::ATTRIBUTE_GROUP, 'Original Broadcast Version')
|
||||
->orWhere(AnimeTheme::ATTRIBUTE_GROUP, 'Original Japanese Version')
|
||||
->orWhere(AnimeTheme::ATTRIBUTE_GROUP, 'Japanese Terrestrial Broadcast')
|
||||
->orWhere(AnimeTheme::ATTRIBUTE_GROUP, '2005 Japanese Terrestrial Broadcast')
|
||||
->orWhere(AnimeTheme::ATTRIBUTE_GROUP, 'TV version')
|
||||
->orWhere(AnimeTheme::ATTRIBUTE_GROUP, 'TV Broadcast')
|
||||
->get();
|
||||
|
||||
$tvVersionGroup = Group::query()->where(Group::ATTRIBUTE_NAME, 'TV Version')->get();
|
||||
$tvVersionThemes->each(fn (AnimeTheme $theme) => $theme->theme_group()->associate($tvVersionGroup)->save());
|
||||
|
||||
}
|
||||
|
||||
protected function bdVersionGroup()
|
||||
{
|
||||
$bdVersionThemes = AnimeTheme::query()
|
||||
->where(AnimeTheme::ATTRIBUTE_GROUP, 'BD version')
|
||||
->get();
|
||||
|
||||
$bdVersionGroup = Group::query()->where(Group::ATTRIBUTE_NAME, 'BD Version')->get();
|
||||
$bdVersionThemes->each(fn (AnimeTheme $theme) => $theme->theme_group()->associate($bdVersionGroup)->save());
|
||||
}
|
||||
|
||||
protected function koreanVersionGroup()
|
||||
{
|
||||
$koreanVersionThemes = AnimeTheme::query()
|
||||
->where(AnimeTheme::ATTRIBUTE_GROUP, 'Korean Version')
|
||||
->get();
|
||||
|
||||
$koreanVersionGroup = Group::query()->where(Group::ATTRIBUTE_NAME, 'Korean Version')->get();
|
||||
$koreanVersionThemes->each(fn (AnimeTheme $theme) => $theme->theme_group()->associate($koreanVersionGroup)->save());
|
||||
}
|
||||
|
||||
protected function hdRemasterGroup()
|
||||
{
|
||||
$hdRemasterThemes = AnimeTheme::query()
|
||||
->where(AnimeTheme::ATTRIBUTE_GROUP, 'HD Remaster')
|
||||
->get();
|
||||
|
||||
$hdRemasterGroup = Group::query()->where(Group::ATTRIBUTE_NAME, 'HD Remaster')->get();
|
||||
$hdRemasterThemes->each(fn (AnimeTheme $theme) => $theme->theme_group()->associate($hdRemasterGroup)->save());
|
||||
}
|
||||
|
||||
protected function gintamaYorinukiGroup()
|
||||
{
|
||||
$gintamaYorinukiThemes = AnimeTheme::query()
|
||||
->where(AnimeTheme::ATTRIBUTE_GROUP, 'Yorinuki Gintama-san')
|
||||
->get();
|
||||
|
||||
$gintamaYorinukiGroup = Group::query()->where(Group::ATTRIBUTE_NAME, 'Yorinuki Gintama-san')->get();
|
||||
$gintamaYorinukiThemes->each(fn (AnimeTheme $theme) => $theme->theme_group()->associate($gintamaYorinukiGroup)->save());
|
||||
}
|
||||
}
|
||||
@@ -1,255 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Database\Seeders\Wiki\Image;
|
||||
|
||||
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 Exception;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Filesystem\FilesystemAdapter;
|
||||
use Illuminate\Support\Facades\Config;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class MoveImageToAppropriateFolderSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
$this->grillFacetImageSeeder();
|
||||
//$this->animeImageSeeder();
|
||||
$this->artistImageSeeder();
|
||||
//$this->studioImageSeeder();
|
||||
}
|
||||
|
||||
protected function grillFacetImageSeeder(): void
|
||||
{
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$chunkSize = 100;
|
||||
/** @var FilesystemAdapter $fs */
|
||||
$fs = Storage::disk(Config::get('image.disk'));
|
||||
$images = Image::query()->where(Image::ATTRIBUTE_FACET, ImageFacet::GRILL)->get();
|
||||
|
||||
foreach ($images->chunk($chunkSize) as $chunk) {
|
||||
foreach ($chunk as $image) {
|
||||
if ($image instanceof Image) {
|
||||
$oldPath = $image->path;
|
||||
$newPath = "grill/{$image->path}";
|
||||
|
||||
$fs->move($oldPath, $newPath);
|
||||
|
||||
$image->update([
|
||||
Image::ATTRIBUTE_PATH => $newPath,
|
||||
]);
|
||||
|
||||
DB::commit();
|
||||
|
||||
echo $oldPath . ' moved to ' . $newPath . "\n";
|
||||
}
|
||||
}
|
||||
sleep(5);
|
||||
}
|
||||
|
||||
echo "grill facet images done\n";
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo 'error ' . $e->getMessage() . "\n";
|
||||
|
||||
DB::rollBack();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
protected function animeImageSeeder(): void
|
||||
{
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$chunkSize = 100;
|
||||
/** @var FilesystemAdapter $fs */
|
||||
$fs = Storage::disk(Config::get('image.disk'));
|
||||
$animes = Anime::query()->where(Anime::ATTRIBUTE_ID, '>', 0)->whereHas(Image::TABLE, function (Builder $query) {
|
||||
$query->where(Image::ATTRIBUTE_PATH, 'not like', '%/%');
|
||||
})->get();
|
||||
|
||||
foreach ($animes->chunk($chunkSize) as $chunk) {
|
||||
foreach ($chunk as $anime) {
|
||||
if ($anime instanceof Anime) {
|
||||
$images = $anime->images()->get();
|
||||
|
||||
if (count($images) === 0) continue;
|
||||
|
||||
$largeCover = $images->where(Image::ATTRIBUTE_FACET, ImageFacet::COVER_LARGE)->first();
|
||||
$smallCover = $images->where(Image::ATTRIBUTE_FACET, ImageFacet::COVER_SMALL)->first();
|
||||
|
||||
if (!empty($largeCover)) {
|
||||
$largeCoverOldPath = $largeCover->path;
|
||||
$largeCoverNewPath = "anime/large-cover/{$largeCover->path}";
|
||||
|
||||
$fs->move($largeCoverOldPath, $largeCoverNewPath);
|
||||
|
||||
$largeCover->update([
|
||||
Image::ATTRIBUTE_PATH => $largeCoverNewPath,
|
||||
]);
|
||||
|
||||
echo $largeCoverOldPath . ' moved to ' . $largeCoverNewPath . "\n";
|
||||
}
|
||||
|
||||
if (!empty($smallCover)) {
|
||||
$smallCoverOldPath = $smallCover->path;
|
||||
$smallCoverNewPath = "anime/small-cover/{$smallCover->path}";
|
||||
|
||||
$fs->move($smallCoverOldPath, $smallCoverNewPath);
|
||||
|
||||
$smallCover->update([
|
||||
Image::ATTRIBUTE_PATH => $smallCoverNewPath,
|
||||
]);
|
||||
|
||||
echo $smallCoverOldPath . ' moved to ' . $smallCoverNewPath . "\n";
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
}
|
||||
}
|
||||
sleep(5);
|
||||
}
|
||||
|
||||
echo "anime images done\n";
|
||||
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo 'error ' . $e->getMessage() . "\n";
|
||||
|
||||
DB::rollBack();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
protected function artistImageSeeder(): void
|
||||
{
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$chunkSize = 100;
|
||||
/** @var FilesystemAdapter $fs */
|
||||
$fs = Storage::disk(Config::get('image.disk'));
|
||||
$artists = Artist::query()->where(Artist::ATTRIBUTE_ID, '>', 0)->whereHas(Image::TABLE, function (Builder $query) {
|
||||
$query->where(Image::ATTRIBUTE_PATH, 'not like', '%/%');
|
||||
})->get();
|
||||
|
||||
foreach ($artists->chunk($chunkSize) as $chunk) {
|
||||
foreach ($chunk as $artist) {
|
||||
if ($artist instanceof Artist) {
|
||||
$images = $artist->images()->get();
|
||||
|
||||
if (count($images) === 0) continue;
|
||||
|
||||
$largeCover = $images->where(Image::ATTRIBUTE_FACET, ImageFacet::COVER_LARGE)->first();
|
||||
$smallCover = $images->where(Image::ATTRIBUTE_FACET, ImageFacet::COVER_SMALL)->first();
|
||||
|
||||
if (!empty($largeCover)) {
|
||||
$largeCoverOldPath = $largeCover->path;
|
||||
$largeCoverNewPath = "artist/large-cover/{$largeCover->path}";
|
||||
|
||||
$fs->move($largeCoverOldPath, $largeCoverNewPath);
|
||||
|
||||
$largeCover->update([
|
||||
Image::ATTRIBUTE_PATH => $largeCoverNewPath,
|
||||
]);
|
||||
|
||||
echo $largeCoverOldPath . ' moved to ' . $largeCoverNewPath . "\n";
|
||||
}
|
||||
|
||||
if (!empty($smallCover)) {
|
||||
$smallCoverOldPath = $smallCover->path;
|
||||
$smallCoverNewPath = "artist/small-cover/{$smallCover->path}";
|
||||
|
||||
$fs->move($smallCoverOldPath, $smallCoverNewPath);
|
||||
|
||||
$smallCover->update([
|
||||
Image::ATTRIBUTE_PATH => $smallCoverNewPath,
|
||||
]);
|
||||
|
||||
echo $smallCoverOldPath . ' moved to ' . $smallCoverNewPath . "\n";
|
||||
}
|
||||
|
||||
DB::commit();
|
||||
}
|
||||
}
|
||||
sleep(5);
|
||||
}
|
||||
|
||||
echo "artist images done\n";
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo 'error ' . $e->getMessage() . "\n";
|
||||
|
||||
DB::rollBack();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
protected function studioImageSeeder(): void
|
||||
{
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
|
||||
$chunkSize = 100;
|
||||
/** @var FilesystemAdapter $fs */
|
||||
$fs = Storage::disk(Config::get('image.disk'));
|
||||
$studios = Studio::query()->where(Studio::ATTRIBUTE_ID, '>', 0)->whereHas(Image::TABLE, function (Builder $query) {
|
||||
$query->where(Image::ATTRIBUTE_PATH, 'not like', '%/%');
|
||||
})->get();
|
||||
|
||||
foreach ($studios->chunk($chunkSize) as $chunk) {
|
||||
foreach ($chunk as $studio) {
|
||||
if ($studio instanceof Studio) {
|
||||
$images = $studio->images()->get();
|
||||
|
||||
if (count($images) === 0) continue;
|
||||
|
||||
$largeCover = $images->where(Image::ATTRIBUTE_FACET, ImageFacet::COVER_LARGE)->first();
|
||||
|
||||
if (!empty($largeCover)) {
|
||||
$oldPath = $largeCover->path;
|
||||
$newPath = "studio/large-cover/{$largeCover->path}";
|
||||
|
||||
$fs->move($oldPath, $newPath);
|
||||
|
||||
$largeCover->update([
|
||||
Image::ATTRIBUTE_PATH => $newPath,
|
||||
]);
|
||||
|
||||
DB::commit();
|
||||
|
||||
echo $oldPath . ' moved to ' . $newPath . "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
sleep(5);
|
||||
}
|
||||
|
||||
echo "studio images done\n";
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo 'error ' . $e->getMessage() . "\n";
|
||||
|
||||
DB::rollBack();
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -567,6 +567,20 @@ return [
|
||||
'name' => 'Start At',
|
||||
],
|
||||
],
|
||||
'group' => [
|
||||
'name' => [
|
||||
'name' => 'Name',
|
||||
'help' => 'The name of the group.',
|
||||
],
|
||||
'slug' => [
|
||||
'name' => 'Slug',
|
||||
'help' => 'The slug that will be appended to the slug of the theme that has the group.',
|
||||
],
|
||||
'video_filename' => [
|
||||
'name' => 'Video Filename',
|
||||
'help' => 'The filename that will be appended to the filaname of the video that is related to the group.',
|
||||
],
|
||||
],
|
||||
'image' => [
|
||||
'facet' => [
|
||||
'help' => 'The page component that the image is intended for. Example: Is this a small cover image or a large cover image?',
|
||||
@@ -890,6 +904,7 @@ return [
|
||||
'external_resource' => 'External Resource',
|
||||
'feature' => 'Feature',
|
||||
'featured_theme' => 'Featured Theme',
|
||||
'group' => 'Group',
|
||||
'image' => 'Image',
|
||||
'page' => 'Page',
|
||||
'permission' => 'Permission',
|
||||
|
||||
@@ -38,6 +38,7 @@ use App\Http\Controllers\Api\Wiki\AnimeController;
|
||||
use App\Http\Controllers\Api\Wiki\ArtistController;
|
||||
use App\Http\Controllers\Api\Wiki\AudioController;
|
||||
use App\Http\Controllers\Api\Wiki\ExternalResourceController;
|
||||
use App\Http\Controllers\Api\Wiki\GroupController;
|
||||
use App\Http\Controllers\Api\Wiki\ImageController;
|
||||
use App\Http\Controllers\Api\Wiki\SeriesController;
|
||||
use App\Http\Controllers\Api\Wiki\SongController;
|
||||
@@ -273,6 +274,7 @@ apiEditablePivotResource('artistsong', 'artist', 'song', ArtistSongController::c
|
||||
apiResource('anime', AnimeController::class);
|
||||
apiResource('artist', ArtistController::class);
|
||||
apiResource('audio', AudioController::class);
|
||||
apiResource('group', GroupController::class);
|
||||
apiResource('image', ImageController::class);
|
||||
apiResource('resource', ExternalResourceController::class);
|
||||
Route::get('search', [SearchController::class, 'show'])->name('search.show');
|
||||
|
||||
Reference in New Issue
Block a user