fix: remove HasTranslations trait, use translations JSON in models + seeders

This commit is contained in:
DevOps 2026-06-28 17:37:08 +00:00
parent ebd4bd19ed
commit 223a4f5640
9 changed files with 214 additions and 77 deletions

View File

@ -4,19 +4,47 @@
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;
class AboutMe extends Model class AboutMe extends Model
{ {
use HasFactory, HasTranslations; use HasFactory;
protected $table = 'website_about_me'; protected $table = 'website_about_me';
protected $fillable = ['image']; protected $fillable = ['image',
'translations',];
protected array $translatable = ['title', 'description'];
public function skills() public function skills()
{ {
return $this->hasMany(Skill::class); return $this->hasMany(Skill::class);
} }
protected $casts = [
'translations' => 'array',
];
public function getTranslation(string $key, string $locale, bool $useFallbackLocale = true): mixed
{
$translations = $this->translations;
if (isset($translations[$key][$locale])) {
return $translations[$key][$locale];
}
if ($useFallbackLocale && isset($translations[$key]['en'])) {
return $translations[$key]['en'];
}
return null;
}
public function getTitleAttribute()
{
return $this->translations['title'] ?? null;
}
public function getDescriptionAttribute()
{
return $this->translations['description'] ?? null;
}
} }

View File

@ -4,19 +4,47 @@
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;
class Project extends Model class Project extends Model
{ {
use HasFactory, HasTranslations; use HasFactory;
protected $table = 'website_projects'; protected $table = 'website_projects';
protected $fillable = ['category_id', 'image1', 'image2']; protected $fillable = ['category_id', 'image1', 'image2',
'translations',];
protected array $translatable = ['title', 'description'];
public function category() public function category()
{ {
return $this->belongsTo(ProjectCategory::class, 'category_id'); return $this->belongsTo(ProjectCategory::class, 'category_id');
} }
protected $casts = [
'translations' => 'array',
];
public function getTranslation(string $key, string $locale, bool $useFallbackLocale = true): mixed
{
$translations = $this->translations;
if (isset($translations[$key][$locale])) {
return $translations[$key][$locale];
}
if ($useFallbackLocale && isset($translations[$key]['en'])) {
return $translations[$key]['en'];
}
return null;
}
public function getTitleAttribute()
{
return $this->translations['title'] ?? null;
}
public function getDescriptionAttribute()
{
return $this->translations['description'] ?? null;
}
} }

View File

@ -4,14 +4,42 @@
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;
class ProjectCategory extends Model class ProjectCategory extends Model
{ {
use HasFactory, HasTranslations; use HasFactory;
protected $table = 'website_project_categories'; protected $table = 'website_project_categories';
protected $fillable = ['image']; protected $fillable = ['image',
'translations',];
protected $casts = [
'translations' => 'array',
];
public function getTranslation(string $key, string $locale, bool $useFallbackLocale = true): mixed
{
$translations = $this->translations;
if (isset($translations[$key][$locale])) {
return $translations[$key][$locale];
}
if ($useFallbackLocale && isset($translations[$key]['en'])) {
return $translations[$key]['en'];
}
return null;
}
public function getTitleAttribute()
{
return $this->translations['title'] ?? null;
}
public function getDescriptionAttribute()
{
return $this->translations['description'] ?? null;
}
protected array $translatable = ['title', 'description'];
} }

View File

