This commit is contained in:
42
Crawler.php
42
Crawler.php
@@ -13,6 +13,9 @@ class Crawler
|
||||
/** @var bool */
|
||||
protected $sortreverse = false;
|
||||
|
||||
/** @var bool */
|
||||
protected $foldersFirst = false;
|
||||
|
||||
/** @var string[] patterns to ignore */
|
||||
protected $ignore = [];
|
||||
|
||||
@@ -41,6 +44,11 @@ class Crawler
|
||||
$this->sortreverse = $sortreverse;
|
||||
}
|
||||
|
||||
public function setFoldersFirst($foldersFirst)
|
||||
{
|
||||
$this->foldersFirst = (bool)$foldersFirst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a (recursive) crawl for finding files based on a given pattern.
|
||||
* Based on a safe glob reimplementation using fnmatch and opendir.
|
||||
@@ -204,13 +212,41 @@ class Crawler
|
||||
$callback = [$this, 'compare' . ucfirst($this->sortby)];
|
||||
if (!is_callable($callback)) return $items;
|
||||
|
||||
usort($items, $callback);
|
||||
if ($this->sortreverse) {
|
||||
$items = array_reverse($items);
|
||||
// Optional grouping: keep directories before files.
|
||||
// Implement reverse ordering by inverting comparisons instead of array_reverse(),
|
||||
// so the directory-first grouping stays intact.
|
||||
if ($this->foldersFirst) {
|
||||
usort($items, function ($a, $b) use ($callback) {
|
||||
$aIsDir = $this->isDirectoryItem($a);
|
||||
$bIsDir = $this->isDirectoryItem($b);
|
||||
if ($aIsDir !== $bIsDir) {
|
||||
return $aIsDir ? -1 : 1;
|
||||
}
|
||||
|
||||
$cmp = call_user_func($callback, $a, $b);
|
||||
if ($this->sortreverse) $cmp = -$cmp;
|
||||
return $cmp;
|
||||
});
|
||||
} else {
|
||||
usort($items, $callback);
|
||||
if ($this->sortreverse) {
|
||||
$items = array_reverse($items);
|
||||
}
|
||||
}
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect whether an item represents a directory.
|
||||
* Supports both crawl() results (children tree) and listDirectory() results (isdir).
|
||||
*/
|
||||
protected function isDirectoryItem($item)
|
||||
{
|
||||
if (!is_array($item)) return false;
|
||||
if (!empty($item['isdir'])) return true;
|
||||
return array_key_exists('children', $item) && $item['children'] !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is allowed by the configured extensions
|
||||
*
|
||||
|
||||
44
Output.php
44
Output.php
@@ -265,27 +265,47 @@ class Output
|
||||
|
||||
$renderer->table_open($columns);
|
||||
|
||||
if ($params['tableheader']) {
|
||||
$hasOpenLocation = isset($params['openlocation']) && is_string($params['openlocation']) && trim($params['openlocation']) !== '';
|
||||
$hasHeader = !empty($params['tableheader']);
|
||||
if ($hasOpenLocation || $hasHeader) {
|
||||
$renderer->tablethead_open();
|
||||
$renderer->tablerow_open();
|
||||
|
||||
$renderer->tableheader_open();
|
||||
$renderer->cdata($this->getLang('filename'));
|
||||
$renderer->tableheader_close();
|
||||
// Small row above the header with an "Open Location" link.
|
||||
if ($hasOpenLocation && ($renderer instanceof \Doku_Renderer_xhtml)) {
|
||||
$openItem = [
|
||||
'name' => $this->getLang('openlocation'),
|
||||
'path' => $params['openlocation'],
|
||||
'isdir' => true,
|
||||
];
|
||||
|
||||
if ($params['showsize']) {
|
||||
$renderer->tableheader_open();
|
||||
$renderer->cdata($this->getLang('filesize'));
|
||||
$renderer->tableheader_close();
|
||||
/** @var \Doku_Renderer_xhtml $renderer */
|
||||
$renderer->doc .= '<tr class="luxtools-openlocation-row"><td colspan="' . (int)$columns . '">';
|
||||
$this->renderDirectoryLink($openItem);
|
||||
$renderer->doc .= '</td></tr>';
|
||||
}
|
||||
|
||||
if ($params['showdate']) {
|
||||
if ($hasHeader) {
|
||||
$renderer->tablerow_open();
|
||||
|
||||
$renderer->tableheader_open();
|
||||
$renderer->cdata($this->getLang('lastmodified'));
|
||||
$renderer->cdata($this->getLang('filename'));
|
||||
$renderer->tableheader_close();
|
||||
|
||||
if ($params['showsize']) {
|
||||
$renderer->tableheader_open();
|
||||
$renderer->cdata($this->getLang('filesize'));
|
||||
$renderer->tableheader_close();
|
||||
}
|
||||
|
||||
if ($params['showdate']) {
|
||||
$renderer->tableheader_open();
|
||||
$renderer->cdata($this->getLang('lastmodified'));
|
||||
$renderer->tableheader_close();
|
||||
}
|
||||
|
||||
$renderer->tablerow_close();
|
||||
}
|
||||
|
||||
$renderer->tablerow_close();
|
||||
$renderer->tablethead_close();
|
||||
}
|
||||
|
||||
|
||||
@@ -10,5 +10,6 @@
|
||||
$lang['filename'] = 'Dateiname';
|
||||
$lang['filesize'] = 'Dateigröße';
|
||||
$lang['lastmodified'] = 'Letzte Änderung';
|
||||
$lang['openlocation'] = 'Ort öffnen';
|
||||
$lang['error_nomatch'] = 'Keine Treffer';
|
||||
$lang['error_outsidejail'] = 'Zugriff verweigert';
|
||||
|
||||
@@ -10,5 +10,6 @@
|
||||
$lang['filename'] = 'Filename';
|
||||
$lang['filesize'] = 'Filesize';
|
||||
$lang['lastmodified'] = 'Last modified';
|
||||
$lang['openlocation'] = 'Open Location';
|
||||
$lang['error_nomatch'] = 'No match';
|
||||
$lang['error_outsidejail'] = 'Access denied';
|
||||
|
||||
@@ -9,5 +9,6 @@
|
||||
$lang['filename'] = 'Bestandsnaam';
|
||||
$lang['filesize'] = 'Bestandsgrootte';
|
||||
$lang['lastmodified'] = 'Laatst gewijzigd';
|
||||
$lang['openlocation'] = 'Locatie openen';
|
||||
$lang['error_nomatch'] = 'Niets gevonden';
|
||||
$lang['error_outsidejail'] = 'Toegang geweigerd';
|
||||
|
||||
19
style.css
Normal file
19
style.css
Normal file
@@ -0,0 +1,19 @@
|
||||
/* LuxTools plugin styles
|
||||
* Keep this minimal and scoped to the plugin container.
|
||||
*/
|
||||
|
||||
/* DokuWiki often highlights rows on hover. Avoid highlighting header rows. */
|
||||
div.filetools-plugin table thead tr:hover > * {
|
||||
background-color: @ini_background_alt !important;
|
||||
}
|
||||
|
||||
|
||||
/* "Open Location" row above the header should be visually smaller. */
|
||||
div.filetools-plugin table thead tr.luxtools-openlocation-row td {
|
||||
font-size: 80%;
|
||||
padding-top: 0.2em;
|
||||
padding-bottom: 0.2em;
|
||||
}
|
||||
div.filetools-plugin table thead tr.luxtools-openlocation-row:hover td {
|
||||
background-color: @ini_background !important;
|
||||
}
|
||||
@@ -165,6 +165,7 @@ abstract class syntax_plugin_luxtools_abstract extends SyntaxPlugin
|
||||
'order' => 'asc',
|
||||
'style' => 'list',
|
||||
'tableheader' => 0,
|
||||
'foldersfirst' => 0,
|
||||
'recursive' => 0,
|
||||
'titlefile' => '_title.txt',
|
||||
'cache' => 0,
|
||||
@@ -222,6 +223,7 @@ abstract class syntax_plugin_luxtools_abstract extends SyntaxPlugin
|
||||
$crawler = new Crawler($this->getConf('extensions'));
|
||||
$crawler->setSortBy($params['sort']);
|
||||
$crawler->setSortReverse($params['order'] === 'desc');
|
||||
$crawler->setFoldersFirst(($params['foldersfirst'] ?? 0) != 0);
|
||||
return $crawler;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,15 @@ require_once(__DIR__ . '/AbstractSyntax.php');
|
||||
*/
|
||||
class syntax_plugin_luxtools_directory extends syntax_plugin_luxtools_abstract
|
||||
{
|
||||
/** @inheritdoc */
|
||||
protected function getDefaultParams(): array
|
||||
{
|
||||
return [
|
||||
// Directory listings should group folders before files by default.
|
||||
'foldersfirst' => 1,
|
||||
];
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
protected function getSyntaxKeyword(): string
|
||||
{
|
||||
@@ -35,6 +44,9 @@ class syntax_plugin_luxtools_directory extends syntax_plugin_luxtools_abstract
|
||||
return true;
|
||||
}
|
||||
|
||||
// Provide the current directory path so Output can render the "Open Location" link.
|
||||
$params['openlocation'] = $pathInfo['root'] . $pathInfo['local'];
|
||||
|
||||
$crawler = $this->createCrawler($params);
|
||||
$items = $crawler->listDirectory(
|
||||
$pathInfo['root'],
|
||||
|
||||
Reference in New Issue
Block a user