From 223a4f5640aceeac559be9726d63f45b4834bdb1 Mon Sep 17 00:00:00 2001 From: DevOps Date: Sun, 28 Jun 2026 17:37:08 +0000 Subject: [PATCH] fix: remove HasTranslations trait, use translations JSON in models + seeders --- app/Models/Website/AboutMe.php | 36 ++++++++++++-- app/Models/Website/Project.php | 36 ++++++++++++-- app/Models/Website/ProjectCategory.php | 36 ++++++++++++-- app/Models/Website/Service.php | 3 +- app/Models/Website/Skill.php | 36 ++++++++++++-- database/seeders/Website/AboutMeSeeder.php | 37 +++++++------- .../seeders/Website/ProjectCategorySeeder.php | 43 ++++++++++------- database/seeders/Website/ProjectSeeder.php | 16 ++++--- database/seeders/Website/ServiceSeeder.php | 48 +++++++++++-------- 9 files changed, 214 insertions(+), 77 deletions(-) diff --git a/app/Models/Website/AboutMe.php b/app/Models/Website/AboutMe.php index 064da97..c31f55c 100644 --- a/app/Models/Website/AboutMe.php +++ b/app/Models/Website/AboutMe.php @@ -4,19 +4,47 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -use Spatie\Translatable\HasTranslations; + class AboutMe extends Model { - use HasFactory, HasTranslations; + use HasFactory; protected $table = 'website_about_me'; - protected $fillable = ['image']; + protected $fillable = ['image', + 'translations',]; - protected array $translatable = ['title', 'description']; + public function skills() { 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; + } + } diff --git a/app/Models/Website/Project.php b/app/Models/Website/Project.php index dd41339..b8c8c45 100644 --- a/app/Models/Website/Project.php +++ b/app/Models/Website/Project.php @@ -4,19 +4,47 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -use Spatie\Translatable\HasTranslations; + class Project extends Model { - use HasFactory, HasTranslations; + use HasFactory; 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() { 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; + } + } diff --git a/app/Models/Website/ProjectCategory.php b/app/Models/Website/ProjectCategory.php index f27d81a..e1fb02e 100644 --- a/app/Models/Website/ProjectCategory.php +++ b/app/Models/Website/ProjectCategory.php @@ -4,14 +4,42 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -use Spatie\Translatable\HasTranslations; + class ProjectCategory extends Model { - use HasFactory, HasTranslations; + use HasFactory; 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']; } diff --git a/app/Models/Website/Service.php b/app/Models/Website/Service.php index 805ea66..5a5d430 100644 --- a/app/Models/Website/Service.php +++ b/app/Models/Website/Service.php @@ -10,7 +10,8 @@ class Service extends Model use HasFactory; protected $table = 'website_services'; - protected $fillable = ['imageSrc']; + protected $fillable = ['imageSrc', + 'translations']; protected $casts = [ 'translations' => 'array', diff --git a/app/Models/Website/Skill.php b/app/Models/Website/Skill.php index b4e24f4..51ad6dd 100644 --- a/app/Models/Website/Skill.php +++ b/app/Models/Website/Skill.php @@ -4,19 +4,47 @@ use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; -use Spatie\Translatable\HasTranslations; + class Skill extends Model { - use HasFactory, HasTranslations; + use HasFactory; 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() { 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; + } + } diff --git a/database/seeders/Website/AboutMeSeeder.php b/database/seeders/Website/AboutMeSeeder.php index ae5d60e..b511962 100644 --- a/database/seeders/Website/AboutMeSeeder.php +++ b/database/seeders/Website/AboutMeSeeder.php @@ -12,13 +12,15 @@ public function run() { $aboutMe = AboutMe::create([ 'image' => '/images/profile.png', - 'title' => [ - '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.', - 'fa' => 'با بیش از ۱۰ سال تجربه در دنیای توسعه وب، مسیر کاری من ترکیبی از مهندسی دقیق فرانت‌اند و درک عمیق از معماری بک‌اند است. تخصص اصلی من در بازطراحی و Refactor کدهای پیچیده، بهینه‌سازی Performance پروژه‌های بزرگ Next.js و پیاده‌سازی زیرساخت‌های پایدار وب است.', + 'translations' => [ + 'title' => [ + '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.', + 'fa' => 'با بیش از ۱۰ سال تجربه در دنیای توسعه وب، مسیر کاری من ترکیبی از مهندسی دقیق فرانت‌اند و درک عمیق از معماری بک‌اند است. تخصص اصلی من در بازطراحی و Refactor کدهای پیچیده، بهینه‌سازی Performance پروژه‌های بزرگ Next.js و پیاده‌سازی زیرساخت‌های پایدار وب است.', + ], ], ]); @@ -27,22 +29,28 @@ public function run() 'image' => '/images/frontend.png', 'percentage' => 100, 'link' => '#', - 'title' => ['en' => 'React / Next.js / TypeScript', 'fa' => 'React / Next.js / TypeScript'], - 'description' => ['en' => 'Core Tech', 'fa' => 'تکنولوژی‌های اصلی'], + 'translations' => [ + 'title' => ['en' => 'React / Next.js / TypeScript', 'fa' => 'React / Next.js / TypeScript'], + 'description' => ['en' => 'Core Tech', 'fa' => 'تکنولوژی‌های اصلی'], + ], ], [ 'image' => '/images/backend.png', 'percentage' => 100, 'link' => '#', - 'title' => ['en' => 'Laravel / PHP / MySQL', 'fa' => 'Laravel / PHP / MySQL'], - 'description' => ['en' => 'Backend & Tools', 'fa' => 'بک‌اند و ابزارها'], + 'translations' => [ + 'title' => ['en' => 'Laravel / PHP / MySQL', 'fa' => 'Laravel / PHP / MySQL'], + 'description' => ['en' => 'Backend & Tools', 'fa' => 'بک‌اند و ابزارها'], + ], ], [ 'image' => '/images/ui.png', 'percentage' => 100, 'link' => '#', - 'title' => ['en' => 'TDD / Clean Architecture', 'fa' => 'TDD / Clean Architecture'], - 'description' => ['en' => 'Architecture & Others', 'fa' => 'معماری و سایر موارد'], + 'translations' => [ + 'title' => ['en' => 'TDD / Clean Architecture', 'fa' => 'TDD / Clean Architecture'], + 'description' => ['en' => 'Architecture & Others', 'fa' => 'معماری و سایر موارد'], + ], ], ]; @@ -51,6 +59,3 @@ public function run() } } } - - } -} diff --git a/database/seeders/Website/ProjectCategorySeeder.php b/database/seeders/Website/ProjectCategorySeeder.php index d5b975c..8cc9bb8 100644 --- a/database/seeders/Website/ProjectCategorySeeder.php +++ b/database/seeders/Website/ProjectCategorySeeder.php @@ -11,33 +11,44 @@ public function run() { $categories = [ [ - 'title' => ['en' => 'App Design', 'fa' => 'طراحی اپلیکیشن'], - 'description' => ['en' => 'Description for App Design', 'fa' => 'توضیحات طراحی اپلیکیشن'], + 'image' => 'category1.jpg', + 'translations' => [ + 'title' => ['en' => 'App Design', 'fa' => 'طراحی اپلیکیشن'], + 'description' => ['en' => 'Description for App Design', 'fa' => 'توضیحات طراحی اپلیکیشن'], + ], ], [ - 'title' => ['en' => 'Front End', 'fa' => 'فرانت اند'], - 'description' => ['en' => 'Description for Front End', 'fa' => 'توضیحات فرانت اند'], + 'image' => 'category2.jpg', + 'translations' => [ + 'title' => ['en' => 'Front End', 'fa' => 'فرانت اند'], + 'description' => ['en' => 'Description for Front End', 'fa' => 'توضیحات فرانت اند'], + ], ], [ - 'title' => ['en' => 'Backend', 'fa' => 'بک اند'], - 'description' => ['en' => 'Description for Backend', 'fa' => 'توضیحات بک اند'], + 'image' => 'category3.jpg', + 'translations' => [ + 'title' => ['en' => 'Backend', 'fa' => 'بک اند'], + 'description' => ['en' => 'Description for Backend', 'fa' => 'توضیحات بک اند'], + ], ], [ - 'title' => ['en' => 'Web Design', 'fa' => 'طراحی وب'], - 'description' => ['en' => 'Description for Web Design', 'fa' => 'توضیحات طراحی وب'], + 'image' => 'category4.jpg', + 'translations' => [ + 'title' => ['en' => 'Web Design', 'fa' => 'طراحی وب'], + 'description' => ['en' => 'Description for Web Design', 'fa' => 'توضیحات طراحی وب'], + ], ], [ - 'title' => ['en' => 'Graphic Design', 'fa' => 'طراحی گرافیک'], - 'description' => ['en' => 'Description for Graphic Design', 'fa' => 'توضیحات طراحی گرافیک'], + 'image' => 'category5.jpg', + 'translations' => [ + 'title' => ['en' => 'Graphic Design', 'fa' => 'طراحی گرافیک'], + 'description' => ['en' => 'Description for Graphic Design', 'fa' => 'توضیحات طراحی گرافیک'], + ], ], ]; - foreach ($categories as $key => $category) { - ProjectCategory::create([ - 'image' => 'category' . ($key + 1) . '.jpg', - 'title' => $category['title'], - 'description' => $category['description'], - ]); + foreach ($categories as $category) { + ProjectCategory::create($category); } } } diff --git a/database/seeders/Website/ProjectSeeder.php b/database/seeders/Website/ProjectSeeder.php index 5f447df..aa63862 100644 --- a/database/seeders/Website/ProjectSeeder.php +++ b/database/seeders/Website/ProjectSeeder.php @@ -20,13 +20,15 @@ public function run() 'category_id' => $category->id, 'image1' => 'project' . $i . '_image1.jpg', 'image2' => 'project' . $i . '_image2.jpg', - 'title' => [ - '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'), - 'fa' => 'توضیحات پروژه ' . $i . ' برای دسته‌بندی ' . $category->getTranslation('title', 'fa'), + 'translations' => [ + 'title' => [ + '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'), + 'fa' => 'توضیحات پروژه ' . $i . ' برای دسته‌بندی ' . $category->getTranslation('title', 'fa'), + ], ], ]); } diff --git a/database/seeders/Website/ServiceSeeder.php b/database/seeders/Website/ServiceSeeder.php index 8fff5c1..1345576 100644 --- a/database/seeders/Website/ServiceSeeder.php +++ b/database/seeders/Website/ServiceSeeder.php @@ -12,35 +12,41 @@ public function run() $services = [ [ 'imageSrc' => '/images/ui-ux-vector.svg', - 'title' => [ - '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.', - 'fa' => 'خلق SPAها و SSRهای بسیار سریع با Next.js، مدیریت استیت‌های پیچیده و بهینه‌سازی Core Web Vitals', + 'translations' => [ + 'title' => [ + '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.', + 'fa' => 'خلق SPAها و SSRهای بسیار سریع با Next.js، مدیریت استیت‌های پیچیده و بهینه‌سازی Core Web Vitals', + ], ], ], [ 'imageSrc' => '/images/web-design-vector.svg', - 'title' => [ - 'en' => 'Backend & API Design', - 'fa' => 'معماری و توسعه بک‌اند', - ], - 'description' => [ - 'en' => 'Designing secure, modular, and optimized RESTful APIs using Laravel and database optimization for scalable systems.', - 'fa' => 'طراحی APIهای ماژولار، امن و بهینه با Laravel و مدیریت دیتابیس‌های مقیاس‌پذیر', + 'translations' => [ + 'title' => [ + 'en' => 'Backend & API Design', + 'fa' => 'معماری و توسعه بک‌اند', + ], + 'description' => [ + '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', - 'title' => [ - 'en' => 'Code Refactoring & Modernization', - 'fa' => 'بازطراحی و مدرن‌سازی کد', - ], - 'description' => [ - 'en' => 'Migrating legacy systems into clean, component-driven, and fully testable architectures to ensure long-term maintainability.', - 'fa' => 'تبدیل کدهای قدیمی و مگالیتی به معماری‌های کامپوننت‌محور، تمیز و تست‌پذیر', + 'translations' => [ + 'title' => [ + 'en' => 'Code Refactoring & Modernization', + 'fa' => 'بازطراحی و مدرن‌سازی کد', + ], + 'description' => [ + 'en' => 'Migrating legacy systems into clean, component-driven, and fully testable architectures to ensure long-term maintainability.', + 'fa' => 'تبدیل کدهای قدیمی و مگالیتی به معماری‌های کامپوننت‌محور، تمیز و تست‌پذیر', + ], ], ], ];