Fixed api issue

This commit is contained in:
m.razaghi
2026-07-12 18:16:02 +03:30
parent 56e57719eb
commit 7ca903ec3c

View File

@@ -80,22 +80,30 @@ class BylawApiController extends Controller
$perPage = min(max((int) $request->input('per_page', 15), 10), 100); $perPage = min(max((int) $request->input('per_page', 15), 10), 100);
$paginator = $query->paginate($perPage); $paginator = $query->paginate($perPage);
// واکشی بهینه گره‌ها از دیتابیس // واکشی ۱۰۰٪ قطعی گره‌ها با آرایه‌های بومی (Native PHP Arrays)
$documentIds = collect($paginator->items())->pluck('id')->toArray(); $documentIds = collect($paginator->items())->pluck('id')->toArray();
$allNodes = collect(); $nodesDictionary = [];
if (!empty($documentIds)) { if (!empty($documentIds)) {
$allNodes = DB::table('bylaw_nodes') $nodes = DB::table('bylaw_nodes')
->whereIn('document_id', $documentIds) ->whereIn('document_id', $documentIds)
->orderBy('sort_order', 'asc') ->orderBy('sort_order', 'asc')
->select('document_id', 'node_content')
->get(); ->get();
foreach ($nodes as $node) {
$docId = $node->document_id;
if (!isset($nodesDictionary[$docId])) {
$nodesDictionary[$docId] = [];
}
if (!empty(trim((string)$node->node_content))) {
$nodesDictionary[$docId][] = trim((string)$node->node_content);
}
}
} }
$items = collect($paginator->items())->map(function ($item) use ($allNodes) { $items = collect($paginator->items())->map(function ($item) use ($nodesDictionary) {
// حل مشکل فیلتر سخت‌گیرانه (Strict) در کالکشن‌ها return $this->formatBylaw($item, $nodesDictionary[$item->id] ?? null);
$itemNodes = $allNodes->filter(function($node) use ($item) {
return $node->document_id == $item->id;
});
return $this->formatBylaw($item, $itemNodes);
}); });
$responseData = [ $responseData = [
@@ -122,13 +130,7 @@ class BylawApiController extends Controller
], 404); ], 404);
} }
// واکشی خام گره‌ها برای توضیحات کلی $formatted = $this->formatBylaw($bylaw);
$rawNodes = DB::table('bylaw_nodes')
->where('document_id', $bylaw->id)
->orderBy('sort_order', 'asc')
->get();
$formatted = $this->formatBylaw($bylaw, $rawNodes);
if (!$formatted['is_locked']) { if (!$formatted['is_locked']) {
$eloquentNodes = BylawNode::with('type') $eloquentNodes = BylawNode::with('type')
@@ -214,19 +216,28 @@ class BylawApiController extends Controller
$paginator = $query->paginate($perPage); $paginator = $query->paginate($perPage);
$documentIds = collect($paginator->items())->pluck('id')->toArray(); $documentIds = collect($paginator->items())->pluck('id')->toArray();
$allNodes = collect(); $nodesDictionary = [];
if (!empty($documentIds)) { if (!empty($documentIds)) {
$allNodes = DB::table('bylaw_nodes') $nodes = DB::table('bylaw_nodes')
->whereIn('document_id', $documentIds) ->whereIn('document_id', $documentIds)
->orderBy('sort_order', 'asc') ->orderBy('sort_order', 'asc')
->select('document_id', 'node_content')
->get(); ->get();
foreach ($nodes as $node) {
$docId = $node->document_id;
if (!isset($nodesDictionary[$docId])) {
$nodesDictionary[$docId] = [];
}
if (!empty(trim((string)$node->node_content))) {
$nodesDictionary[$docId][] = trim((string)$node->node_content);
}
}
} }
$items = collect($paginator->items())->map(function ($item) use ($allNodes) { $items = collect($paginator->items())->map(function ($item) use ($nodesDictionary) {
$itemNodes = $allNodes->filter(function($node) use ($item) { return $this->formatBylaw($item, $nodesDictionary[$item->id] ?? null);
return $node->document_id == $item->id;
});
return $this->formatBylaw($item, $itemNodes);
}); });
$responseData = [ $responseData = [
@@ -266,19 +277,28 @@ class BylawApiController extends Controller
$items = $query->orderBy('approval_date', 'desc')->take(5)->get(); $items = $query->orderBy('approval_date', 'desc')->take(5)->get();
$documentIds = $items->pluck('id')->toArray(); $documentIds = $items->pluck('id')->toArray();
$allNodes = collect(); $nodesDictionary = [];
if (!empty($documentIds)) { if (!empty($documentIds)) {
$allNodes = DB::table('bylaw_nodes') $nodes = DB::table('bylaw_nodes')
->whereIn('document_id', $documentIds) ->whereIn('document_id', $documentIds)
->orderBy('sort_order', 'asc') ->orderBy('sort_order', 'asc')
->select('document_id', 'node_content')
->get(); ->get();
foreach ($nodes as $node) {
$docId = $node->document_id;
if (!isset($nodesDictionary[$docId])) {
$nodesDictionary[$docId] = [];
}
if (!empty(trim((string)$node->node_content))) {
$nodesDictionary[$docId][] = trim((string)$node->node_content);
}
}
} }
$formattedItems = $items->map(function ($item) use ($allNodes) { $formattedItems = $items->map(function ($item) use ($nodesDictionary) {
$itemNodes = $allNodes->filter(function($node) use ($item) { return $this->formatBylaw($item, $nodesDictionary[$item->id] ?? null);
return $node->document_id == $item->id;
});
return $this->formatBylaw($item, $itemNodes);
}); });
return $this->success([ return $this->success([
@@ -340,19 +360,28 @@ class BylawApiController extends Controller
$itemsToFormat = array_filter([$previousItem, $current, $nextItem]); $itemsToFormat = array_filter([$previousItem, $current, $nextItem]);
$documentIds = collect($itemsToFormat)->pluck('id')->toArray(); $documentIds = collect($itemsToFormat)->pluck('id')->toArray();
$allNodes = collect(); $nodesDictionary = [];
if (!empty($documentIds)) { if (!empty($documentIds)) {
$allNodes = DB::table('bylaw_nodes') $nodes = DB::table('bylaw_nodes')
->whereIn('document_id', $documentIds) ->whereIn('document_id', $documentIds)
->orderBy('sort_order', 'asc') ->orderBy('sort_order', 'asc')
->select('document_id', 'node_content')
->get(); ->get();
foreach ($nodes as $node) {
$docId = $node->document_id;
if (!isset($nodesDictionary[$docId])) {
$nodesDictionary[$docId] = [];
}
if (!empty(trim((string)$node->node_content))) {
$nodesDictionary[$docId][] = trim((string)$node->node_content);
}
}
} }
$results = array_values(array_map(function($item) use ($allNodes) { $results = array_values(array_map(function($item) use ($nodesDictionary) {
$itemNodes = $allNodes->filter(function($node) use ($item) { return $this->formatBylaw($item, $nodesDictionary[$item->id] ?? null);
return $node->document_id == $item->id;
});
return $this->formatBylaw($item, $itemNodes);
}, $itemsToFormat)); }, $itemsToFormat));
return $this->success($results, 'Success', 'Pager Window Details'); return $this->success($results, 'Success', 'Pager Window Details');
@@ -364,38 +393,38 @@ class BylawApiController extends Controller
} }
/** /**
* BULLETPROOF DESCRIPTION GENERATOR * سیستم کاملاً ضد گلوله برای استخراج Description
*/ */
private function formatBylaw($item, $itemNodes = null) private function formatBylaw($item, $preloadedNodes = null)
{ {
$isLocked = $this->isLockedForCurrentUser($item); $isLocked = $this->isLockedForCurrentUser($item);
// ۱. اولویت اول: متنی که ادمین در پنل وارد کرده است
$description = $item->description; $description = $item->description;
$cleanDesc = trim(str_replace([' ', '‌', "\r", "\n", "\t", ' '], '', strip_tags($description ?? ''))); // ۲. اولویت دوم: اگر توضیحات ادمین خالی بود، متن قانون را از گره‌ها می‌گیریم
if (empty(trim((string)$description))) {
// اگر فیلد اصلی description خالی بود (که در خزش فعلی خالی است)، به سراغ متن اصلی می‌رویم // اگر آرایه گره‌ها از قبل (در توابع index یا search) آماده شده بود:
if (strlen($cleanDesc) < 5) { if ($preloadedNodes !== null && is_array($preloadedNodes)) {
$description = implode("\n\n", $preloadedNodes);
// شبکه اطمینان: اگر متغیر حاوی گره‌ها به هر دلیلی خالی بود، مستقیماً از دیتابیس می‌گیریم // در غیر این صورت (مثلا در تابع single) مستقیماً از دیتابیس می‌گیریم
if ($itemNodes === null || (is_countable($itemNodes) && count($itemNodes) === 0)) { } else {
$itemNodes = DB::table('bylaw_nodes') $nodes = DB::table('bylaw_nodes')
->where('document_id', $item->id) ->where('document_id', $item->id)
->orderBy('sort_order', 'asc') ->orderBy('sort_order', 'asc')
->get(); ->pluck('node_content')
} ->toArray();
$nodeContents = []; $validContents = [];
foreach ($itemNodes as $node) { foreach ($nodes as $content) {
// استخراج امن متن از آبجکت یا آرایه (برای جلوگیری از خطاهای احتمالی) if (!empty(trim((string)$content))) {
$contentRaw = is_array($node) ? ($node['node_content'] ?? '') : ($node->node_content ?? ''); $validContents[] = trim((string)$content);
}
$content = trim(strip_tags($contentRaw));
if (!empty($content)) {
$nodeContents[] = $content;
} }
$description = implode("\n\n", $validContents);
} }
$description = implode("\n\n", $nodeContents);
} }
return [ return [
@@ -416,7 +445,7 @@ class BylawApiController extends Controller
'bylaw_type' => $item->bylaw_type, 'bylaw_type' => $item->bylaw_type,
'global_status' => $item->global_status, 'global_status' => $item->global_status,
'pdf_file_url' => $isLocked ? null : ($item->pdf_file_path ? asset('storage/' . $item->pdf_file_path) : null), 'pdf_file_url' => $isLocked ? null : ($item->pdf_file_path ? asset('storage/' . $item->pdf_file_path) : null),
'description' => $isLocked ? null : $description, // متن کامل از node_content اینجا قرار می‌گیرد 'description' => $isLocked ? null : $description,
'is_locked' => $isLocked, 'is_locked' => $isLocked,
]; ];
} }