Allow opening folder lisings on client
Some checks failed
DokuWiki Default Tasks / all (push) Has been cancelled
Some checks failed
DokuWiki Default Tasks / all (push) Has been cancelled
This commit is contained in:
30
Output.php
30
Output.php
@@ -16,6 +16,9 @@ class Output
|
|||||||
/** @var array */
|
/** @var array */
|
||||||
protected $files;
|
protected $files;
|
||||||
|
|
||||||
|
/** @var Path|false|null */
|
||||||
|
protected $openPathMapper = null;
|
||||||
|
|
||||||
|
|
||||||
public function __construct(\Doku_Renderer $renderer, $basedir, $webdir, $files)
|
public function __construct(\Doku_Renderer $renderer, $basedir, $webdir, $files)
|
||||||
{
|
{
|
||||||
@@ -307,6 +310,8 @@ class Output
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$path = $this->mapOpenPath($path);
|
||||||
|
|
||||||
global $conf;
|
global $conf;
|
||||||
/** @var \Doku_Renderer_xhtml $renderer */
|
/** @var \Doku_Renderer_xhtml $renderer */
|
||||||
$renderer = $this->renderer;
|
$renderer = $this->renderer;
|
||||||
@@ -336,6 +341,31 @@ class Output
|
|||||||
$renderer->doc .= $renderer->_formatLink($link);
|
$renderer->doc .= $renderer->_formatLink($link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map a filesystem path to an alias path (if configured).
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function mapOpenPath($path)
|
||||||
|
{
|
||||||
|
if ($this->openPathMapper === false) return $path;
|
||||||
|
|
||||||
|
if ($this->openPathMapper === null) {
|
||||||
|
$syntax = plugin_load('syntax', 'luxtools');
|
||||||
|
$pathConfig = $syntax ? (string)$syntax->getConf('paths') : '';
|
||||||
|
|
||||||
|
if (trim($pathConfig) === '') {
|
||||||
|
$this->openPathMapper = false;
|
||||||
|
return $path;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->openPathMapper = new Path($pathConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->openPathMapper->mapToAliasPath($path);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a file link on the XHTML renderer
|
* Render a file link on the XHTML renderer
|
||||||
*/
|
*/
|
||||||
|
|||||||
43
Path.php
43
Path.php
@@ -103,6 +103,49 @@ class Path
|
|||||||
return $pathInfo;
|
return $pathInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map a real filesystem path back to a configured alias, if available.
|
||||||
|
*
|
||||||
|
* Example: root "/share/Datascape/" with alias "/Scape/" maps
|
||||||
|
* "/share/Datascape/some/folder" -> "/Scape/some/folder".
|
||||||
|
*
|
||||||
|
* If no alias matches, the input path is returned unchanged (except for
|
||||||
|
* normalization of slashes and dot-segments).
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function mapToAliasPath($path)
|
||||||
|
{
|
||||||
|
if (!is_string($path) || $path === '') return $path;
|
||||||
|
|
||||||
|
// normalize input for matching, but do not force a trailing slash
|
||||||
|
$normalized = static::cleanPath($path, false);
|
||||||
|
|
||||||
|
// collect root->alias mappings (avoid alias keys that reference the same config)
|
||||||
|
$mappings = [];
|
||||||
|
foreach ($this->paths as $key => $info) {
|
||||||
|
if (!isset($info['root']) || $key !== $info['root']) continue;
|
||||||
|
if (empty($info['alias'])) continue;
|
||||||
|
$mappings[$info['root']] = $info['alias'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($mappings === []) return $normalized;
|
||||||
|
|
||||||
|
// Prefer the longest matching root (handles nested/overlapping roots)
|
||||||
|
uksort($mappings, static fn($a, $b) => strlen($b) - strlen($a));
|
||||||
|
|
||||||
|
foreach ($mappings as $root => $alias) {
|
||||||
|
if (str_starts_with($normalized, $root)) {
|
||||||
|
$suffix = substr($normalized, strlen($root));
|
||||||
|
$alias = static::cleanPath($alias, true);
|
||||||
|
return rtrim($alias, '/') . '/' . $suffix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $normalized;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clean a path for better comparison
|
* Clean a path for better comparison
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -110,4 +110,13 @@ EOT
|
|||||||
$this->expectExceptionMessageMatches('/Path not allowed/');
|
$this->expectExceptionMessageMatches('/Path not allowed/');
|
||||||
$this->path->getPathInfo($path);
|
$this->path->getPathInfo($path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMapToAliasPath()
|
||||||
|
{
|
||||||
|
$mapped = $this->path->mapToAliasPath('/linux/another/path/some/folder');
|
||||||
|
$this->assertEquals('alias/some/folder', $mapped);
|
||||||
|
|
||||||
|
$unmapped = $this->path->mapToAliasPath('/linux/file/path/example.txt');
|
||||||
|
$this->assertEquals('/linux/file/path/example.txt', $unmapped);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ class plugin_luxtools_test extends DokuWikiTest
|
|||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
// Setup config so that access to the TMP directory will be allowed
|
// Setup config so that access to the TMP directory will be allowed
|
||||||
$conf ['plugin']['luxtools']['paths'] = TMP_DIR . '/filelistdata/' . "\n" . 'W> http://localhost/';
|
$conf ['plugin']['luxtools']['paths'] = TMP_DIR . '/filelistdata/' . "\n" . 'A> /Scape' . "\n" . 'W> http://localhost/';
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -288,6 +288,6 @@ class plugin_luxtools_test extends DokuWikiTest
|
|||||||
$this->assertStringNotContainsString('example2.txt', $xhtml);
|
$this->assertStringNotContainsString('example2.txt', $xhtml);
|
||||||
|
|
||||||
// Directory row should trigger the same behaviour as {{open>...}} for that folder
|
// Directory row should trigger the same behaviour as {{open>...}} for that folder
|
||||||
$this->assertStringContainsString('data-path="' . TMP_DIR . '/filelistdata/exampledir"', $xhtml);
|
$this->assertStringContainsString('data-path="/Scape/exampledir"', $xhtml);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user