This commit is contained in:
36
Crawler.php
36
Crawler.php
@@ -13,6 +13,9 @@ class Crawler
|
|||||||
/** @var bool */
|
/** @var bool */
|
||||||
protected $sortreverse = false;
|
protected $sortreverse = false;
|
||||||
|
|
||||||
|
/** @var bool */
|
||||||
|
protected $foldersFirst = false;
|
||||||
|
|
||||||
/** @var string[] patterns to ignore */
|
/** @var string[] patterns to ignore */
|
||||||
protected $ignore = [];
|
protected $ignore = [];
|
||||||
|
|
||||||
@@ -41,6 +44,11 @@ class Crawler
|
|||||||
$this->sortreverse = $sortreverse;
|
$this->sortreverse = $sortreverse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setFoldersFirst($foldersFirst)
|
||||||
|
{
|
||||||
|
$this->foldersFirst = (bool)$foldersFirst;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does a (recursive) crawl for finding files based on a given pattern.
|
* Does a (recursive) crawl for finding files based on a given pattern.
|
||||||
* Based on a safe glob reimplementation using fnmatch and opendir.
|
* Based on a safe glob reimplementation using fnmatch and opendir.
|
||||||
@@ -204,13 +212,41 @@ class Crawler
|
|||||||
$callback = [$this, 'compare' . ucfirst($this->sortby)];
|
$callback = [$this, 'compare' . ucfirst($this->sortby)];
|
||||||
if (!is_callable($callback)) return $items;
|
if (!is_callable($callback)) return $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);
|
usort($items, $callback);
|
||||||
if ($this->sortreverse) {
|
if ($this->sortreverse) {
|
||||||
$items = array_reverse($items);
|
$items = array_reverse($items);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return $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
|
* Check if a file is allowed by the configured extensions
|
||||||
*
|
*
|
||||||
|
|||||||
22
Output.php
22
Output.php
@@ -265,8 +265,26 @@ class Output
|
|||||||
|
|
||||||
$renderer->table_open($columns);
|
$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->tablethead_open();
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
];
|
||||||
|
|
||||||
|
/** @var \Doku_Renderer_xhtml $renderer */
|
||||||
|
$renderer->doc .= '<tr class="luxtools-openlocation-row"><td colspan="' . (int)$columns . '">';
|
||||||
|
$this->renderDirectoryLink($openItem);
|
||||||
|
$renderer->doc .= '</td></tr>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($hasHeader) {
|
||||||
$renderer->tablerow_open();
|
$renderer->tablerow_open();
|
||||||
|
|
||||||
$renderer->tableheader_open();
|
$renderer->tableheader_open();
|
||||||
@@ -286,6 +304,8 @@ class Output
|
|||||||
}
|
}
|
||||||
|
|
||||||
$renderer->tablerow_close();
|
$renderer->tablerow_close();
|
||||||
|
}
|
||||||
|
|
||||||
$renderer->tablethead_close();
|
$renderer->tablethead_close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,5 +10,6 @@
|
|||||||
$lang['filename'] = 'Dateiname';
|
$lang['filename'] = 'Dateiname';
|
||||||
$lang['filesize'] = 'Dateigröße';
|
$lang['filesize'] = 'Dateigröße';
|
||||||
$lang['lastmodified'] = 'Letzte Änderung';
|
$lang['lastmodified'] = 'Letzte Änderung';
|
||||||
|
$lang['openlocation'] = 'Ort öffnen';
|
||||||
$lang['error_nomatch'] = 'Keine Treffer';
|
$lang['error_nomatch'] = 'Keine Treffer';
|
||||||
$lang['error_outsidejail'] = 'Zugriff verweigert';
|
$lang['error_outsidejail'] = 'Zugriff verweigert';
|
||||||
|
|||||||
@@ -10,5 +10,6 @@
|
|||||||
$lang['filename'] = 'Filename';
|
$lang['filename'] = 'Filename';
|
||||||
$lang['filesize'] = 'Filesize';
|
$lang['filesize'] = 'Filesize';
|
||||||
$lang['lastmodified'] = 'Last modified';
|
$lang['lastmodified'] = 'Last modified';
|
||||||
|
$lang['openlocation'] = 'Open Location';
|
||||||
$lang['error_nomatch'] = 'No match';
|
$lang['error_nomatch'] = 'No match';
|
||||||
$lang['error_outsidejail'] = 'Access denied';
|
$lang['error_outsidejail'] = 'Access denied';
|
||||||
|
|||||||
@@ -9,5 +9,6 @@
|
|||||||
$lang['filename'] = 'Bestandsnaam';
|
$lang['filename'] = 'Bestandsnaam';
|
||||||
$lang['filesize'] = 'Bestandsgrootte';
|
$lang['filesize'] = 'Bestandsgrootte';
|
||||||
$lang['lastmodified'] = 'Laatst gewijzigd';
|
$lang['lastmodified'] = 'Laatst gewijzigd';
|
||||||
|
$lang['openlocation'] = 'Locatie openen';
|
||||||
$lang['error_nomatch'] = 'Niets gevonden';
|
$lang['error_nomatch'] = 'Niets gevonden';
|
||||||
$lang['error_outsidejail'] = 'Toegang geweigerd';
|
$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',
|
'order' => 'asc',
|
||||||
'style' => 'list',
|
'style' => 'list',
|
||||||
'tableheader' => 0,
|
'tableheader' => 0,
|
||||||
|
'foldersfirst' => 0,
|
||||||
'recursive' => 0,
|
'recursive' => 0,
|
||||||
'titlefile' => '_title.txt',
|
'titlefile' => '_title.txt',
|
||||||
'cache' => 0,
|
'cache' => 0,
|
||||||
@@ -222,6 +223,7 @@ abstract class syntax_plugin_luxtools_abstract extends SyntaxPlugin
|
|||||||
$crawler = new Crawler($this->getConf('extensions'));
|
$crawler = new Crawler($this->getConf('extensions'));
|
||||||
$crawler->setSortBy($params['sort']);
|
$crawler->setSortBy($params['sort']);
|
||||||
$crawler->setSortReverse($params['order'] === 'desc');
|
$crawler->setSortReverse($params['order'] === 'desc');
|
||||||
|
$crawler->setFoldersFirst(($params['foldersfirst'] ?? 0) != 0);
|
||||||
return $crawler;
|
return $crawler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,15 @@ require_once(__DIR__ . '/AbstractSyntax.php');
|
|||||||
*/
|
*/
|
||||||
class syntax_plugin_luxtools_directory extends syntax_plugin_luxtools_abstract
|
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 */
|
/** @inheritdoc */
|
||||||
protected function getSyntaxKeyword(): string
|
protected function getSyntaxKeyword(): string
|
||||||
{
|
{
|
||||||
@@ -35,6 +44,9 @@ class syntax_plugin_luxtools_directory extends syntax_plugin_luxtools_abstract
|
|||||||
return true;
|
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);
|
$crawler = $this->createCrawler($params);
|
||||||
$items = $crawler->listDirectory(
|
$items = $crawler->listDirectory(
|
||||||
$pathInfo['root'],
|
$pathInfo['root'],
|
||||||
|
|||||||
Reference in New Issue
Block a user