@ -10,7 +10,8 @@ class Service extends Model
use HasFactory; use HasFactory;
protected $table = 'website_services'; protected $table = 'website_services';
protected $fillable = ['imageSrc']; protected $fillable = ['imageSrc',
'translations'];
protected $casts = [ protected $casts = [
'translations' => 'array', 'translations' => 'array',

View File

@ -4,19 +4,47 @@
use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;
class Skill extends Model class Skill extends Model
{ {
use HasFactory, HasTranslations; use HasFactory;
protected $table = 'website_skills'; protected $table = 'website_skills';
protected $fillable = ['image', 'link', 'about_me_id', 'percentage']; protected $fillable = ['image', 'link', 'about_me_id', 'percentage',
'translations',];
protected array $translatable = ['title', 'description'];
public function aboutMe() public function aboutMe()
{ {
return $this->belongsTo(AboutMe::class, 'about_me_id'); return $this->belongsTo(AboutMe::class, 'about_me_id');
} }
protected $casts = [
'translations' => 'array',
];
public function getTranslation(string $key, string $locale, bool $useFallbackLocale = true): mixed
{
$translations = $this->translations;
if (isset($translations[$key][$locale])) {
return $translations[$key][$locale];
}
if ($useFallbackLocale && isset($translations[$key]['en'])) {
return $translations[$key]['en'];
}
return null;
}
public function getTitleAttribute()
{
return $this->translations['title'] ?? null;
}
public function getDescriptionAttribute()
{
return $this->translations['description'] ?? null;
}
} }

View File

@ -12,13 +12,15 @@ public function run()
{ {
$aboutMe = AboutMe::create([ $aboutMe = AboutMe::create([
'image' => '/images/profile.png', 'image' => '/images/profile.png',
'title' => [ 'translations' => [
'en' => 'About Me', 'title' => [
'fa' => 'درباره من', 'en' => 'About Me',
], 'fa' => 'درباره من',
'description' => [ ],
'en' => 'With over 10 years of experience in web development, I bridge the gap between pixel-perfect frontend engineering and robust backend architecture. Specialized in refactoring legacy codebases, optimizing core web vitals, and building scalable enterprise-grade Next.js applications.', 'description' => [
'fa' => 'با بیش از ۱۰ سال تجربه در دنیای توسعه وب، مسیر کاری من ترکیبی از مهندسی دقیق فرانت‌اند و درک عمیق از معماری بک‌اند است. تخصص اصلی من در بازطراحی و Refactor کدهای پیچیده، بهینه‌سازی Performance پروژه‌های بزرگ Next.js و پیاده‌سازی زیرساخت‌های پایدار وب است.', 'en' => 'With over 10 years of experience in web development, I bridge the gap between pixel-perfect frontend engineering and robust backend architecture. Specialized in refactoring legacy codebases, optimizing core web vitals, and building scalable enterprise-grade Next.js applications.',
'fa' => 'با بیش از ۱۰ سال تجربه در دنیای توسعه وب، مسیر کاری من ترکیبی از مهندسی دقیق فرانت‌اند و درک عمیق از معماری بک‌اند است. تخصص اصلی من در بازطراحی و Refactor کدهای پیچیده، بهینه‌سازی Performance پروژه‌های بزرگ Next.js و پیاده‌سازی زیرساخت‌های پایدار وب است.',
],
], ],
]); ]);
@ -27,22 +29,28 @@ public function run()
'image' => '/images/frontend.png', 'image' => '/images/frontend.png',
'percentage' => 100, 'percentage' => 100,
'link' => '#', 'link' => '#',
'title' => ['en' => 'React / Next.js / TypeScript', 'fa' => 'React / Next.js / TypeScript'], 'translations' => [
'description' => ['en' => 'Core Tech', 'fa' => 'تکنولوژی‌های اصلی'], 'title' => ['en' => 'React / Next.js / TypeScript', 'fa' => 'React / Next.js / TypeScript'],
'description' => ['en' => 'Core Tech', 'fa' => 'تکنولوژی‌های اصلی'],
],
], ],
[ [
'image' => '/images/backend.png', 'image' => '/images/backend.png',
'percentage' => 100, 'percentage' => 100,
'link' => '#', 'link' => '#',
'title' => ['en' => 'Laravel / PHP / MySQL', 'fa' => 'Laravel / PHP / MySQL'], 'translations' => [
'description' => ['en' => 'Backend & Tools', 'fa' => 'بک‌اند و ابزارها'], 'title' => ['en' => 'Laravel / PHP / MySQL', 'fa' => 'Laravel / PHP / MySQL'],
'description' => ['en' => 'Backend & Tools', 'fa' => 'بک‌اند و ابزارها'],
],
], ],
[ [
'image' => '/images/ui.png', 'image' => '/images/ui.png',
'percentage' => 100, 'percentage' => 100,
'link' => '#', 'link' => '#',
'title' => ['en' => 'TDD / Clean Architecture', 'fa' => 'TDD / Clean Architecture'], 'translations' => [
'description' => ['en' => 'Architecture & Others', 'fa' => 'معماری و سایر موارد'], 'title' => ['en' => 'TDD / Clean Architecture', 'fa' => 'TDD / Clean Architecture'],
'description' => ['en' => 'Architecture & Others', 'fa' => 'معماری و سایر موارد'],
],
], ],
]; ];
@ -51,6 +59,3 @@ public function run()
} }
} }
} }
}
}

