Implement Site Translations API and DataGrid View: Introduced a new API controller for managing site translations, including methods for listing, storing, updating, and deleting translations. Added a DataGrid view for the site translations page, allowing for enhanced user interaction and management of translations. Implemented session-based view toggling between traditional table and DataGrid formats, improving usability. Localization support has been integrated for all text elements, ensuring a seamless experience for users across different languages.

This commit is contained in:
Ümit Tunç
2026-01-10 21:54:56 +03:00
parent 2fdf187658
commit e80c94146d
4 changed files with 730 additions and 1 deletions
@@ -0,0 +1,292 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use App\Models\SiteTranslation;
use App\Models\Language;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Validator;
class SiteTranslationController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index(Request $request): JsonResponse
{
$query = SiteTranslation::query();
// Search
if ($request->has('search')) {
$search = $request->get('search');
$query->where(function ($q) use ($search) {
$q->where('key', 'like', "%{$search}%")
->orWhereRaw("JSON_SEARCH(translations, 'one', ?, NULL, '$[*]') IS NOT NULL", ["%{$search}%"]);
});
}
// Sorting
$sortField = $request->get('sort', 'id');
$sortOrder = $request->get('order', 'desc');
$query->orderBy($sortField, $sortOrder);
// Pagination
$page = $request->get('page', 1);
$pageSize = $request->get('pageSize', 20);
$totalCount = $query->count();
$items = $query->skip(($page - 1) * $pageSize)->take($pageSize)->get();
// Format data for DataGrid
$data = $items->map(function ($item) {
$formatted = [
'id' => $item->id,
'key' => $item->key,
'hash' => $item->hash,
'created_at' => $item->created_at?->toDateTimeString(),
'updated_at' => $item->updated_at?->toDateTimeString(),
];
// Add translation fields for each active language
$languages = Language::where('is_active', true)->get();
$translations = $item->translations ?? [];
foreach ($languages as $language) {
$formatted[$language->code] = $translations[$language->code] ?? '';
}
return $formatted;
});
return response()->json([
'data' => $data,
'totalCount' => $totalCount,
]);
}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request): JsonResponse
{
$validator = Validator::make($request->all(), [
'key' => 'required|string|max:500',
]);
if ($validator->fails()) {
return response()->json([
'success' => false,
'errors' => $validator->errors(),
], 422);
}
$hash = md5($request->key);
// Check if translation already exists
$exists = SiteTranslation::where('hash', $hash)->first();
if ($exists) {
return response()->json([
'success' => false,
'message' => 'Bu key zaten mevcut.',
], 409);
}
$languages = Language::where('is_active', true)->get();
$translations = [];
foreach ($languages as $language) {
if ($request->has($language->code)) {
$translations[$language->code] = $request->get($language->code, '');
}
}
$translation = SiteTranslation::create([
'hash' => $hash,
'key' => $request->key,
'translations' => $translations,
]);
Cache::forget("site_translation_{$hash}");
return response()->json([
'success' => true,
'data' => $translation->load('translations'),
'message' => 'Çeviri başarıyla oluşturuldu.',
], 201);
}
/**
* Update the specified resource in storage.
*/
public function update(Request $request, $id): JsonResponse
{
$translation = SiteTranslation::findOrFail($id);
$validator = Validator::make($request->all(), [
'key' => 'sometimes|required|string|max:500',
]);
if ($validator->fails()) {
return response()->json([
'success' => false,
'errors' => $validator->errors(),
], 422);
}
$languages = Language::where('is_active', true)->get();
$translations = $translation->translations ?? [];
// Update translations
foreach ($languages as $language) {
if ($request->has($language->code)) {
$translations[$language->code] = $request->get($language->code, '');
}
}
// Update key if provided
if ($request->has('key') && $request->key !== $translation->key) {
$translation->key = $request->key;
$translation->hash = md5($request->key);
}
$translation->translations = $translations;
$translation->save();
Cache::forget("site_translation_{$translation->hash}");
return response()->json([
'success' => true,
'data' => $translation->fresh(),
'message' => 'Çeviri başarıyla güncellendi.',
]);
}
/**
* Batch update multiple resources.
*/
public function batchUpdate(Request $request): JsonResponse
{
$validator = Validator::make($request->all(), [
'changes' => 'required|array',
]);
if ($validator->fails()) {
return response()->json([
'success' => false,
'errors' => $validator->fails(),
], 422);
}
$changes = $request->get('changes', []);
$updated = [];
$errors = [];
foreach ($changes as $change) {
try {
// ID can be in 'key' field (integer) or directly in 'key' field
$id = is_numeric($change['key'] ?? null)
? (int)$change['key']
: ($change['key']['id'] ?? null);
if (!$id) {
$errors[] = 'ID bulunamadı.';
continue;
}
$translation = SiteTranslation::find($id);
if (!$translation) {
$errors[] = "ID {$id} için kayıt bulunamadı.";
continue;
}
$data = $change['data'] ?? [];
$languages = Language::where('is_active', true)->get();
$translations = $translation->translations ?? [];
// Update translations
foreach ($languages as $language) {
if (isset($data[$language->code])) {
$translations[$language->code] = $data[$language->code];
}
}
// Update key if provided
if (isset($data['key']) && $data['key'] !== $translation->key) {
$translation->key = $data['key'];
$translation->hash = md5($data['key']);
}
$translation->translations = $translations;
$translation->save();
Cache::forget("site_translation_{$translation->hash}");
$updated[] = $translation->id;
} catch (\Exception $e) {
$id = is_numeric($change['key'] ?? null)
? (int)$change['key']
: ($change['key']['id'] ?? 'unknown');
$errors[] = "ID {$id} için hata: " . $e->getMessage();
}
}
return response()->json([
'success' => count($errors) === 0,
'updated' => $updated,
'errors' => $errors,
'message' => count($updated) . ' kayıt güncellendi.',
]);
}
/**
* Remove the specified resource from storage.
*/
public function destroy($id): JsonResponse
{
$translation = SiteTranslation::findOrFail($id);
$hash = $translation->hash;
$translation->delete();
Cache::forget("site_translation_{$hash}");
return response()->json([
'success' => true,
'message' => 'Çeviri başarıyla silindi.',
]);
}
/**
* Batch delete multiple resources.
*/
public function batchDestroy(Request $request): JsonResponse
{
$validator = Validator::make($request->all(), [
'ids' => 'required|array',
'ids.*' => 'required|integer|exists:site_translations,id',
]);
if ($validator->fails()) {
return response()->json([
'success' => false,
'errors' => $validator->errors(),
], 422);
}
$ids = $request->get('ids', []);
$translations = SiteTranslation::whereIn('id', $ids)->get();
foreach ($translations as $translation) {
Cache::forget("site_translation_{$translation->hash}");
}
SiteTranslation::whereIn('id', $ids)->delete();
return response()->json([
'success' => true,
'message' => count($ids) . ' kayıt başarıyla silindi.',
]);
}
}