Browse Source

implement local directory browser

PHP-GTK3
yggverse 5 months ago
parent
commit
c66dd6b94c
  1. 106
      src/Entity/Browser/Container/Page/Content.php
  2. 132
      src/Model/Filesystem.php

106
src/Entity/Browser/Container/Page/Content.php

@ -103,59 +103,91 @@ class Content @@ -103,59 +103,91 @@ class Content
{
case 'file':
if (file_exists($address->getPath()) && is_readable($address->getPath()))
switch (true)
{
switch ($address->getPath())
{
case is_dir($address->getPath()):
// Try directory
case (
$list = \Yggverse\Yoda\Model\Filesystem::getList(
$address->getPath()
)
):
// @TODO build fs listing
$map = [];
break;
foreach ($list as $item)
{
$map[] = trim(
sprintf(
'=> file://%s %s',
$item['path'],
$item['name'] . (
$item['file'] ? null : '/'
)
)
);
}
case str_ends_with($address->getPath(), '.gmi'):
$this->data->setGemtext(
implode(
PHP_EOL,
$map
) . PHP_EOL
);
$title = null;
$this->page->title->set(
basename(
$address->getPath()
),
'localhost'
);
$this->data->setGemtext(
file_get_contents( // @TODO format relative links
$address->getPath()
),
$title
);
break;
if ($title) // detect title by document h1
{
$this->page->title->set(
$title
);
}
// Try open file by extension supported
case str_ends_with(
$address->getPath(),
'.gmi'
):
break;
$title = null;
default:
$this->data->setGemtext(
file_get_contents( // @TODO format relative links
$address->getPath()
),
$title
);
if ($title) // detect title by document h1
{
$this->page->title->set(
'Oops!',
'file extension not supported'
$title,
'localhost'
);
}
$this->data->setPlain(
'File extension not supported'
else
{
$this->page->title->set(
basename(
$address->getPath()
),
'localhost'
);
}
}
}
else
{
$this->page->title->set(
'Failure',
'resource not found or not readable'
);
break;
$this->data->setPlain(
'Could not open file'
);
default:
$this->page->title->set(
'Failure',
'resource not found or not readable'
);
$this->data->setPlain(
'Could not open location'
);
}
break;

132
src/Model/Filesystem.php

@ -81,6 +81,112 @@ class Filesystem @@ -81,6 +81,112 @@ class Filesystem
return $this->_base . $filename;
}
public static function getList(
?string $dirname,
string $sort = 'name',
int $order = SORT_ASC,
int $method = SORT_STRING | SORT_NATURAL | SORT_FLAG_CASE
): ?array
{
// Convert to realpath with ending slash
if (!$realpath = self::_getRealpath($dirname))
{
return null;
}
// Make sure requested path is directory
if (!is_dir($realpath))
{
return null;
}
// Begin list builder
$directories = [];
$files = [];
foreach ((array) scandir($realpath) as $name)
{
// Skip system locations
if (empty($name) || $name == '.')
{
continue;
}
// Try to build destination path
if (!$path = self::_getRealpath($realpath . $name))
{
continue;
}
// Context
switch (true)
{
case is_dir($path):
$directories[] =
[
'file' => false,
'path' => $path,
'name' => $name,
'link' => urlencode(
$name
),
'time' => filemtime(
$path
)
];
break;
case is_file($path):
$files[] =
[
'file' => true,
'path' => $path,
'name' => $name,
'link' => urlencode(
$name
),
'time' => filemtime(
$path
)
];
break;
}
}
// Sort order
array_multisort(
array_column(
$directories,
$sort
),
$order,
$method,
$directories
);
// Sort files by name ASC
array_multisort(
array_column(
$directories,
$sort
),
$order,
$method,
$directories
);
// Merge list
return array_merge(
$directories,
$files
);
}
private static function _fixDirectorySeparators(
string $path,
string $separator = DIRECTORY_SEPARATOR
@ -95,4 +201,30 @@ class Filesystem @@ -95,4 +201,30 @@ class Filesystem
$path
);
}
// PHP::realpath extension appending slash to dir paths
private static function _getRealpath(
?string $path
): ?string
{
if (empty($path))
{
return null;
}
if (!$realpath = realpath($path))
{
return null;
}
if (is_dir($realpath))
{
$realpath = rtrim(
$realpath,
DIRECTORY_SEPARATOR
) . DIRECTORY_SEPARATOR;
}
return $realpath;
}
}
Loading…
Cancel
Save