View File

@ -11,33 +11,44 @@ public function run()
{ {
$categories = [ $categories = [
[ [
'title' => ['en' => 'App Design', 'fa' => 'طراحی اپلیکیشن'], 'image' => 'category1.jpg',
'description' => ['en' => 'Description for App Design', 'fa' => 'توضیحات طراحی اپلیکیشن'], 'translations' => [
'title' => ['en' => 'App Design', 'fa' => 'طراحی اپلیکیشن'],
'description' => ['en' => 'Description for App Design', 'fa' => 'توضیحات طراحی اپلیکیشن'],
],
], ],
[ [
'title' => ['en' => 'Front End', 'fa' => 'فرانت اند'], 'image' => 'category2.jpg',
'description' => ['en' => 'Description for Front End', 'fa' => 'توضیحات فرانت اند'], 'translations' => [
'title' => ['en' => 'Front End', 'fa' => 'فرانت اند'],
'description' => ['en' => 'Description for Front End', 'fa' => 'توضیحات فرانت اند'],
],
], ],
[ [
'title' => ['en' => 'Backend', 'fa' => 'بک اند'], 'image' => 'category3.jpg',
'description' => ['en' => 'Description for Backend', 'fa' => 'توضیحات بک اند'], 'translations' => [
'title' => ['en' => 'Backend', 'fa' => 'بک اند'],
'description' => ['en' => 'Description for Backend', 'fa' => 'توضیحات بک اند'],
],
], ],
[ [
'title' => ['en' => 'Web Design', 'fa' => 'طراحی وب'], 'image' => 'category4.jpg',
'description' => ['en' => 'Description for Web Design', 'fa' => 'توضیحات طراحی وب'], 'translations' => [
'title' => ['en' => 'Web Design', 'fa' => 'طراحی وب'],
'description' => ['en' => 'Description for Web Design', 'fa' => 'توضیحات طراحی وب'],
],
], ],
[ [
'title' => ['en' => 'Graphic Design', 'fa' => 'طراحی گرافیک'], 'image' => 'category5.jpg',
'description' => ['en' => 'Description for Graphic Design', 'fa' => 'توضیحات طراحی گرافیک'], 'translations' => [
'title' => ['en' => 'Graphic Design', 'fa' => 'طراحی گرافیک'],
'description' => ['en' => 'Description for Graphic Design', 'fa' => 'توضیحات طراحی گرافیک'],
],
], ],
]; ];
foreach ($categories as $key => $category) { foreach ($categories as $category) {
ProjectCategory::create([ ProjectCategory::create($category);
'image' => 'category' . ($key + 1) . '.jpg',
'title' => $category['title'],
'description' => $category['description'],
]);
} }
} }
} }

View File

