From abdfe190a7e41e24d968e33ad9b8e4d675319bb8 Mon Sep 17 00:00:00 2001 From: "m.razaghi" Date: Sun, 12 Jul 2026 18:34:10 +0330 Subject: [PATCH] Fixed api issue --- .../Controllers/api/BylawApiController.php | 107 +++++++++++++----- 1 file changed, 78 insertions(+), 29 deletions(-) diff --git a/app/Http/Controllers/api/BylawApiController.php b/app/Http/Controllers/api/BylawApiController.php index 4b7c8a3..a52c5df 100644 --- a/app/Http/Controllers/api/BylawApiController.php +++ b/app/Http/Controllers/api/BylawApiController.php @@ -10,7 +10,6 @@ use App\Models\BylawNode; use App\Models\BylawCodificationLink; use App\Traits\BaseApiResponse; use Illuminate\Http\Request; -use Illuminate\Support\Facades\DB; class BylawApiController extends Controller { @@ -80,8 +79,20 @@ class BylawApiController extends Controller $perPage = min(max((int) $request->input('per_page', 15), 10), 100); $paginator = $query->paginate($perPage); - $items = collect($paginator->items())->map(function ($item) { - return $this->formatBylaw($item); + // واکشی دسته‌جمعی و ایمنِ گره‌ها با استفاده از Eloquent + $docIds = collect($paginator->items())->pluck('id')->map(fn($id) => (int)$id)->toArray(); + $nodesByDoc = collect(); + + if (!empty($docIds)) { + $nodesByDoc = BylawNode::whereIn('document_id', $docIds) + ->orderBy('sort_order', 'asc') + ->get() + ->groupBy(fn($node) => (int)$node->document_id); + } + + $items = collect($paginator->items())->map(function ($item) use ($nodesByDoc) { + $itemNodes = $nodesByDoc->get((int)$item->id, collect()); + return $this->formatBylaw($item, $itemNodes); }); $responseData = [ @@ -193,8 +204,19 @@ class BylawApiController extends Controller $perPage = min(max((int) $request->input('per_page', 15), 10), 100); $paginator = $query->paginate($perPage); - $items = collect($paginator->items())->map(function ($item) { - return $this->formatBylaw($item); + $docIds = collect($paginator->items())->pluck('id')->map(fn($id) => (int)$id)->toArray(); + $nodesByDoc = collect(); + + if (!empty($docIds)) { + $nodesByDoc = BylawNode::whereIn('document_id', $docIds) + ->orderBy('sort_order', 'asc') + ->get() + ->groupBy(fn($node) => (int)$node->document_id); + } + + $items = collect($paginator->items())->map(function ($item) use ($nodesByDoc) { + $itemNodes = $nodesByDoc->get((int)$item->id, collect()); + return $this->formatBylaw($item, $itemNodes); }); $responseData = [ @@ -233,8 +255,19 @@ class BylawApiController extends Controller $count = $query->count(); $items = $query->orderBy('approval_date', 'desc')->take(5)->get(); - $formattedItems = $items->map(function ($item) { - return $this->formatBylaw($item); + $docIds = $items->pluck('id')->map(fn($id) => (int)$id)->toArray(); + $nodesByDoc = collect(); + + if (!empty($docIds)) { + $nodesByDoc = BylawNode::whereIn('document_id', $docIds) + ->orderBy('sort_order', 'asc') + ->get() + ->groupBy(fn($node) => (int)$node->document_id); + } + + $formattedItems = $items->map(function ($item) use ($nodesByDoc) { + $itemNodes = $nodesByDoc->get((int)$item->id, collect()); + return $this->formatBylaw($item, $itemNodes); }); return $this->success([ @@ -295,9 +328,20 @@ class BylawApiController extends Controller $itemsToFormat = array_filter([$previousItem, $current, $nextItem]); - $results = array_values(array_map(function($item) { - return $this->formatBylaw($item); - }, $itemsToFormat)); + $docIds = collect($itemsToFormat)->pluck('id')->map(fn($id) => (int)$id)->toArray(); + $nodesByDoc = collect(); + + if (!empty($docIds)) { + $nodesByDoc = BylawNode::whereIn('document_id', $docIds) + ->orderBy('sort_order', 'asc') + ->get() + ->groupBy(fn($node) => (int)$node->document_id); + } + + $results = collect($itemsToFormat)->map(function($item) use ($nodesByDoc) { + $itemNodes = $nodesByDoc->get((int)$item->id, collect()); + return $this->formatBylaw($item, $itemNodes); + })->values()->toArray(); return $this->success($results, 'Success', 'Pager Window Details'); } @@ -311,30 +355,32 @@ class BylawApiController extends Controller } /** - * اجرای مستقیم SQL برای دور زدن باگ‌های فیلتر و مدل در لاراول + * متد قدرتمند برای استخراج ایمن متون */ - private function formatBylaw($item) + private function formatBylaw($item, $itemNodes = null) { $isLocked = $this->isLockedForCurrentUser($item); - // واکشی خام با دستور استاندارد SQL (کاملاً تضمینی) - $rawNodes = DB::select("SELECT node_content FROM bylaw_nodes WHERE document_id = ? ORDER BY sort_order ASC", [$item->id]); - - $extractedTexts = []; - foreach ($rawNodes as $node) { - // حذف فضاهای خالی اضافی بدون حذف محتوای اصلی - $text = trim($node->node_content); - if ($text !== '' && $text !== null) { - $extractedTexts[] = $text; - } + // واکشی در صورت خالی بودن کالکشن + if ($itemNodes === null) { + $itemNodes = BylawNode::where('document_id', $item->id)->orderBy('sort_order', 'asc')->get(); } - // چسباندن تمام تکه متن‌ها به یکدیگر - $finalNodeContent = implode("\n\n", $extractedTexts); + // استخراج محتوا و تبدیل امنِ Encoding (ضد باگِ JSON Encode لاراول) + $nodeContentAsDescription = $itemNodes->pluck('node_content') + ->map(function ($text) { + // اطمینان از حذف فاصله‌ها و اعمال انکودینگ استاندارد برای جلوگیری از باگ‌های نامرئی + $safeText = trim((string)$text); + return mb_convert_encoding($safeText, 'UTF-8', 'UTF-8'); + }) + ->filter(function ($text) { + return $text !== ''; + }) + ->implode("\n\n"); - // بک‌آپ نهایی (اگر به طرز عجیبی واقعاً دیتابیس برای این آیدی هیچ پاسخی نداد) - if (empty($finalNodeContent)) { - $finalNodeContent = $item->description; + // اگر همچنان خالی ماند (فقط در صورتی که دیتابیس واقعاً رکورد نداشته باشد) + if (empty($nodeContentAsDescription)) { + $nodeContentAsDescription = mb_convert_encoding(trim((string)$item->description), 'UTF-8', 'UTF-8'); } return [ @@ -356,8 +402,11 @@ class BylawApiController extends Controller 'global_status' => $item->global_status, 'pdf_file_url' => $isLocked ? null : ($item->pdf_file_path ? asset('storage/' . $item->pdf_file_path) : null), - // نتیجه استخراج مستقیم SQL در این متغیر قرار گرفته است: - 'description' => $isLocked ? null : $finalNodeContent, + // نتیجه استخراج ۱۰۰٪ در اینجا می‌نشیند + 'description' => $isLocked ? null : $nodeContentAsDescription, + + // 🚨 پارامتر عیب‌یابی: این عدد نشان می‌دهد چند گره متصل به این فایل در دیتابیس پیدا شد + 'debug_node_count' => $itemNodes->count(), 'is_locked' => $isLocked, ];