From 375e3b166c8bbe412e7d80596b725c39e8848002 Mon Sep 17 00:00:00 2001 From: "m.razaghi" Date: Sun, 12 Jul 2026 17:42:34 +0330 Subject: [PATCH] Fixed api issue --- .../Controllers/api/BylawApiController.php | 92 ++++++++++--------- 1 file changed, 51 insertions(+), 41 deletions(-) diff --git a/app/Http/Controllers/api/BylawApiController.php b/app/Http/Controllers/api/BylawApiController.php index 55082d1..6573926 100644 --- a/app/Http/Controllers/api/BylawApiController.php +++ b/app/Http/Controllers/api/BylawApiController.php @@ -10,6 +10,7 @@ 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 { @@ -79,9 +80,13 @@ class BylawApiController extends Controller $perPage = min(max((int) $request->input('per_page', 15), 10), 100); $paginator = $query->paginate($perPage); - // Pre-fetch ALL nodes for the current page in ONE query + // Pre-fetch ALL nodes directly via DB facade for speed and reliability $documentIds = collect($paginator->items())->pluck('id'); - $allNodes = BylawNode::whereIn('document_id', $documentIds)->orderBy('sort_order', 'asc')->get()->groupBy('document_id'); + $allNodes = DB::table('bylaw_nodes') + ->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())); @@ -111,15 +116,17 @@ class BylawApiController extends Controller ], 404); } - $nodes = BylawNode::with('type') - ->where('document_id', $bylaw->id) - ->orderBy('sort_order', 'asc') - ->get(); - - $formatted = $this->formatBylaw($bylaw, $nodes); + // Fetch nodes using DB facade for the format function, but Eloquent for the nodes array + $rawNodes = DB::table('bylaw_nodes')->where('document_id', $bylaw->id)->orderBy('sort_order', 'asc')->get(); + $formatted = $this->formatBylaw($bylaw, $rawNodes); if (!$formatted['is_locked']) { - $formatted['nodes'] = $nodes->map(function ($node) { + $eloquentNodes = BylawNode::with('type') + ->where('document_id', $bylaw->id) + ->orderBy('sort_order', 'asc') + ->get(); + + $formatted['nodes'] = $eloquentNodes->map(function ($node) { return [ 'id' => $node->id, 'parent_id' => $node->parent_id, @@ -196,9 +203,12 @@ class BylawApiController extends Controller $perPage = min(max((int) $request->input('per_page', 15), 10), 100); $paginator = $query->paginate($perPage); - // 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'); + $allNodes = DB::table('bylaw_nodes') + ->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())); @@ -240,9 +250,12 @@ class BylawApiController extends Controller $count = $query->count(); $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'); + $allNodes = DB::table('bylaw_nodes') + ->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())); @@ -306,9 +319,12 @@ class BylawApiController extends Controller $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'); + $allNodes = DB::table('bylaw_nodes') + ->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())); @@ -322,39 +338,33 @@ class BylawApiController extends Controller return ! auth()->user()->isSubscriber() && (bool) ($item->is_locked ?? false); } + /** + * BULLETPROOF DESCRIPTION GENERATOR + */ private function formatBylaw($item, $preloadedNodes = null) { $isLocked = $this->isLockedForCurrentUser($item); - $description = $item->description; - // AGGRESSIVE HTML CLEANER: Destroys hidden HTML tags,  , and whitespaces - $cleanDesc = trim(preg_replace('/\s+/', '', html_entity_decode(strip_tags($description ?? '')))); + // 1. We ALWAYS try to build the description from the `node_content` FIRST. + $nodes = $preloadedNodes !== null + ? $preloadedNodes + : DB::table('bylaw_nodes')->where('document_id', $item->id)->orderBy('sort_order', 'asc')->get(); - // If the description is genuinely empty, pull from the nodes! - if ($cleanDesc === '' || strtolower($cleanDesc) === 'null') { - - $nodes = $preloadedNodes !== null - ? $preloadedNodes - : BylawNode::where('document_id', $item->id)->orderBy('sort_order', 'asc')->get(); - - $descParts = []; - foreach ($nodes as $node) { - // Grab all possible text fields - $identifier = trim(strip_tags($node->node_identifier ?? '')); - $title = trim(strip_tags($node->title ?? '')); - $content = trim(strip_tags($node->node_content ?? '')); - - // Combine them neatly (e.g. "Article 1 - Definitions - This is the text...") - $combined = array_filter([$identifier, $title, $content], function($val) { - return $val !== ''; - }); - - if (!empty($combined)) { - $descParts[] = implode(" : ", $combined); - } + $nodeContents = []; + foreach ($nodes as $node) { + // We specifically ask for the node_content column here + $content = trim(strip_tags($node->node_content ?? '')); + if (!empty($content)) { + $nodeContents[] = $content; } + } - $description = implode("\n\n", $descParts); + // Stitch them all together + $description = implode("\n\n", $nodeContents); + + // 2. If node_content is COMPLETELY EMPTY across all nodes, ONLY THEN do we fallback to the old description + if (empty(trim(strip_tags($description)))) { + $description = $item->description; } return [