@ -20,13 +20,15 @@ public function run()
'category_id' => $category->id, 'category_id' => $category->id,
'image1' => 'project' . $i . '_image1.jpg', 'image1' => 'project' . $i . '_image1.jpg',
'image2' => 'project' . $i . '_image2.jpg', 'image2' => 'project' . $i . '_image2.jpg',
'title' => [ 'translations' => [
'en' => 'Project ' . $i . ' - ' . $category->getTranslation('title', 'en'), 'title' => [
'fa' => 'پروژه ' . $i . ' - ' . $category->getTranslation('title', 'fa'), 'en' => 'Project ' . $i . ' - ' . $category->getTranslation('title', 'en'),
], 'fa' => 'پروژه ' . $i . ' - ' . $category->getTranslation('title', 'fa'),
'description' => [ ],
'en' => 'Description for project ' . $i . ' in category ' . $category->getTranslation('title', 'en'), 'description' => [
'fa' => 'توضیحات پروژه ' . $i . ' برای دسته‌بندی ' . $category->getTranslation('title', 'fa'), 'en' => 'Description for project ' . $i . ' in category ' . $category->getTranslation('title', 'en'),
'fa' => 'توضیحات پروژه ' . $i . ' برای دسته‌بندی ' . $category->getTranslation('title', 'fa'),
],
], ],
]); ]);
} }

View File

@ -12,35 +12,41 @@ public function run()
$services = [ $services = [
[ [
'imageSrc' => '/images/ui-ux-vector.svg', 'imageSrc' => '/images/ui-ux-vector.svg',
'title' => [ 'translations' => [
'en' => 'Senior Frontend Engineering', 'title' => [
'fa' => 'توسعه فرانت‌اند ارشد', 'en' => 'Senior Frontend Engineering',
], 'fa' => 'توسعه فرانت‌اند ارشد',
'description' => [ ],
'en' => 'Building ultra-fast SSR/Static apps, complex state management, and modern UI architectures focusing on core web vitals.', 'description' => [
'fa' => 'خلق SPAها و SSRهای بسیار سریع با Next.js، مدیریت استیت‌های پیچیده و بهینه‌سازی Core Web Vitals', 'en' => 'Building ultra-fast SSR/Static apps, complex state management, and modern UI architectures focusing on core web vitals.',
'fa' => 'خلق SPAها و SSRهای بسیار سریع با Next.js، مدیریت استیت‌های پیچیده و بهینه‌سازی Core Web Vitals',
],
], ],
], ],
[ [
'imageSrc' => '/images/web-design-vector.svg', 'imageSrc' => '/images/web-design-vector.svg',
'title' => [ 'translations' => [
'en' => 'Backend & API Design', 'title' => [
'fa' => 'معماری و توسعه بک‌اند', 'en' => 'Backend & API Design',
], 'fa' => 'معماری و توسعه بک‌اند',
'description' => [ ],
'en' => 'Designing secure, modular, and optimized RESTful APIs using Laravel and database optimization for scalable systems.', 'description' => [
'fa' => 'طراحی APIهای ماژولار، امن و بهینه با Laravel و مدیریت دیتابیس‌های مقیاس‌پذیر', 'en' => 'Designing secure, modular, and optimized RESTful APIs using Laravel and database optimization for scalable systems.',
'fa' => 'طراحی APIهای ماژولار، امن و بهینه با Laravel و مدیریت دیتابیس‌های مقیاس‌پذیر',
],
], ],
], ],
[ [
'imageSrc' => '/images/app-design-vector.svg', 'imageSrc' => '/images/app-design-vector.svg',
'title' => [ 'translations' => [
'en' => 'Code Refactoring & Modernization', 'title' => [
'fa' => 'بازطراحی و مدرن‌سازی کد', 'en' => 'Code Refactoring & Modernization',
], 'fa' => 'بازطراحی و مدرن‌سازی کد',
'description' => [ ],
'en' => 'Migrating legacy systems into clean, component-driven, and fully testable architectures to ensure long-term maintainability.', 'description' => [
'fa' => 'تبدیل کدهای قدیمی و مگالیتی به معماری‌های کامپوننت‌محور، تمیز و تست‌پذیر', 'en' => 'Migrating legacy systems into clean, component-driven, and fully testable architectures to ensure long-term maintainability.',
'fa' => 'تبدیل کدهای قدیمی و مگالیتی به معماری‌های کامپوننت‌محور، تمیز و تست‌پذیر',
],
], ],
], ],
]; ];