diff --git a/.DS_Store b/.DS_Store index a61c8b0..5661c24 100644 Binary files a/.DS_Store and b/.DS_Store differ diff --git a/com_eis/.DS_Store b/com_eis/.DS_Store index 5423f05..5ccbf1b 100644 Binary files a/com_eis/.DS_Store and b/com_eis/.DS_Store differ diff --git a/com_eis/Archiv.zip b/com_eis/Archiv.zip index 7dcf0a2..390d08d 100644 Binary files a/com_eis/Archiv.zip and b/com_eis/Archiv.zip differ diff --git a/com_eis/administrator/.DS_Store b/com_eis/administrator/.DS_Store index 43d88e8..1310777 100644 Binary files a/com_eis/administrator/.DS_Store and b/com_eis/administrator/.DS_Store differ diff --git a/com_eis/administrator/language/.DS_Store b/com_eis/administrator/language/.DS_Store index 706556e..30f1ba4 100644 Binary files a/com_eis/administrator/language/.DS_Store and b/com_eis/administrator/language/.DS_Store differ diff --git a/com_eis/administrator/language/de-DE/de-DE.com_eis.ini b/com_eis/administrator/language/de-DE/de-DE.com_eis.ini index b1a830b..3a089a4 100644 --- a/com_eis/administrator/language/de-DE/de-DE.com_eis.ini +++ b/com_eis/administrator/language/de-DE/de-DE.com_eis.ini @@ -1,9 +1,44 @@ +; Joomla Backend – UI-Texte -COM_EIS_DOCUMENT_PATH="Dokumentenpfad" -COM_EIS_DOCUMENT_PATH_LABEL="Pfad zu den PDF-Dokumenten" +; Allgemein +COM_EIS_TITLE="EIS" +COM_EIS_SUBTITLE="Dokumentenverwaltung" +COM_EIS_BACK="Zurück" +COM_EIS_SAVE="Speichern" +COM_EIS_CANCEL="Abbrechen" +COM_EIS_APPLY="Anwenden" +COM_EIS_CLOSE="Schließen" + +; Main View (Baum & Scan) +COM_EIS_PDF_TREE="PDF-Baum" COM_EIS_SCAN_DOCUMENTS="Dokumente einlesen" -COM_EIS_MAIN="EIS Hauptansicht" -COM_EIS_MENU="EIS" -COM_EIS_CONFIG="Einstellungen" -COM_EIS_MAINTENANCE="Wartung" -COM_EIS_PDF_TREE="Verzeichnisbaum" +COM_EIS_DOCUMENT_PATH="Dokumenten-Pfad" +COM_EIS_NO_DOCUMENTS_FOUND="Noch keine Dokumente in der Datenbank. Bitte zuerst „Dokumente einlesen“ ausführen." +COM_EIS_EXPAND_ALL="Ausklappen" +COM_EIS_COLLAPSE_ALL="Einklappen" +COM_EIS_PREVIEW_OPEN_NEWTAB="Im neuen Tab öffnen" +COM_EIS_PREVIEW_TITLE="PDF-Vorschau" +COM_EIS_FILESIZE="Dateigröße" +COM_EIS_VIRTUAL_NEW="Neue Dokumente" + +; Config View (Einstellungen) +COM_EIS_SETTINGS_TITLE="Einstellungen" +COM_EIS_FIELDSET_GENERAL="Allgemein" +COM_EIS_FIELD_DOCUMENT_ROOT_LABEL="Basis-Verzeichnis für PDFs" +COM_EIS_FIELD_DOCUMENT_ROOT_DESC="Absoluter Serverpfad, in dem die PDF-Dateien liegen (z. B. /var/www/pdf)." + +; Meldungen +COM_EIS_MSG_SAVED_SUCCESS="Einstellungen wurden gespeichert." +COM_EIS_MSG_SAVED_ERROR="Einstellungen konnten nicht gespeichert werden." +COM_EIS_MSG_SCAN_STARTED="Einlesen gestartet." +COM_EIS_MSG_SCAN_DONE="Einlesen abgeschlossen." +COM_EIS_MSG_INVALID_PATH="Der angegebene Pfad ist ungültig oder nicht lesbar." + +; Toolbar/Buttons (falls eigene Toolbars) +COM_EIS_TOOLBAR_SAVE="Speichern" +COM_EIS_TOOLBAR_APPLY="Übernehmen" +COM_EIS_TOOLBAR_CLOSE="Schließen" + +COM_EIS_MSG_PATH_NOT_EXISTS="Hinweis: Das Verzeichnis „%s“ existiert nicht." +COM_EIS_MSG_PATH_NOT_READABLE="Hinweis: Das Verzeichnis „%s“ ist nicht lesbar." + diff --git a/com_eis/administrator/language/de-DE/de-DE.com_eis.sys.ini b/com_eis/administrator/language/de-DE/de-DE.com_eis.sys.ini index c6b7729..16e199b 100644 --- a/com_eis/administrator/language/de-DE/de-DE.com_eis.sys.ini +++ b/com_eis/administrator/language/de-DE/de-DE.com_eis.sys.ini @@ -1 +1,6 @@ -COM_EIS="EIS Komponente" \ No newline at end of file +; Joomla Backend – Systemtexte (Menü, Erweiterungsname, Kurzbeschreibung) +COM_EIS="EIS" +COM_EIS_MENU="EIS" +COM_EIS_MAIN="EIS-Dokumente" +COM_EIS_CONFIG="Einstellungen" +COM_EIS_XML_DESCRIPTION="EIS Komponente zum Verwalten und Anzeigen von PDFs." diff --git a/com_eis/administrator/language/en-GB/en-GB.com_eis.ini b/com_eis/administrator/language/en-GB/en-GB.com_eis.ini index b1a830b..21703af 100644 --- a/com_eis/administrator/language/en-GB/en-GB.com_eis.ini +++ b/com_eis/administrator/language/en-GB/en-GB.com_eis.ini @@ -1,9 +1,32 @@ +COM_EIS_TITLE="EIS" +COM_EIS_SUBTITLE="Document Management" +COM_EIS_BACK="Back" +COM_EIS_SAVE="Save" +COM_EIS_CANCEL="Cancel" +COM_EIS_APPLY="Apply" +COM_EIS_CLOSE="Close" -COM_EIS_DOCUMENT_PATH="Dokumentenpfad" -COM_EIS_DOCUMENT_PATH_LABEL="Pfad zu den PDF-Dokumenten" -COM_EIS_SCAN_DOCUMENTS="Dokumente einlesen" -COM_EIS_MAIN="EIS Hauptansicht" -COM_EIS_MENU="EIS" -COM_EIS_CONFIG="Einstellungen" -COM_EIS_MAINTENANCE="Wartung" -COM_EIS_PDF_TREE="Verzeichnisbaum" +COM_EIS_PDF_TREE="PDF Tree" +COM_EIS_SCAN_DOCUMENTS="Scan Documents" +COM_EIS_DOCUMENT_PATH="Document Path" +COM_EIS_NO_DOCUMENTS_FOUND="No documents in the database yet. Please run “Scan Documents” first." +COM_EIS_EXPAND_ALL="Expand All" +COM_EIS_COLLAPSE_ALL="Collapse All" +COM_EIS_PREVIEW_OPEN_NEWTAB="Open in new tab" +COM_EIS_PREVIEW_TITLE="PDF Preview" +COM_EIS_FILESIZE="File size" + +COM_EIS_SETTINGS_TITLE="Settings" +COM_EIS_FIELDSET_GENERAL="General" +COM_EIS_FIELD_DOCUMENT_ROOT_LABEL="Base directory for PDFs" +COM_EIS_FIELD_DOCUMENT_ROOT_DESC="Absolute server path containing the PDF files (e.g. /var/www/pdf)." + +COM_EIS_MSG_SAVED_SUCCESS="Settings saved." +COM_EIS_MSG_SAVED_ERROR="Settings could not be saved." +COM_EIS_MSG_SCAN_STARTED="Scan started." +COM_EIS_MSG_SCAN_DONE="Scan finished." +COM_EIS_MSG_INVALID_PATH="The specified path is invalid or not readable." + +COM_EIS_TOOLBAR_SAVE="Save" +COM_EIS_TOOLBAR_APPLY="Apply" +COM_EIS_TOOLBAR_CLOSE="Close" diff --git a/com_eis/administrator/language/en-GB/en-GB.com_eis.sys.ini b/com_eis/administrator/language/en-GB/en-GB.com_eis.sys.ini index c6b7729..567a032 100644 --- a/com_eis/administrator/language/en-GB/en-GB.com_eis.sys.ini +++ b/com_eis/administrator/language/en-GB/en-GB.com_eis.sys.ini @@ -1 +1,5 @@ -COM_EIS="EIS Komponente" \ No newline at end of file +COM_EIS="EIS" +COM_EIS_MENU="EIS" +COM_EIS_MAIN="EIS Documents" +COM_EIS_CONFIG="Settings" +COM_EIS_XML_DESCRIPTION="EIS component for managing and viewing PDFs." diff --git a/com_eis/administrator/sql/install.mysql.utf8.sql b/com_eis/administrator/sql/install.mysql.utf8.sql index 4fa17c6..b1a42e7 100644 --- a/com_eis/administrator/sql/install.mysql.utf8.sql +++ b/com_eis/administrator/sql/install.mysql.utf8.sql @@ -1,18 +1,33 @@ +-- Documents CREATE TABLE IF NOT EXISTS `#__eis_documents` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `name` VARCHAR(255) NOT NULL, - `path` TEXT NOT NULL, - `parent_id` INT UNSIGNED DEFAULT NULL, - `is_folder` TINYINT(1) DEFAULT 0, - `title` VARCHAR(255) DEFAULT NULL, - `description` TEXT DEFAULT NULL, - `ordering` INT DEFAULT 0, - PRIMARY KEY (`id`) + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NOT NULL, + `path` TEXT NOT NULL, + `parent_id` INT UNSIGNED DEFAULT NULL, + `is_folder` TINYINT(1) NOT NULL DEFAULT 0, + `title` VARCHAR(255) DEFAULT NULL, + `description` TEXT DEFAULT NULL, + `ordering` INT NOT NULL DEFAULT 0, + `created` DATETIME DEFAULT NULL, + `modified` DATETIME DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `idx_eis_docs_parent` (`parent_id`), + KEY `idx_eis_docs_ordering` (`ordering`), + KEY `idx_eis_docs_name` (`name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; - +-- Settings (Key/Value) CREATE TABLE IF NOT EXISTS `#__eis_settings` ( - `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, - `pdf_path` TEXT NOT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; \ No newline at end of file + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `param` VARCHAR(191) NOT NULL, + `value` TEXT NULL, + `created` DATETIME DEFAULT NULL, + `modified` DATETIME DEFAULT NULL, + PRIMARY KEY (`id`), + UNIQUE KEY `uniq_param` (`param`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + +-- Standardwert für den PDF-Pfad (leer = noch nicht gesetzt) + +INSERT IGNORE INTO `#__eis_settings` (`param`, `value`, `created`, `modified`) +VALUES ('document_root', '/var/www/pdf', NOW(), NOW()); \ No newline at end of file diff --git a/com_eis/administrator/src/.DS_Store b/com_eis/administrator/src/.DS_Store index 63835f0..9398dad 100644 Binary files a/com_eis/administrator/src/.DS_Store and b/com_eis/administrator/src/.DS_Store differ diff --git a/com_eis/administrator/src/Controller/ConfigController.php b/com_eis/administrator/src/Controller/ConfigController.php index 3f05047..1937add 100644 --- a/com_eis/administrator/src/Controller/ConfigController.php +++ b/com_eis/administrator/src/Controller/ConfigController.php @@ -4,43 +4,55 @@ namespace EIS\Component\EIS\Administrator\Controller; \defined('_JEXEC') or die; use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Controller\BaseController; use Joomla\CMS\Router\Route; +use Joomla\CMS\Session\Session; +use EIS\Component\EIS\Administrator\Helper\SettingsHelper; class ConfigController extends BaseController { public function save(): void { - $app = Factory::getApplication(); - $input = $app->getInput(); - $db = Factory::getDbo(); - - // Eingabe - $pdfPath = $input->getString('pdf_path', ''); - - // Existiert ein Eintrag? - $query = $db->getQuery(true) - ->select('COUNT(*)') - ->from($db->quoteName('#__eis_settings')); - $db->setQuery($query); - $exists = (int) $db->loadResult() > 0; - - if ($exists) { - // Update - $query = $db->getQuery(true) - ->update($db->quoteName('#__eis_settings')) - ->set($db->quoteName('pdf_path') . ' = ' . $db->quote($pdfPath)); - } else { - // Insert - $query = $db->getQuery(true) - ->insert($db->quoteName('#__eis_settings')) - ->columns([$db->quoteName('pdf_path')]) - ->values($db->quote($pdfPath)); + // CSRF + if (!Session::checkToken('post')) { + throw new \RuntimeException(Text::_('JINVALID_TOKEN'), 403); } - $db->setQuery($query)->execute(); + $app = Factory::getApplication(); + $input = $app->getInput(); - $app->enqueueMessage('Pfad gespeichert: ' . $pdfPath, 'message'); + // Feldname aus dem Config-Template + $path = (string) $input->post->get('document_root', '', 'string'); + $path = trim($path); + + // Minimal-Validierung & Normalisierung + // (Hier kein striktes is_readable(), damit man den Pfad auch erst konfigurieren kann, + // wenn das Verzeichnis später angelegt/umgehängt wird. Warnen ist aber hilfreich.) + if ($path === '') { + $app->enqueueMessage(Text::_('COM_EIS_MSG_INVALID_PATH') ?: 'Bitte einen gültigen Pfad angeben.', 'warning'); + $this->setRedirect(Route::_('index.php?option=com_eis&view=config', false)); + return; + } + + // Doppelte Slashes und trailing Slash bereinigen + $path = preg_replace('#/+#', '/', $path); + // Lass den Root-Slash stehen, entferne sonst trailing Slash + if ($path !== '/' && str_ends_with($path, '/')) { + $path = rtrim($path, '/'); + } + + // Optional: Hinweise zur Existenz/Lesbarkeit (nur Hinweis, kein Hard-Error) + if (!is_dir($path)) { + $app->enqueueMessage(Text::sprintf('COM_EIS_MSG_PATH_NOT_EXISTS', $path) ?: "Hinweis: Verzeichnis existiert nicht: {$path}", 'notice'); + } elseif (!is_readable($path)) { + $app->enqueueMessage(Text::sprintf('COM_EIS_MSG_PATH_NOT_READABLE', $path) ?: "Hinweis: Verzeichnis nicht lesbar: {$path}", 'notice'); + } + + // Persistieren + SettingsHelper::setSetting('document_root', $path); + + $app->enqueueMessage(Text::_('COM_EIS_MSG_SAVED_SUCCESS') ?: 'Einstellungen wurden gespeichert.', 'message'); $this->setRedirect(Route::_('index.php?option=com_eis&view=config', false)); } } diff --git a/com_eis/administrator/src/Controller/DisplayController.php b/com_eis/administrator/src/Controller/DisplayController.php index dd15b78..ab8e989 100644 --- a/com_eis/administrator/src/Controller/DisplayController.php +++ b/com_eis/administrator/src/Controller/DisplayController.php @@ -5,8 +5,12 @@ namespace EIS\Component\EIS\Administrator\Controller; \defined('_JEXEC') or die; use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; use Joomla\CMS\MVC\Controller\BaseController; +use Joomla\CMS\Router\Route; +use Joomla\CMS\Session\Session; use Joomla\Database\DatabaseDriver; +use EIS\Component\EIS\Administrator\Helper\SettingsHelper; class DisplayController extends BaseController { @@ -17,36 +21,39 @@ class DisplayController extends BaseController */ public function scan(): void { - $db = Factory::getDbo(); + // CSRF prüfen (Form hat Token) + if (!Session::checkToken('post')) { + throw new \RuntimeException(Text::_('JINVALID_TOKEN'), 403); + } - // Pfad aus Tabelle laden - $query = $db->getQuery(true) - ->select($db->quoteName('pdf_path')) - ->from($db->quoteName('#__eis_settings')) - ->order('id ASC') - ->setLimit(1); + $app = Factory::getApplication(); + /** @var DatabaseDriver $db */ + $db = Factory::getDbo(); - $db->setQuery($query); - $path = $db->loadResult(); + // Pfad aus Settings laden (Key/Value); Default /var/www/pdf + $path = SettingsHelper::getSetting('document_root', '/var/www/pdf'); if (!$path || !is_dir($path)) { - Factory::getApplication()->enqueueMessage('Pfad ungültig oder nicht gesetzt: ' . $path, 'error'); - $this->setRedirect('index.php?option=com_eis&view=main'); + $app->enqueueMessage(Text::sprintf('COM_EIS_MSG_PATH_NOT_EXISTS', $path) ?: ('Pfad ungültig oder nicht gesetzt: ' . $path), 'error'); + $this->setRedirect(Route::_('index.php?option=com_eis&view=main', false)); return; } // Verzeichnis rekursiv scannen $data = $this->scanFolder($path); - // Alte Einträge löschen + // Alte Einträge löschen (Hinweis: Dann sind ALLE eingefügten „neu“) $db->truncateTable('#__eis_documents'); - // In Datenbank speichern - $this->saveToDb($data, null, $db); + // In Datenbank speichern und neue IDs sammeln + $newIds = $this->saveToDb($data, null, $db); + + // Neue IDs im UserState für die View -> virtueller Ordner "Neue Dokumente" + $app->setUserState('com_eis.new_ids', $newIds); // Erfolgsmeldung - Factory::getApplication()->enqueueMessage('PDF-Struktur erfolgreich gespeichert.', 'message'); - $this->setRedirect('index.php?option=com_eis&view=main'); + $app->enqueueMessage(Text::_('COM_EIS_MSG_SCAN_DONE') ?: 'PDF-Struktur erfolgreich gespeichert.', 'message'); + $this->setRedirect(Route::_('index.php?option=com_eis&view=main', false)); } /** @@ -59,7 +66,12 @@ class DisplayController extends BaseController return $result; } - foreach (scandir($dir) as $file) { + $entries = @scandir($dir); + if ($entries === false) { + return $result; + } + + foreach ($entries as $file) { if ($file === '.' || $file === '..') { continue; } @@ -78,18 +90,26 @@ class DisplayController extends BaseController } } + // Alphabetisch stabil sortieren (Ordner/Dateien je Ebene) + usort($result, static function ($a, $b) { + return strcasecmp((string)$a['name'], (string)$b['name']); + }); + return $result; } /** * Struktur rekursiv in die Datenbank schreiben + * @return int[] Insert-IDs aller neu eingefügten Dateien (für „Neue Dokumente“) */ - private function saveToDb(array $items, ?int $parentId, DatabaseDriver $db): void + private function saveToDb(array $items, ?int $parentId, DatabaseDriver $db): array { + $insertedFileIds = []; + foreach ($items as $item) { $name = $db->quote($item['name']); - $path = $db->quote($item['path'] ?? ''); // Leerer String statt NULL - $parent = $parentId !== null ? (int) $parentId : 'NULL'; + $path = $db->quote($item['path'] ?? ''); // leer statt NULL + $parent = $parentId !== null ? (int)$parentId : 'NULL'; $isFolder = isset($item['children']) ? 1 : 0; $query = $db->getQuery(true) @@ -97,45 +117,55 @@ class DisplayController extends BaseController ->columns(['name', 'path', 'parent_id', 'is_folder']) ->values("$name, $path, $parent, $isFolder"); - $db->setQuery($query); - $db->execute(); + $db->setQuery($query)->execute(); - $insertedId = $db->insertid(); + $insertedId = (int)$db->insertid(); if ($isFolder && !empty($item['children'])) { - $this->saveToDb($item['children'], $insertedId, $db); + // Kinder speichern + $childIds = $this->saveToDb($item['children'], $insertedId, $db); + // Nur Datei-IDs sammeln + $insertedFileIds = array_merge($insertedFileIds, $childIds); + } else { + // Datei -> ID merken + $insertedFileIds[] = $insertedId; } } + + return $insertedFileIds; } + public function rename(): void { // CSRF prüfen - \Joomla\CMS\Session\Session::checkToken() or jexit(\JText::_('JINVALID_TOKEN')); + if (!Session::checkToken('post')) { + throw new \RuntimeException(Text::_('JINVALID_TOKEN'), 403); + } - $app = \Joomla\CMS\Factory::getApplication(); - $id = (int) $app->input->get('id'); - $title = trim((string) $app->input->get('title', '', 'STRING')); + $app = Factory::getApplication(); + $id = (int) $app->input->post->get('id', 0); + $title = trim((string) $app->input->post->get('title', '', 'string')); if ($id <= 0) { - $app->enqueueMessage('Ungültige ID', 'error'); - $this->setRedirect('index.php?option=com_eis&view=main'); + $app->enqueueMessage(Text::_('JERROR_AN_ERROR_HAS_OCCURRED') ?: 'Ungültige ID', 'error'); + $this->setRedirect(Route::_('index.php?option=com_eis&view=main', false)); return; } - /** @var \Joomla\Database\DatabaseDriver $db */ - $db = \Joomla\CMS\Factory::getDbo(); + /** @var DatabaseDriver $db */ + $db = Factory::getDbo(); $query = $db->getQuery(true) ->update($db->quoteName('#__eis_documents')) ->set($db->quoteName('title') . ' = ' . ($title === '' ? 'NULL' : $db->quote($title))) - ->where($db->quoteName('id') . ' = ' . (int) $id); + ->where($db->quoteName('id') . ' = ' . (int)$id); try { $db->setQuery($query)->execute(); - $app->enqueueMessage('Anzeigename gespeichert', 'message'); + $app->enqueueMessage(Text::_('COM_EIS_MSG_SAVED_SUCCESS') ?: 'Anzeigename gespeichert', 'message'); } catch (\Throwable $e) { - $app->enqueueMessage('Fehler beim Speichern: ' . $e->getMessage(), 'error'); + $app->enqueueMessage((Text::_('COM_EIS_MSG_SAVED_ERROR') ?: 'Fehler beim Speichern: ') . $e->getMessage(), 'error'); } - $this->setRedirect('index.php?option=com_eis&view=main'); + $this->setRedirect(Route::_('index.php?option=com_eis&view=main', false)); } } diff --git a/com_eis/administrator/src/Helper/SettingsHelper.php b/com_eis/administrator/src/Helper/SettingsHelper.php new file mode 100644 index 0000000..85fddd6 --- /dev/null +++ b/com_eis/administrator/src/Helper/SettingsHelper.php @@ -0,0 +1,45 @@ +getQuery(true) + ->select($db->quoteName('value')) + ->from($db->quoteName('#__eis_settings')) + ->where($db->quoteName('param') . ' = ' . $db->quote($param)); + $db->setQuery($q); + $val = $db->loadResult(); + + return ($val !== null && $val !== '') ? $val : $default; + } + + public static function setSetting(string $param, $value): void + { + $db = Factory::getDbo(); + + // Basis-INSERT per Query-Builder zusammenstellen … + $qb = $db->getQuery(true) + ->insert($db->quoteName('#__eis_settings')) + ->columns([$db->quoteName('param'), $db->quoteName('value'), $db->quoteName('modified')]) + ->values( + $db->quote($param) . ', ' . + $db->quote((string) $value) . ', ' . + $db->quote(date('Y-m-d H:i:s')) + ); + + // … und dann als String um "ON DUPLICATE KEY UPDATE" erweitern. + $sql = (string) $qb + . ' ON DUPLICATE KEY UPDATE ' + . $db->quoteName('value') . ' = VALUES(' . $db->quoteName('value') . '), ' + . $db->quoteName('modified') . ' = VALUES(' . $db->quoteName('modified') . ')'; + + $db->setQuery($sql)->execute(); + } +} diff --git a/com_eis/administrator/src/Helper/TreeHelper.php b/com_eis/administrator/src/Helper/TreeHelper.php index ba62edd..97f18b8 100644 --- a/com_eis/administrator/src/Helper/TreeHelper.php +++ b/com_eis/administrator/src/Helper/TreeHelper.php @@ -5,6 +5,7 @@ namespace EIS\Component\EIS\Administrator\Helper; \defined('_JEXEC') or die; use Joomla\CMS\Factory; +use Joomla\CMS\Language\Text; use Joomla\Database\DatabaseDriver; class TreeHelper @@ -30,12 +31,46 @@ class TreeHelper // alphabetisch nach name foreach ($grouped as &$group) { - usort($group, fn($a, $b) => strcasecmp($a['name'], $b['name'])); + usort($group, static fn($a, $b) => strcasecmp((string)$a['name'], (string)$b['name'])); } return $grouped; } + /** + * Kombiniert: Virtueller Ordner "Neue Dokumente" (falls $newIds vorhanden) + normaler Baum + */ + public static function renderTreeWithNew(array $items, array $newIds = []): string + { + $html = ''; + + // 1) Virtueller Ordner "Neue Dokumente" + $newFiles = self::collectFilesByIds($items, $newIds); + if (!empty($newFiles)) { + $label = Text::_('COM_EIS_VIRTUAL_NEW') ?: 'Neue Dokumente'; + + $html .= '
- +
- - - +