added seo for Persons

This commit is contained in:
F4ilji
2025-05-25 19:01:00 +05:00
parent 9c22e7601c
commit 7d6b75b708
6 changed files with 49 additions and 4 deletions
+16 -2
View File
@@ -5,6 +5,9 @@ namespace App\Containers\User\Models;
use App\Containers\InstituteStructure\Models\Department; use App\Containers\InstituteStructure\Models\Department;
use App\Containers\InstituteStructure\Models\Division; use App\Containers\InstituteStructure\Models\Division;
use App\Containers\InstituteStructure\Models\Faculty; use App\Containers\InstituteStructure\Models\Faculty;
use App\Ship\Contracts\SeoDescriptionInterface;
use App\Ship\Contracts\SeoTitleInterface;
use App\Ship\Traits\HasSeo;
use BezhanSalleh\FilamentShield\FilamentShield; use BezhanSalleh\FilamentShield\FilamentShield;
use BezhanSalleh\FilamentShield\Support\Utils; use BezhanSalleh\FilamentShield\Support\Utils;
use BezhanSalleh\FilamentShield\Traits\HasPanelShield; use BezhanSalleh\FilamentShield\Traits\HasPanelShield;
@@ -19,9 +22,9 @@ use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens; use Laravel\Sanctum\HasApiTokens;
use Spatie\Permission\Traits\HasRoles; use Spatie\Permission\Traits\HasRoles;
class User extends Authenticatable implements FilamentUser class User extends Authenticatable implements FilamentUser, SeoTitleInterface, SeoDescriptionInterface
{ {
use HasApiTokens, HasFactory, Notifiable, HasRoles, HasPanelShield; use HasApiTokens, HasFactory, Notifiable, HasRoles, HasPanelShield, HasSeo;
/** /**
* The attributes that are mass assignable. * The attributes that are mass assignable.
@@ -117,4 +120,15 @@ class User extends Authenticatable implements FilamentUser
default => false, default => false,
}; };
} }
public function getSeoTitle(): string
{
return $this->name;
}
public function getSeoDescription(): array
{
$text = 'Персональная страница сотрудника - ' . $this->name;
return $this->prepareDescription($text);
}
} }
@@ -16,12 +16,12 @@ class PersonController extends Controller
public function show(string $slug) public function show(string $slug)
{ {
$personData = Cache::remember( $personData = Cache::remember(
CacheKeys::USER_PREFIX->value . $slug, CacheKeys::USER_PREFIX->value . $slug,
now()->addHours(24), now()->addHours(24),
fn() => User::with(['userDetail', 'departments_work.faculty', 'departments_teach.faculty', 'divisions', 'faculties']) fn() => User::with(['userDetail', 'departments_work.faculty', 'departments_teach.faculty', 'divisions', 'faculties'])
->where('slug', $slug) ->where('slug', $slug)
->whereHas('userDetail')
->firstOrFail() ->firstOrFail()
); );
@@ -4,12 +4,15 @@ namespace App\Filament\Resources\UserResource\Pages;
use App\Filament\Resources\UserResource; use App\Filament\Resources\UserResource;
use App\Containers\User\Models\User; use App\Containers\User\Models\User;
use App\Services\Filament\Traits\SeoGenerate;
use Filament\Actions; use Filament\Actions;
use Filament\Resources\Pages\CreateRecord; use Filament\Resources\Pages\CreateRecord;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class CreateUser extends CreateRecord class CreateUser extends CreateRecord
{ {
use SeoGenerate;
protected static string $resource = UserResource::class; protected static string $resource = UserResource::class;
protected function mutateFormDataBeforeCreate(array $data): array protected function mutateFormDataBeforeCreate(array $data): array
@@ -18,6 +21,11 @@ class CreateUser extends CreateRecord
return $data; return $data;
} }
protected function afterCreate(): void
{
$this->createSeo($this->record);
}
private function generateUniqueSlug(string $name): string private function generateUniqueSlug(string $name): string
{ {
// Преобразуем имя в slug (например, заменяем пробелы на дефисы и приводим к нижнему регистру) // Преобразуем имя в slug (например, заменяем пробелы на дефисы и приводим к нижнему регистру)
@@ -4,12 +4,15 @@ namespace App\Filament\Resources\UserResource\Pages;
use App\Containers\User\Models\User; use App\Containers\User\Models\User;
use App\Filament\Resources\UserResource; use App\Filament\Resources\UserResource;
use App\Services\Filament\Traits\SeoGenerate;
use Filament\Actions; use Filament\Actions;
use Filament\Resources\Pages\EditRecord; use Filament\Resources\Pages\EditRecord;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class EditUser extends EditRecord class EditUser extends EditRecord
{ {
use SeoGenerate;
protected static string $resource = UserResource::class; protected static string $resource = UserResource::class;
protected function mutateFormDataBeforeSave(array $data): array protected function mutateFormDataBeforeSave(array $data): array
@@ -19,6 +22,11 @@ class EditUser extends EditRecord
return $data; return $data;
} }
protected function afterSave(): void
{
$this->updateSeo($this->record);
}
private function generateUniqueSlug(string $name): string private function generateUniqueSlug(string $name): string
{ {
// Преобразуем имя в slug (например, заменяем пробелы на дефисы и приводим к нижнему регистру) // Преобразуем имя в slug (например, заменяем пробелы на дефисы и приводим к нижнему регистру)
+4 -1
View File
@@ -4,6 +4,7 @@ namespace App\Services\Filament\Traits;
use App\Services\Filament\Domain\Seo\SeoGeneratorService; use App\Services\Filament\Domain\Seo\SeoGeneratorService;
use App\Ship\Contracts\SeoDescriptionInterface; use App\Ship\Contracts\SeoDescriptionInterface;
use App\Ship\Contracts\SeoTitleInterface;
trait SeoGenerate trait SeoGenerate
{ {
@@ -25,7 +26,9 @@ trait SeoGenerate
private function generateSeoData($record) { private function generateSeoData($record) {
return app(SeoGeneratorService::class)->generate([ return app(SeoGeneratorService::class)->generate([
'title' => $record->title, 'title' => $record instanceof SeoTitleInterface
? $record->getSeoTitle()
: $record->title,
'content' => $record instanceof SeoDescriptionInterface 'content' => $record instanceof SeoDescriptionInterface
? $record->getSeoDescription() ? $record->getSeoDescription()
: $record->content, : $record->content,
+12
View File
@@ -12,4 +12,16 @@ trait HasSeo
{ {
return $this->morphOne(Seo::class, 'seoable'); return $this->morphOne(Seo::class, 'seoable');
} }
public function prepareDescription(string $description): array
{
return [
[
'type' => 'paragraph',
'data' => [
'content' => $description,
],
]
];
}
} }