Add Language Management Module: Created Language resource with CRUD pages, schemas, and models to support the universal translation system. Implemented localization for English and Turkish, ensuring consistent user experience. Added necessary policies and seeder for initial language data, enhancing the overall language management functionality.

This commit is contained in:
Ümit Tunç
2025-10-01 04:15:21 -03:00
parent 7cbbf521e1
commit a4aea280f2
21 changed files with 2398 additions and 4 deletions
+352
View File
@@ -0,0 +1,352 @@
# Translation System - Quick Start Guide
## 🚀 5 Dakikada Başlangıç
### 1️⃣ Admin Panel'e Git
```
http://your-domain.com/admin/languages
```
### 2️⃣ Dilleri Aktifleştir
- 🇹🇷 Türkçe (TR) - Zaten aktif (varsayılan)
- 🇬🇧 İngilizce (EN) - Zaten aktif
- 🇩🇪 Almanca (DE) - İsterseniz aktif edin
- 🇫🇷 Fransızca (FR) - İsterseniz aktif edin
### 3️⃣ İlk Çeviriyi Ekle
#### Tinker ile (Terminal):
```bash
php artisan tinker
# Blog çevirisi ekle
$blog = App\Models\Blog::first();
$blog->setTranslation('title', 'en', 'My First Blog Post', 'published');
$blog->setTranslation('content', 'en', 'This is my blog content in English...', 'published');
# Kontrol et
echo $blog->translate('title', 'en');
```
#### Kod ile:
```php
use App\Models\Blog;
$blog = Blog::find(1);
// İngilizce çeviri ekle
$blog->setTranslation('title', 'en', 'My Blog Title', 'published');
$blog->setTranslation('content', 'en', 'Blog content here...', 'published');
$blog->setTranslation('excerpt', 'en', 'Short description', 'published');
// Oku
echo $blog->translate('title'); // Mevcut dilde
echo $blog->translate('title', 'en'); // İngilizce
echo $blog->translate('title', 'tr'); // Türkçe
```
### 4️⃣ Translation Progress Kontrol Et
```php
$blog = Blog::find(1);
// İlerleme yüzdeleri
$progress = $blog->getTranslationProgress();
print_r($progress);
// ['tr' => 100, 'en' => 60, 'de' => 0]
// Eksik çeviriler
$missing = $blog->getMissingTranslations('en');
print_r($missing);
// ['meta_title', 'meta_description']
// Durum
echo $blog->getTranslationStatus('en'); // 'partial'
```
### 5️⃣ Kullanıcıya Dil Yetkisi Ver
```php
use App\Models\User;
$user = User::find(1);
// Türkçe içerik yöneticisi
$user->assignLanguage('tr',
canCreate: true,
canEdit: true,
canApprove: true,
canPublish: true
);
// İngilizce çevirmen (yayınlayamaz)
$user->assignLanguage('en',
canCreate: true,
canEdit: true,
canApprove: false,
canPublish: false
);
// Kontrol
if ($user->canManageLanguage('tr')) {
echo "User can manage Turkish!";
}
```
## 💡 Yaygın Kullanım Örnekleri
### Örnek 1: Blog Oluştur ve Çevir
```php
// 1. Türkçe blog oluştur
$blog = Blog::create([
'title' => 'Laravel Eğitimi',
'slug' => 'laravel-egitimi',
'content' => 'Laravel hakkında detaylı bilgi...',
'excerpt' => 'Laravel nedir?',
'status' => 'published',
'author_id' => 1,
]);
// 2. İngilizce çevirisi ekle
$blog->setTranslation('title', 'en', 'Laravel Tutorial', 'published');
$blog->setTranslation('content', 'en', 'Detailed info about Laravel...', 'published');
$blog->setTranslation('excerpt', 'en', 'What is Laravel?', 'published');
// 3. Almanca çevirisi ekle (draft olarak)
$blog->setTranslation('title', 'de', 'Laravel Tutorial', 'draft');
$blog->setTranslation('content', 'de', 'Detaillierte Informationen über Laravel...', 'draft');
// 4. Çevirileri kullan
echo $blog->translate('title'); // Mevcut dilde
echo $blog->translate('title', 'en'); // İngilizce
echo $blog->translate('title', 'de'); // Almanca (draft, yayında değil)
```
### Örnek 2: Translation Workflow
```php
$blog = Blog::find(1);
// Çeviri oluştur (draft olarak başlar)
$translation = $blog->setTranslation('title', 'en', 'My Title', 'draft');
// Workflow adımları
$translation->submitForReview(); // Draft → Review
$translation->approve(auth()->id()); // Review → Approved
$translation->publish(auth()->id()); // Approved → Published
// Veya direkt yayınla
$translation->publish(); // Draft/Review/Approved → Published
// Geri al
$translation->unpublish(); // Published → Approved
$translation->reject(); // Review → Draft
```
### Örnek 3: Yeni Model Ekle
```php
// 1. Model oluştur
class Product extends Model
{
use HasTranslations;
protected $fillable = [
'name', 'slug', 'description', 'price', 'sku'
];
protected $translatable = [
'name',
'description',
];
}
// 2. Migration
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('slug')->unique();
$table->text('description');
$table->decimal('price', 10, 2);
$table->string('sku')->unique();
$table->timestamps();
});
// 3. Kullan
$product = Product::create([
'name' => 'Laptop',
'slug' => 'laptop',
'description' => 'Yüksek performanslı laptop',
'price' => 15000,
'sku' => 'LAP-001'
]);
$product->setTranslation('name', 'en', 'Laptop', 'published');
$product->setTranslation('description', 'en', 'High performance laptop', 'published');
// Artık Product'da çeviri var! 🎉
echo $product->translate('name', 'en'); // "Laptop"
```
### Örnek 4: Tüm Çevirileri Getir
```php
$blog = Blog::find(1);
// Bir alanın tüm dillerdeki çevirileri
$titleTranslations = $blog->getTranslations('title');
foreach ($titleTranslations as $langCode => $translation) {
echo "{$langCode}: {$translation->field_value}\n";
}
// tr: Laravel Eğitimi
// en: Laravel Tutorial
// de: Laravel Tutorial
// Bir dilin tüm alan çevirileri
$enTranslations = $blog->getTranslationsForLanguage('en');
foreach ($enTranslations as $fieldName => $translation) {
echo "{$fieldName}: {$translation->field_value}\n";
}
// title: Laravel Tutorial
// content: Detailed info about Laravel...
// excerpt: What is Laravel?
```
### Örnek 5: Helper Functions
```php
// Mevcut dil
$currentLang = current_language(); // Language model
$currentCode = current_language_code(); // 'tr'
// Varsayılan dil
$defaultLang = default_language();
$defaultCode = default_language_code(); // 'tr'
// Aktif diller
$languages = available_languages(); // Collection [TR, EN]
$codes = available_language_codes(); // ['tr', 'en']
// Dil değiştir
switch_language('en');
app()->setLocale('en');
// Model çevirisi
$title = translate_model($blog, 'title', 'en');
// Çeviri var mı?
if (has_translation($blog, 'title', 'en')) {
echo "English translation exists!";
}
// İlerleme
$progress = translation_progress($blog, 'en'); // 75
// Kullanıcı dilleri
$userLanguages = user_managed_languages(); // Collection
$userCodes = user_managed_language_codes(); // ['tr', 'en']
// Dil bilgileri
echo get_language_flag('tr'); // 🇹🇷
echo format_language_name('tr'); // Turkish (Türkçe)
```
## 🎯 Sık Sorulan Sorular
### 1. Varsayılan dilde çeviri lazım mı?
Hayır! Varsayılan dil (TR) için veritabanındaki orijinal değer kullanılır. Sadece diğer diller için çeviri eklemeniz yeterli.
### 2. Çeviri yoksa ne olur?
Fallback mekanizması devreye girer:
1. İstenen dilde ara
2. Yoksa varsayılan dilde ara
3. Yoksa model'deki orijinal değeri kullan
### 3. Draft çeviriler görünür mü?
Hayır, sadece `published` çeviriler görünür. Ama parametre ile draft'ları da alabilirsiniz:
```php
$translation = $blog->getTranslation('title', 'en', published: false);
```
### 4. Toplu çeviri nasıl yapılır?
```php
// TR'den EN'e tüm alanları kopyala
$blog->duplicateTranslation('tr', 'en');
// Tüm diller için placeholder oluştur
$blog->syncTranslations(['tr', 'en', 'de']);
```
### 5. Performans nasıl?
- ✅ Indexed queries
- ✅ Eager loading desteği
- ✅ Tek query ile tüm çevirileri çek
- ✅ Cache-ready yapı
## 📊 Dashboard Özet Örneği
```php
// Admin dashboard widget örneği
$stats = [
'total_languages' => Language::active()->count(),
'total_translations' => Translation::published()->count(),
'pending_approvals' => Translation::review()->count(),
'translation_progress' => []
];
foreach (Language::active()->get() as $language) {
$stats['translation_progress'][$language->code] = [
'name' => $language->name,
'flag' => $language->flag,
'count' => Translation::forLanguage($language->code)->published()->count(),
];
}
```
## 🎨 Blade Template Kullanımı
```blade
{{-- Mevcut dilde --}}
<h1>{{ $blog->translate('title') }}</h1>
{{-- Belirli dilde --}}
<h1>{{ $blog->translate('title', 'en') }}</h1>
{{-- Helper ile --}}
<h1>{{ translate_model($blog, 'title') }}</h1>
{{-- Dil seçici --}}
@foreach(available_languages() as $language)
<a href="?lang={{ $language->code }}">
{{ $language->flag }} {{ $language->name }}
</a>
@endforeach
{{-- Progress bar --}}
@php
$progress = $blog->getTranslationProgress();
@endphp
@foreach($progress as $code => $percentage)
<div class="progress-bar">
<span>{{ get_language_flag($code) }}</span>
<div style="width: {{ $percentage }}%">{{ $percentage }}%</div>
</div>
@endforeach
```
## 🔥 Pro Tips
1. **Her zaman published status kullanın** (son kullanıcı için)
2. **Draft status kullanın** (henüz tamamlanmamış çeviriler için)
3. **Translation progress ile takip edin** (hangi diller eksik?)
4. **User-language permissions ile kontrol edin** (kim ne yapabilir?)
5. **Fallback mekanizmasını kullanın** (eksik çeviriler için)
---
Hazırsınız! 🚀 Artık universal translation sisteminiz tamamen çalışıyor!
+431
View File
@@ -0,0 +1,431 @@
# Universal Dynamic Translation System
## 🌟 Genel Bakış
Citrus Platform için geliştirilmiş **evrensel, dinamik ve role-based** çeviri sistemi. Bu sistem, herhangi bir modelin çeviri desteğine sahip olmasını sağlar ve kullanıcı bazlı dil yönetimi sunar.
## 📋 Sistem Mimarisi
```
┌─────────────────┐
│ languages │ → Dinamik dil tanımları (TR, EN, DE, FR, AR...)
└─────────────────┘
┌─────────────────┐
│ translations │ → Evrensel çeviri tablosu (polymorphic)
└─────────────────┘
┌─────────────────┐
│ user_languages │ → Kullanıcı-Dil ilişkisi (yetkiler)
└─────────────────┘
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──────────┐
│ pages │ │ blogs │ │products │ │ news │ → Herhangi bir model
└─────────┘ └─────────┘ └─────────┘ └──────────┘
```
## ✅ Kurulum ve Yapılandırma
### 1. Database Tabloları
```bash
php artisan migrate
```
Oluşturulan tablolar:
- `languages` - Dil tanımları
- `translations` - Çeviri veriler (polymorphic)
- `user_languages` - Kullanıcı-dil yetkileri
### 2. Varsayılan Diller
```bash
php artisan db:seed --class=LanguageSeeder
```
Eklenen diller:
- 🇹🇷 Türkçe (tr) - Varsayılan, Aktif
- 🇬🇧 İngilizce (en) - Aktif
- 🇩🇪 Almanca (de) - Pasif
- 🇫🇷 Fransızca (fr) - Pasif
- 🇸🇦 Arapça (ar) - Pasif, RTL
### 3. Model Entegrasyonu
Herhangi bir modele çeviri desteği eklemek için:
```php
use App\Traits\HasTranslations;
class YourModel extends Model
{
use HasTranslations;
protected $translatable = [
'title',
'description',
'content',
];
}
```
## 🎯 Kullanım
### Çeviri Kaydetme
```php
// Basit çeviri kaydetme
$blog->setTranslation('title', 'en', 'My Blog Post');
// Status ile kaydetme
$blog->setTranslation('title', 'en', 'My Blog Post', 'published');
// Kullanıcı ID ile
$blog->setTranslation('title', 'en', 'My Blog Post', 'draft', auth()->id());
```
### Çeviri Okuma
```php
// Mevcut dilde
$title = $blog->translate('title');
// Belirli bir dilde
$title = $blog->translate('title', 'en');
// Fallback olmadan
$title = $blog->translate('title', 'en', false);
```
### Toplu İşlemler
```php
// Tüm çevirileri al (bir alan için)
$translations = $blog->getTranslations('title');
// ['tr' => 'Blog Yazım', 'en' => 'My Blog Post']
// Bir dildeki tüm çevirileri al
$translations = $blog->getTranslationsForLanguage('en');
// ['title' => 'My Blog Post', 'content' => '...']
// Çeviri var mı kontrol et
if ($blog->hasTranslation('title', 'en')) {
// ...
}
```
### Translation Progress
```php
// Tüm diller için ilerleme
$progress = $blog->getTranslationProgress();
// ['tr' => 100, 'en' => 75, 'de' => 0]
// Eksik çevirileri bul
$missing = $blog->getMissingTranslations('en');
// ['meta_description', 'excerpt']
// Çeviri durumu
$status = $blog->getTranslationStatus('en');
// 'complete', 'partial', 'missing'
```
### Translation Workflow
```php
// Çeviri oluştur (draft)
$translation = $blog->setTranslation('title', 'en', 'My Title', 'draft');
// Onaya gönder
$translation->submitForReview();
// Onayla
$translation->approve(auth()->id());
// Yayınla
$translation->publish(auth()->id());
// Reddet
$translation->reject();
```
### Dil Değiştirme
```php
// Runtime'da dil değiştir
switch_language('en');
// Uygulama dili
app()->setLocale('tr');
```
## 🔐 Kullanıcı Yetkilendirme
### Kullanıcıya Dil Atama
```php
// Tam yetki ile dil ata
$user->assignLanguage('tr',
canCreate: true,
canEdit: true,
canApprove: true,
canPublish: true
);
// Sadece oluşturma ve düzenleme yetkisi
$user->assignLanguage('en',
canCreate: true,
canEdit: true,
canApprove: false,
canPublish: false
);
```
### Yetki Kontrolleri
```php
// Kullanıcı bu dili yönetebilir mi?
if ($user->canManageLanguage('en')) {
// ...
}
// Specific permissions
if ($user->canCreateInLanguage('en')) { }
if ($user->canEditInLanguage('en')) { }
if ($user->canApproveInLanguage('en')) { }
if ($user->canPublishInLanguage('en')) { }
// Kullanıcının yönettiği diller
$languages = $user->getManagedLanguages();
$codes = $user->getManagedLanguageCodes(); // ['tr', 'en']
```
### Query Filtering
```php
// Sadece belirli dildeki içerikleri getir
Blog::whereHasTranslation('en')->get();
// Kullanıcının yönettiği dillerdeki içerikleri getir
Blog::whereHasTranslationForUser(auth()->user())->get();
```
## 🛠️ Helper Functions
```php
// Mevcut dil
$language = current_language(); // Language model
$code = current_language_code(); // 'tr'
// Varsayılan dil
$defaultLang = default_language();
$defaultCode = default_language_code();
// Aktif diller
$languages = available_languages(); // Collection
$codes = available_language_codes(); // ['tr', 'en']
// Model çevirisi
$value = translate_model($blog, 'title', 'en');
// Çeviri kontrolü
$exists = has_translation($blog, 'title', 'en');
// İlerleme
$progress = translation_progress($blog, 'en'); // 75
// Kullanıcı yetkileri
$can = user_can_manage_language('en');
$languages = user_managed_languages();
$codes = user_managed_language_codes();
// Dil bilgileri
$flag = get_language_flag('tr'); // 🇹🇷
$name = format_language_name('tr'); // Turkish (Türkçe)
// Status
$badge = get_translation_status_badge('published');
$color = get_translation_status_color('draft');
```
## 📊 Filament Admin Panel
### Language Management
Admin panelde **Languages** resource'u üzerinden:
- ✅ Dil ekleme/düzenleme/silme
- ✅ Dil aktif/pasif yapma
- ✅ Varsayılan dil seçme
- ✅ Sıralama düzenleme
- ✅ RTL/LTR desteği
### Permissions
Spatie Permission ile entegre:
- `language::viewAny`
- `language::view`
- `language::create`
- `language::update`
- `language::delete`
- `language::restore`
- `language::forceDelete`
- `language::activate`
- `language::setDefault`
### Policy Kuralları
- Varsayılan dil silinemez
- Varsayılan dil pasif edilemez
- Super admin tüm yetkilere sahip
- Diğer kullanıcılar permission'lara göre erişir
## 🎨 Translation Workflow Statuses
| Status | Açıklama | Badge Color |
|--------|----------|-------------|
| `draft` | Taslak, henüz onaylanmamış | Gray |
| `review` | Onay bekliyor | Warning |
| `approved` | Onaylanmış, yayınlanmayı bekliyor | Success |
| `published` | Yayınlanmış, görünür | Primary |
## 📦 Database Schema
### languages
```sql
id, code (unique), name, native_name, flag, direction,
is_active, is_default, sort_order,
created_by, updated_by, created_at, updated_at, deleted_at
```
### translations
```sql
id, translatable_type, translatable_id, language_code,
field_name, field_value, status, version,
created_by, updated_by, approved_by, approved_at, published_at,
created_at, updated_at, deleted_at
UNIQUE: translatable_type + translatable_id + language_code + field_name
```
### user_languages
```sql
id, user_id, language_code,
can_create, can_edit, can_approve, can_publish,
created_at, updated_at
UNIQUE: user_id + language_code
```
## 🚀 Örnekler
### Yeni Model için Çeviri Ekle
```php
// 1. Model oluştur
class Product extends Model
{
use HasTranslations;
protected $translatable = ['name', 'description', 'features'];
}
// 2. Çeviri ekle
$product = Product::create(['name' => 'Ürün', 'slug' => 'urun']);
$product->setTranslation('name', 'en', 'Product', 'published');
$product->setTranslation('description', 'en', 'Product description', 'published');
// 3. Kullan
echo $product->translate('name'); // Mevcut dilde
echo $product->translate('name', 'en'); // İngilizce'de
```
### Çeviri İlerlemesi Widget
```php
$progress = $blog->getTranslationProgress();
foreach ($progress as $langCode => $percentage) {
$language = Language::findByCode($langCode);
echo "{$language->flag} {$language->name}: {$percentage}%";
}
```
### Kullanıcı Dil Yönetimi
```php
// Turkish Editor oluştur
$user = User::find(1);
$user->assignLanguage('tr', true, true, false, true);
// English Translator oluştur
$translator = User::find(2);
$translator->assignLanguage('en', true, true, false, false);
// Multi-language Manager
$manager = User::find(3);
$manager->assignLanguage('tr', true, true, true, true);
$manager->assignLanguage('en', true, true, true, true);
```
## ⚡ Performans
- ✅ Indexed queries (translatable_type, translatable_id, language_code)
- ✅ Eager loading desteği
- ✅ Cache-ready yapı
- ✅ Efficient polymorphic relationships
- ✅ Unique constraints
## 🔄 Migration
Mevcut projeden yeni sisteme geçiş için:
```php
// Eski sistem
$blog->title_tr
$blog->title_en
// Yeni sisteme migrate
$blog->setTranslation('title', 'tr', $blog->title_tr, 'published');
$blog->setTranslation('title', 'en', $blog->title_en, 'published');
```
## 📝 Notlar
1. **Zero Configuration**: Yeni model için sadece trait ekle
2. **Dynamic**: Runtime'da dil ekle/çıkar
3. **Role-Based**: Her kullanıcı farklı dilleri yönetebilir
4. **Workflow**: Draft → Review → Approved → Published
5. **Fallback**: Çeviri yoksa default dile düş
6. **Version Control**: Her çevirinin versiyonu
7. **Soft Delete**: Tüm tablolar soft delete destekli
## 🎯 Gelecek Özellikler (TODO)
- [ ] Translation approval notifications
- [ ] Bulk translation import/export
- [ ] Translation memory (önceki çevirilerden öner)
- [ ] AI-powered translation suggestions
- [ ] Translation dashboard widget
- [ ] Language-specific user roles
- [ ] Translation history/audit log
- [ ] Compare translations side-by-side
- [ ] Missing translations report
## 📚 İlgili Dosyalar
- Models: `app/Models/Language.php`, `Translation.php`, `UserLanguage.php`
- Trait: `app/Traits/HasTranslations.php`
- Helpers: `app/Helpers/translation_helpers.php`
- Resource: `app/Filament/Admin/Resources/Languages/`
- Policy: `app/Policies/LanguagePolicy.php`
- Migrations: `database/migrations/*_create_languages_table.php`
- Translations: `lang/tr/language.php`, `lang/en/language.php`
---
**Geliştirici:** Citrus Platform Team
**Versiyon:** 1.0.0
**Tarih:** 1 Ekim 2025