Одним из самых простых способов публикации файлов является их размещение в пределах ветви файловой системы, доступной для просмотра в браузере. Как сделать такой «просмотрщик» на 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
Интересный модуль. Не для всех движков есть.