feat: song native title (#979)

This commit is contained in:
Kyrch
2025-10-24 03:31:00 -03:00
committed by GitHub
parent 6721443646
commit 4a7b960d34
12 changed files with 154 additions and 4 deletions
+14 -1
View File
@@ -77,6 +77,11 @@ class Song extends BaseResource
->helperText(__('filament.fields.song.title.help'))
->required()
->maxLength(192),
TextInput::make(SongModel::ATTRIBUTE_TITLE_NATIVE)
->label(__('filament.fields.song.title_native.name'))
->helperText(__('filament.fields.song.title_native.help'))
->maxLength(192),
]);
}
@@ -90,6 +95,10 @@ class Song extends BaseResource
TextColumn::make(SongModel::ATTRIBUTE_TITLE)
->label(__('filament.fields.song.title.name'))
->copyableWithMessage(),
TextColumn::make(SongModel::ATTRIBUTE_TITLE_NATIVE)
->label(__('filament.fields.song.title_native.name'))
->copyableWithMessage(),
])
->searchable();
}
@@ -106,8 +115,12 @@ class Song extends BaseResource
TextEntry::make(SongModel::ATTRIBUTE_TITLE)
->label(__('filament.fields.song.title.name'))
->copyableWithMessage(),
TextEntry::make(SongModel::ATTRIBUTE_TITLE_NATIVE)
->label(__('filament.fields.song.title_native.name'))
->copyableWithMessage(),
])
->columns(2),
->columns(3),
TimestampSection::make(),
]);
@@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
namespace App\GraphQL\Schema\Fields\Wiki\Song;
use App\Contracts\GraphQL\Fields\CreatableField;
use App\Contracts\GraphQL\Fields\UpdatableField;
use App\GraphQL\Schema\Fields\StringField;
use App\Models\Wiki\Song;
class SongTitleNativeField extends StringField implements CreatableField, UpdatableField
{
public function __construct()
{
parent::__construct(Song::ATTRIBUTE_TITLE_NATIVE);
}
public function description(): string
{
return 'The native name of the composition';
}
/**
* @param array<string, mixed> $args
*/
public function getCreationRules(array $args): array
{
return [
'sometimes',
'required',
'string',
'max:192',
];
}
/**
* @param array<string, mixed> $args
*/
public function getUpdateRules(array $args): array
{
return [
'sometimes',
'required',
'string',
'max:192',
];
}
}
@@ -11,6 +11,7 @@ use App\GraphQL\Schema\Fields\Base\IdField;
use App\GraphQL\Schema\Fields\Base\UpdatedAtField;
use App\GraphQL\Schema\Fields\Field;
use App\GraphQL\Schema\Fields\Wiki\Song\SongTitleField;
use App\GraphQL\Schema\Fields\Wiki\Song\SongTitleNativeField;
use App\GraphQL\Schema\Types\EloquentType;
use App\GraphQL\Schema\Types\Pivot\Morph\ResourceableType;
use App\GraphQL\Schema\Types\Wiki\Anime\AnimeThemeType;
@@ -51,6 +52,7 @@ class SongType extends EloquentType implements ReportableType
return [
new IdField(Song::ATTRIBUTE_ID, Song::class),
new SongTitleField(),
new SongTitleNativeField(),
new CreatedAtField(),
new UpdatedAtField(),
new DeletedAtField(),
+8 -3
View File
@@ -34,6 +34,7 @@ use Illuminate\Support\Collection;
* @property Collection<int, ExternalResource> $resources
* @property int $song_id
* @property string|null $title
* @property string|null $title_native
*
* @method static SongFactory factory(...$parameters)
*/
@@ -48,6 +49,7 @@ class Song extends BaseModel implements HasResources, SoftDeletable
final public const string ATTRIBUTE_ID = 'song_id';
final public const string ATTRIBUTE_TITLE = 'title';
final public const string ATTRIBUTE_TITLE_NATIVE = 'title_native';
final public const string RELATION_ANIME = 'animethemes.anime';
final public const string RELATION_ANIMETHEMES = 'animethemes';
@@ -65,6 +67,7 @@ class Song extends BaseModel implements HasResources, SoftDeletable
*/
protected $fillable = [
Song::ATTRIBUTE_TITLE,
Song::ATTRIBUTE_TITLE_NATIVE,
];
/**
@@ -107,9 +110,11 @@ class Song extends BaseModel implements HasResources, SoftDeletable
public function getSubtitle(): string
{
return $this->animethemes()->count() !== 0 && $this->animethemes->first()->anime !== null
? "{$this->animethemes->first()->anime->getName()} {$this->animethemes->first()->slug}"
: $this->getName();
if ($this->animethemes()->count() !== 0 && $this->animethemes->first()->anime !== null) {
return "{$this->animethemes->first()->anime->getName()} {$this->animethemes->first()->slug}";
}
return $this->title_native ?? $this->getKey();
}
/**
@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);
namespace App\Scout\Elasticsearch\Api\Field\Wiki\Song;
use App\Models\Wiki\Song;
use App\Scout\Elasticsearch\Api\Field\StringField;
use App\Scout\Elasticsearch\Api\Schema\Schema;
class SongTitleNativeField extends StringField
{
public function __construct(Schema $schema)
{
parent::__construct($schema, Song::ATTRIBUTE_TITLE_NATIVE);
}
}
@@ -28,6 +28,12 @@ class ThemeQuery extends ElasticQuery
'should' => $this->createNestedTextQuery('song', 'title', $criteria->getTerm()),
],
],
[
'bool' => [
'boost' => 0.9,
'should' => $this->createNestedTextQuery('song', 'title_native', $criteria->getTerm()),
],
],
[
'bool' => [
'boost' => 0.5,
@@ -36,6 +36,27 @@ class SongQuery extends ElasticQuery
->lenient(true)
->fuzziness('AUTO')
)
->should(
new MatchPhraseQueryBuilder()
->field('title_native')
->query($criteria->getTerm())
)
->should(
new MatchQueryBuilder()
->field('title_native')
->query($criteria->getTerm())
->operator('AND')
->boost(0.9)
)
->should(
new MatchQueryBuilder()
->field('title_native')
->query($criteria->getTerm())
->operator('AND')
->lenient(true)
->fuzziness('AUTO')
->boost(0.9)
)
->minimumShouldMatch(1);
return Song::searchQuery($query);
@@ -11,6 +11,7 @@ use App\Models\Wiki\Song;
use App\Scout\Elasticsearch\Api\Field\Base\IdField;
use App\Scout\Elasticsearch\Api\Field\Field;
use App\Scout\Elasticsearch\Api\Field\Wiki\Song\SongTitleField;
use App\Scout\Elasticsearch\Api\Field\Wiki\Song\SongTitleNativeField;
use App\Scout\Elasticsearch\Api\Query\Wiki\SongQuery;
use App\Scout\Elasticsearch\Api\Schema\Schema;
use App\Scout\Elasticsearch\Api\Schema\Wiki\Anime\ThemeSchema;
@@ -50,6 +51,7 @@ class SongSchema extends Schema
[
new IdField($this, Song::ATTRIBUTE_ID),
new SongTitleField($this),
new SongTitleNativeField($this),
],
);
}
+1
View File
@@ -31,6 +31,7 @@ class SongFactory extends Factory
{
return [
Song::ATTRIBUTE_TITLE => fake()->words(3, true),
Song::ATTRIBUTE_TITLE_NATIVE => fake()->words(3, true),
];
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
use App\Models\Wiki\Song;
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(Song::TABLE, Song::ATTRIBUTE_TITLE_NATIVE)) {
Schema::table(Song::TABLE, function (Blueprint $table) {
$table->string(Song::ATTRIBUTE_TITLE_NATIVE)->nullable()->after(Song::ATTRIBUTE_TITLE);
});
}
}
};
@@ -23,6 +23,13 @@ final class CreateSongIndex implements MigrationInterface
],
],
]);
$mapping->text('title_native', [
'fields' => [
'keyword' => [
'type' => 'keyword',
],
],
]);
$mapping->date('updated_at');
});
}
+4
View File
@@ -892,6 +892,10 @@ return [
'help' => 'The title of the song',
'name' => 'Title',
],
'title_native' => [
'help' => 'The native title of the song as it is credited',
'name' => 'Native Title',
],
],
'studio' => [
'name' => [