Implement category tree via AJAX to avoid 500 errors on page load

This commit is contained in:
Edwin Noorlander 2025-11-12 08:47:52 +01:00
parent 953f831ab9
commit deb27490c2
5 changed files with 78 additions and 1 deletions

View File

@ -19,7 +19,6 @@ $loader = new \Twig\Loader\FilesystemLoader(__DIR__ . '/templates');
$twig = new \Twig\Environment($loader, [ $twig = new \Twig\Environment($loader, [
// 'cache' => __DIR__ . '/cache/twig', // Uncomment for production // 'cache' => __DIR__ . '/cache/twig', // Uncomment for production
'debug' => true, 'debug' => true,
'max_recursion' => 100,
]); ]);
// --- Translation Setup --- // --- Translation Setup ---

View File

@ -44,6 +44,59 @@ $router->addRoute('GET', '/api/categories', [CategoryController::class, 'listCat
$router->addRoute('GET', '/api/categories/list', [CategoryController::class, 'listCategoriesJson']); $router->addRoute('GET', '/api/categories/list', [CategoryController::class, 'listCategoriesJson']);
$router->addRoute('GET', '/api/categories/{id}', [CategoryController::class, 'getCategory']); $router->addRoute('GET', '/api/categories/{id}', [CategoryController::class, 'getCategory']);
$router->addRoute('GET', '/api/parts', [ItemController::class, 'renderAddForm']); $router->addRoute('GET', '/api/parts', [ItemController::class, 'renderAddForm']);
$router->addRoute('GET', '/api/tree', function() {
try {
$db = App\Database\Database::getInstance();
$categories = App\Models\Category::getAll($db);
function build_category_tree($categories, $parentId = null, &$visited = [], $depth = 0, &$nodeCount = 0) {
if ($depth > 5 || $nodeCount > 100) return [];
$tree = [];
foreach ($categories as $cat) {
if ($cat['parent_id'] == $parentId && !in_array($cat['id'], $visited)) {
$visited[] = $cat['id'];
$node = [
'id' => $cat['id'],
'name' => $cat['name'],
'children' => build_category_tree($categories, $cat['id'], $visited, $depth + 1, $nodeCount)
];
$tree[] = $node;
$nodeCount++;
if ($nodeCount > 100) break;
}
}
return $tree;
}
function render_category_tree($nodes, $depth = 0) {
if ($depth > 5) return '';
$html = '';
foreach ($nodes as $node) {
$html .= '<li>';
$html .= '<span class="category" onclick="toggleCategory(this)">' . htmlspecialchars($node['name']) . '</span>';
if (!empty($node['children'])) {
$html .= '<ul style="display: none;">';
$html .= render_category_tree($node['children'], $depth + 1);
$html .= '</ul>';
}
$html .= '</li>';
}
return $html;
}
$nodeCount = 0;
$categoryTree = build_category_tree($categories, null, $visited = [], 0, $nodeCount);
$html = '<ul class="category-tree">' . render_category_tree($categoryTree) . '</ul>';
if (strlen($html) > 10000) {
$html = '<ul class="nav flex-column nav-pills"><li class="nav-item"><a class="nav-link" href="#" data-route="/">Overview</a></li><li class="nav-item"><a class="nav-link" href="#" data-route="/categories">Categories</a></li><li class="nav-item"><a class="nav-link" href="#" data-route="/parts">Parts</a></li></ul>';
}
header('Content-Type: text/html');
echo $html;
} catch (Exception $e) {
header('Content-Type: text/html');
echo '<ul class="nav flex-column nav-pills"><li class="nav-item"><a class="nav-link" href="#" data-route="/">Overview</a></li><li class="nav-item"><a class="nav-link" href="#" data-route="/categories">Categories</a></li><li class="nav-item"><a class="nav-link" href="#" data-route="/parts">Parts</a></li></ul>';
}
});
// --- API CRUD Routes --- // --- API CRUD Routes ---
// Items // Items

View File

@ -115,6 +115,16 @@ document.addEventListener('DOMContentLoaded', function() {
const initialPath = window.location.pathname === '/' ? '/items' : window.location.pathname; const initialPath = window.location.pathname === '/' ? '/items' : window.location.pathname;
fetchContent(initialPath, false); fetchContent(initialPath, false);
// Load category tree
fetch('/api/tree')
.then(response => response.text())
.then(html => {
document.querySelector('.sidebar').innerHTML = html;
})
.catch(error => {
console.error('Error loading tree:', error);
});
// Page-specific scripts (e.g., form submissions) // Page-specific scripts (e.g., form submissions)
function initPageSpecificScripts() { function initPageSpecificScripts() {
// Overview page: filter form // Overview page: filter form

15
test_db.php Normal file
View File

@ -0,0 +1,15 @@
<?php
require 'vendor/autoload.php';
require 'config.php';
$db = App\Database\Database::getInstance();
try {
$stmt = $db->query('SELECT COUNT(*) FROM categories');
$count = $stmt->fetchColumn();
echo "Categories: $count\n";
$stmt = $db->query('SELECT COUNT(*) FROM items');
$count = $stmt->fetchColumn();
echo "Items: $count\n";
} catch (Exception $e) {
echo "Error: " . $e->getMessage() . "\n";
}
?>