Как сделать файловую систему доступной для просмотра в браузере?

Одним из самых простых способов публикации файлов является их размещение в пределах ветви файловой системы, доступной для просмотра в браузере. Как сделать такой «просмотрщик» на G-Drive, можно прочитать в данной статье.

Представленный в статье модуль не предназначен для отображения сразу всей структуры некоторой ветви файловой системы. В нем в ответ на каждый запрос отображаются оглавление отдельного каталога и строка навигации для перехода в один из вышележащих каталогов относительно текущего (отображаемого). Для получения оглавления каталога мной были использованы стандартные функции opendir, readdir и closedir. Основу модуля составляет следующий код:

$ps=strlen($p0)?'/':'';
$prefix='';
$base=$ps.$p0.'/';
$path=$ps.$px.'/';
$fullpath=$_SERVER['DOCUMENT_ROOT'].$ps.$px;

if (
  realpath($fullpath)===strtr($fullpath,'/',DIRECTORY_SEPARATOR)&&
  strncmp($path,$prefix.$base,strlen($prefix)+strlen($base))==0&&
  chdir($fullpath)&&
  ($dir=opendir($fullpath))
)
{
  $dirs=array();
  $files=array();
  while (($obj=readdir($dir))!==false)
  {
    if ($obj[0]!='.')
    {
      if (is_dir($obj)) $dirs[]=$obj;
      else
      {
        $files[]=$obj;
        $sizes[]=filesize($obj);
      }
    }
  }
  closedir($dir);
}
else error(404);

В коде реализовано наложение адресной ветви на ветвь файловой системы путем совмещения категории G-Drive с каталогом файловой системы, который является вершиной доступной для просмотра ветви файловой системы или находится выше нее.

Путь для адреса «вершины» (базовый путь) складывается из префикса и базы. База – это краткое имя вершины, обрамленное слешами, или слеш. Префикс – это часть пути до базы. Текущий путь определяется адресом текущего каталога и обязательно содержит завершающий слеш вне зависимости от его наличия в адресе. Полный путь – это полное имя текущего каталога в файловой системе. Он наоборот не содержит завершающий слеш (кроме случая, когда текущим является корневой каталог файловой системы).

Использование переменной $ps позволяет корректно задавать пути для пустой категории, что в свою очередь позволяет отображать оглавление каталога по адресу, состоящему из слеша, т.е. на главной странице сайта. Для отображения подкаталогов недостаточно подключения модуля только к пустой категории. Его также нужно подключить к категориям, которые соответствуют подкаталогам, нуждающимся в отображении. При этом к пустой категории можно подключить отдельный модуль, отображающий в качестве имен подкаталогов имена или символьные идентификаторы категорий, к которым подключен данный модуль.

В модуле также присутствует серверный код сортировки оглавления каталога. Добавьте к основному ветвлению в начало условия фрагмент $pn<4&& и в конец первого блока ветвления (сразу после команды закрытия каталога) фрагмент

  if ($pn==1) rsort($dirs);
  else sort($dirs);
  
  if (count($files)) switch ($pn)
  {
    case 0:
      array_multisort($files,$sizes);
      break;
    case 1:
      array_multisort($files,SORT_DESC,$sizes);
      break;
    case 2:
      array_multisort($sizes,$files);
      break;
    case 3:
      array_multisort($sizes,SORT_DESC,$files);
  }

  function sortlink($s=0)
  {
    $p=$s<<1;
    $p+=$GLOBALS['pn']==$p;
    return $p?'?p='.$p:'';
  }

Из кода видно, что сортировка может выполняться по имени и размеру файлов, по возрастанию и убыванию. Функция sortlink предназначена для добавления к адресу текущего каталога параметра, переключающего тип сортировки. Когда в параметре функции указан 0, адрес позволит выполнить сортировку по имени (установить тип сортировки 0 или 1), а когда 1 – по размеру файлов (установить тип сортировки 2 или 3). Ссылки с адресами для переключения целесообразно размещать в заголовках столбцов таблицы, содержащих соответственно имена и размеры файлов. Во всех прочих адресах каталогов нужно наследовать текущий тип сортировки. Для этого можно определить специальную переменную $term:

$term=$pn?'?p='.$pn:'';

Эту же переменную можно использовать для добавления к адресам каталогов завершающего слеша, немного изменив ее определение (только не добавляйте такой терминатор к адресу главной, а используйте его вместо адреса главной):

$term=$pn?'/?p='.$pn:'/';

Код вывода строки навигации для шаблона:

<p><?php $i=strlen($prefix); while (++$i<strlen($path)): ?>/<a href="<?=

substr($path,0,$i=strpos($path,'/',$start=$i)),$term

?>"><?= 

substr($path,$start,$i-$start)

?></a><?php endwhile; ?></p>

И код вывода таблицы с оглавлением каталога:

<table cellspacing=0 id="fb">
<tr><th><a href="<?= $p,sortlink(0) ?>">Name</a></th><th class="num"><a href="<?= $p,sortlink(1) ?>">Size</a></th></tr>
<?php $i=0; foreach ($dirs as $obj): ?>
<tr class="r<?= $i++&1 ?>"><td class="folder"><a href="<?= $path,$obj,$term ?>"><?= $obj ?></a></td><td class="num">folder</td></tr>
<?php endforeach; foreach ($files as $j=>$obj): ?>
<tr class="r<?= $i++&1 ?>"><td class="file"><a href="<?= $path,$obj ?>"><?= $obj ?></a></td><td class="num"><?= $sizes[$j] ?> B</td></tr>
<?php endforeach; ?>
<tr><th colspan=2>Items: <?= $i ?> (files: <?= count($files) ?>, folders: <?= count($dirs) ?>)</th></tr>
</table>

Запрос на подключение модуля:

INSERT INTO `site_categories` (`id`, `name`, `bits`) VALUES
('files', 'File Browser', 45);

Расшифровка значения поля bits (45=1011012):

  • 102 – использовать режим подключения файлов x2 для подключения файла files.h.php с основным кодом модуля и файла вложенного шаблона files.php;
  • 1 – разрешить GET-параметр p для непустых объектов категории;
  • 1 – разрешить GET-параметр p для пустого объекта категории;
  • 012 – использовать режим разрешений 1.

Демонстрация: /files – пробуем!

Исходники: g-drive-files-0.05.zip

Комментарии: 0

Отправить комментарий

Ваш адрес E-mail не будет опубликован.