Dokumenteninfo wird jetzt in DB geschrieben.

This commit is contained in:
Thomas Spohr
2025-07-31 12:22:10 +02:00
parent 9c9d422380
commit 266fd69afb
23 changed files with 278 additions and 115 deletions

BIN
mod_pdf_tree/.DS_Store vendored

Binary file not shown.

Binary file not shown.

View File

@@ -1,75 +1,66 @@
<?php
// Direktzugriff verhindern
defined('_JEXEC') or die;
// Hilfsklasse zur URI-Verarbeitung einbinden
use Joomla\CMS\Uri\Uri;
use Joomla\CMS\Factory;
use Joomla\Database\DatabaseDriver;
/**
* Modul-Hilfsklasse: Baumstruktur aus JSON-Datei aufbereiten
*/
class ModEisAnzeigeHelper
{
/**
* JSON-Datei einlesen und als Array zurückgeben
* @param string $jsonPath Pfad relativ zum Joomla-Root
* @return array Strukturierte Baumdaten oder leeres Array
* Holt alle PDF-Elemente aus der Datenbank
*/
public static function getItems(string $jsonPath): array
public static function getItems(): array
{
$file = JPATH_ROOT . DIRECTORY_SEPARATOR . ltrim($jsonPath, '/');
if (!file_exists($file)) {
return [];
/** @var DatabaseDriver $db */
$db = Factory::getDbo();
$query = $db->getQuery(true)
->select('*')
->from($db->quoteName('#__eis_documents'))
->order($db->quoteName('ordering') . ' ASC');
$rows = $db->setQuery($query)->loadAssocList();
// Nach parent_id gruppieren
$grouped = [];
foreach ($rows as $row) {
$pid = $row['parent_id'] === null ? null : (int) $row['parent_id'];
$grouped[$pid][] = $row;
}
$json = file_get_contents($file);
$data = json_decode($json, true);
if (json_last_error() !== JSON_ERROR_NONE || !is_array($data)) {
return [];
}
return $data;
return $grouped;
}
/**
* Baumstruktur als HTML generieren (rekursiv)
* @param array $items Eingelesene JSON-Daten
* @return string HTML-Ausgabe
* Hauptfunktion zum Rendern des Baums
*/
public static function renderTree(array $items): string
public static function renderTree(array $items, int $parentId = null): string
{
if (!isset($items[$parentId])) {
return '';
}
$html = '<ul class="pdf-tree">';
foreach ($items as $node) {
$name = htmlspecialchars($node['name'], ENT_QUOTES, 'UTF-8');
foreach ($items[$parentId] as $item) {
$isFolder = (bool) $item['is_folder'];
$title = htmlspecialchars($item['title'] ?: $item['name']);
// $path = htmlspecialchars($item['path'] ?? '');
$path = htmlspecialchars(self::convertToRelativeUrl($item['path'] ?? ''));
// Ordner: hat Kinder
if (isset($node['children']) && is_array($node['children'])) {
$count = self::countFiles($node['children']);
$html .= '<li class="folder">'
. '<span class="toggle">▶</span>'
. '<span class="folder-icon"></span>'
. '<span class="folder-name">'
. $name . ' (' . $count . ')'
. '</span>';
// Rekursiver Aufruf
$html .= self::renderTree($node['children']);
if ($isFolder) {
$fileCount = self::countFilesRecursive($items, $item['id']);
$html .= '<li class="folder">';
$html .= '<span class="toggle">▶</span>';
$html .= '<span class="folder-icon"></span>' . $title . ' <small>(' . $fileCount . ')</small>';
$html .= self::renderTree($items, $item['id']);
$html .= '</li>';
} else {
// Datei
$path = $node['path'] ?? '';
$relative = str_replace(JPATH_ROOT, '', $path);
$url = Uri::root(true) . '/' . ltrim(str_replace(DIRECTORY_SEPARATOR, '/', $relative), '/');
$html .= '<li class="file">'
. '<span class="file-icon"></span>'
. '<a href="' . $url . '" class="file-link" download>'
. $name . '</a>'
. '</li>';
$html .= '<li class="file">';
$html .= '<span class="file-icon"></span><a class="file-link" href="' . $path . '">' . $title . '</a>';
$html .= '</li>';
}
}
@@ -77,18 +68,36 @@ class ModEisAnzeigeHelper
return $html;
}
/**
* Dateien im aktuellen Knotenbaum zählen
* @param array $items Unterknoten
* @return int Anzahl Dateien
* Konvertiert absoluten Serverpfad in URL
*/
private static function countFiles(array $items): int
private static function convertToRelativeUrl(string $fullPath): string
{
// <== HIER den absoluten Pfad zu deinem Webroot anpassen
$webRoot = '/var/www/vhosts/ts-it24.net/stbv.ts-it24.net';
$webBase = ''; // ggf. '/subdir' falls Joomla in Unterordner
if (str_starts_with($fullPath, $webRoot)) {
return $webBase . str_replace($webRoot, '', $fullPath);
}
return $fullPath; // Fallback: Original verwenden
}
/**
* Zählt alle PDF-Dateien unterhalb eines Ordners rekursiv
*/
private static function countFilesRecursive(array $items, int $parentId): int
{
$count = 0;
foreach ($items as $node) {
if (isset($node['children']) && is_array($node['children'])) {
$count += self::countFiles($node['children']);
if (!isset($items[$parentId])) {
return 0;
}
foreach ($items[$parentId] as $item) {
if ((bool)$item['is_folder']) {
$count += self::countFilesRecursive($items, $item['id']);
} else {
$count++;
}

View File

@@ -6,12 +6,13 @@ defined('_JEXEC') or die;
require_once __DIR__ . '/helper.php';
// Retrieve JSON path and access params
$jsonPath = $params->get('json_path', 'media/com_eis/documents.json');
$confidentialLevel = $params->get('confidential_level');
$privateUserId = $params->get('private_user');
// $jsonPath = $params->get('json_path', 'media/com_eis/documents.json');
// $confidentialLevel = $params->get('confidential_level');
// $privateUserId = $params->get('private_user');
// Load and parse document tree
$items = ModEisAnzeigeHelper::getItems();
// Load and parse JSON document tree
$items = ModEisAnzeigeHelper::getItems($jsonPath);
// TODO: Apply access filtering
// $items = ModEisAnzeigeHelper::filterByAccess($items, $confidentialLevel, $privateUserId);

View File

@@ -148,4 +148,4 @@ document.addEventListener('DOMContentLoaded', function() {
});
});
});
</script>
</script>