From 677e101181258ded44100563a61168485724ca6a Mon Sep 17 00:00:00 2001 From: "m.razaghi" Date: Sun, 12 Jul 2026 17:33:31 +0330 Subject: [PATCH] Fixed api issue --- .../Controllers/api/BylawApiController.php | 123 ++++++++++-------- 1 file changed, 68 insertions(+), 55 deletions(-) diff --git a/app/Http/Controllers/api/BylawApiController.php b/app/Http/Controllers/api/BylawApiController.php index 64f8bfb..66791f5 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,12 @@ 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); + // Pre-fetch ALL nodes for the current page in ONE query (Prevents Database crashing/emptying) + $documentIds = collect($paginator->items())->pluck('id'); + $allNodes = BylawNode::whereIn('document_id', $documentIds)->orderBy('sort_order', 'asc')->get()->groupBy('document_id'); + + $items = collect($paginator->items())->map(function ($item) use ($allNodes) { + return $this->formatBylaw($item, $allNodes->get($item->id, collect())); }); $responseData = [ @@ -108,29 +111,29 @@ class BylawApiController extends Controller ], 404); } - $formatted = $this->formatBylaw($bylaw); + // Fetch nodes safely + $nodes = BylawNode::with('type') + ->where('document_id', $bylaw->id) + ->orderBy('sort_order', 'asc') + ->get(); + + $formatted = $this->formatBylaw($bylaw, $nodes); if (!$formatted['is_locked']) { - $nodes = BylawNode::with('type') - ->where('document_id', $bylaw->id) - ->orderBy('sort_order', 'asc') - ->get() - ->map(function ($node) { - return [ - 'id' => $node->id, - 'parent_id' => $node->parent_id, - 'node_type' => optional($node->type)->name, - 'node_identifier' => $node->node_identifier, - 'title' => $node->title, - 'node_content' => $node->node_content, - 'sort_order' => $node->sort_order, - 'valid_from' => $node->valid_from, - 'valid_to' => $node->valid_to, - 'node_status' => $node->node_status, - ]; - }); - - $formatted['nodes'] = $nodes->toArray(); + $formatted['nodes'] = $nodes->map(function ($node) { + return [ + 'id' => $node->id, + 'parent_id' => $node->parent_id, + 'node_type' => optional($node->type)->name, + 'node_identifier' => $node->node_identifier, + 'title' => $node->title, + 'node_content' => $node->node_content, + 'sort_order' => $node->sort_order, + 'valid_from' => $node->valid_from, + 'valid_to' => $node->valid_to, + 'node_status' => $node->node_status, + ]; + })->toArray(); $links = BylawCodificationLink::where('source_entity_type', 'bylaw_doc') ->where('source_entity_id', $bylaw->id) @@ -194,8 +197,12 @@ 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); + // Pre-fetch ALL nodes for the current page in ONE query + $documentIds = collect($paginator->items())->pluck('id'); + $allNodes = BylawNode::whereIn('document_id', $documentIds)->orderBy('sort_order', 'asc')->get()->groupBy('document_id'); + + $items = collect($paginator->items())->map(function ($item) use ($allNodes) { + return $this->formatBylaw($item, $allNodes->get($item->id, collect())); }); $responseData = [ @@ -232,12 +239,18 @@ class BylawApiController extends Controller } $count = $query->count(); - $items = $query->orderBy('approval_date', 'desc')->take(5)->get()->map(function ($item) { - return $this->formatBylaw($item); + $items = $query->orderBy('approval_date', 'desc')->take(5)->get(); + + // Pre-fetch ALL nodes for the current page in ONE query + $documentIds = $items->pluck('id'); + $allNodes = BylawNode::whereIn('document_id', $documentIds)->orderBy('sort_order', 'asc')->get()->groupBy('document_id'); + + $formattedItems = $items->map(function ($item) use ($allNodes) { + return $this->formatBylaw($item, $allNodes->get($item->id, collect())); }); return $this->success([ - 'items' => $items, + 'items' => $formattedItems, 'count' => $count ], 'Success', 'Fast Search Results'); } @@ -292,11 +305,15 @@ class BylawApiController extends Controller ->orderBy('id', 'asc') ->first(); - $results = array_values(array_filter([ - $previousItem ? $this->formatBylaw($previousItem) : null, - $this->formatBylaw($current), - $nextItem ? $this->formatBylaw($nextItem) : null - ])); + $itemsToFormat = array_filter([$previousItem, $current, $nextItem]); + + // Pre-fetch ALL nodes + $documentIds = collect($itemsToFormat)->pluck('id'); + $allNodes = BylawNode::whereIn('document_id', $documentIds)->orderBy('sort_order', 'asc')->get()->groupBy('document_id'); + + $results = array_values(array_map(function($item) use ($allNodes) { + return $this->formatBylaw($item, $allNodes->get($item->id, collect())); + }, $itemsToFormat)); return $this->success($results, 'Success', 'Pager Window Details'); } @@ -306,36 +323,32 @@ class BylawApiController extends Controller return ! auth()->user()->isSubscriber() && (bool) ($item->is_locked ?? false); } - private function formatBylaw($item) + /** + * 100% Bulletproof formatting with aggressive HTML empty-checking + */ + private function formatBylaw($item, $preloadedNodes = null) { $isLocked = $this->isLockedForCurrentUser($item); $description = $item->description; - // HARDCORE EMPTY CHECK: Destroy all tags, non-breaking spaces, and newlines. - $cleanDesc = trim(str_replace([' ', '‌', "\r", "\n", "\t", ' '], '', strip_tags($description ?? ''))); + // AGGRESSIVE HTML CLEANER: Destroys hidden HTML tags,  , and whitespaces + $cleanDesc = trim(preg_replace('/\s+/', '', html_entity_decode(strip_tags($description ?? '')))); - // If the description is genuinely empty, pull from the nodes table! - if (empty($cleanDesc)) { - $nodes = DB::table('bylaw_nodes') - ->where('document_id', $item->id) - ->orderBy('sort_order', 'asc') - ->get(['title', 'node_content']); // Fetch BOTH title and node_content + // If the description is genuinely empty, pull from the nodes! + if ($cleanDesc === '') { - $descParts = []; - foreach ($nodes as $node) { - $nodeTitle = trim($node->title ?? ''); - $nodeContent = trim($node->node_content ?? ''); + // Uses nodes passed from the parent query, OR natively queries them if missing + $nodes = $preloadedNodes !== null ? $preloadedNodes : BylawNode::where('document_id', $item->id)->orderBy('sort_order', 'asc')->get(); - if (!empty($nodeTitle)) { - $descParts[] = $nodeTitle; - } - if (!empty($nodeContent)) { - $descParts[] = $nodeContent; - } + if ($nodes && $nodes->count() > 0) { + // Extracts node_content, drops any that are pure empty space, and joins them + $description = $nodes->pluck('node_content')->filter(function ($content) { + return trim(preg_replace('/\s+/', '', html_entity_decode(strip_tags($content ?? '')))) !== ''; + })->implode("\n\n"); + } else { + $description = null; } - - $description = implode("\n\n", $descParts); } return [