View source
<?php
function filebrowser_help($section = NULL, $sethelp = NULL) {
static $pagehelp = '';
if (!isset($section)) {
$pagehelp = $sethelp;
}
elseif ($section == $_GET['q'] && $pagehelp) {
return $pagehelp;
}
}
function filebrowser_admin_settings() {
$form = array(
'filebrowser_root' => array(
'#type' => 'textfield',
'#title' => t('Root directory'),
'#default_value' => variable_get('filebrowser_root', ''),
'#maxlength' => '100',
'#size' => '70',
'#description' => t('Root directory used to present the filebrowser interface. Users will not be able to go up from this folder. Only a directory name under the Drupal root is accepted. Example: "public/files".'),
),
'filebrowser_icons' => array(
'#type' => 'textfield',
'#title' => t('Icon directory'),
'#default_value' => variable_get('filebrowser_icons', ''),
'#maxlength' => '100',
'#size' => '70',
'#description' => t('Name of directory, where file type icons are stored. Files should be named "file-txt.png", "file-gif.png", etc. The default icon is "file-default.png".'),
),
'filebrowser_hide_description_files' => array(
'#type' => 'radios',
'#title' => t('Display of description files'),
'#default_value' => variable_get('filebrowser_hide_description_files', 0),
'#options' => array(
t('Show'),
t('Hide'),
),
'#description' => t('Whether to show or hide description files from directory listings.'),
),
);
return system_settings_form($form);
}
function filebrowser_perm() {
return array(
'access filebrowser',
);
}
function filebrowser_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array(
'path' => 'filebrowser',
'title' => t('Filebrowser'),
'access' => user_access('access filebrowser'),
'callback' => 'filebrowser_page',
'type' => MENU_SUGGESTED_ITEM,
);
$items[] = array(
'path' => 'admin/settings/filebrowser',
'title' => t('Filebrowser'),
'description' => t('Set filebrowser root folder and display properties.'),
'callback' => 'drupal_get_form',
'callback arguments' => array(
'filebrowser_admin_settings',
),
'access' => user_access('administer site configuration'),
);
}
return $items;
}
function filebrowser_page() {
$subfolder = preg_replace("!^filebrowser/*!", "", $_GET['q']);
$parts = explode("/", $subfolder);
$breadcrumb = array();
$dirname = t('root');
if ($subfolder) {
$dirname = array_pop($parts);
while (count($parts)) {
$breadcrumb[] = l($parts[count($parts) - 1], filebrowser_proper_path(join("/", $parts)));
array_pop($parts);
}
$breadcrumb[] = l(t('Filebrowser root'), 'filebrowser');
}
$breadcrumb[] = l(t('Home'), NULL);
drupal_set_breadcrumb(array_reverse($breadcrumb));
drupal_set_title(t('@dirname directory', array(
"@dirname" => $dirname,
)));
if (!($files = filebrowser_get_list($subfolder))) {
drupal_set_message(t('Unable to get files for this directory.'));
return theme("filebrowser_page", '');
}
$headers = array_merge(array(
array(
'data' => t("Name"),
'field' => 1,
),
array(
'data' => t("Size"),
'field' => 2,
),
array(
'data' => t("Last modified"),
'field' => 3,
),
), filebrowser_get_fileinfo());
filebrowser_sort_table(array(
tablesort_get_order($headers),
tablesort_get_sort($headers),
));
$folders = array();
foreach ($files as $rnum => $filei) {
if ($filei[1]['data'] == '') {
$folders[] = $filei;
unset($files[$rnum]);
}
}
usort($files, 'filebrowser_sort_table');
$files = array_merge($folders, $files);
foreach ($files as $rnum => $filei) {
foreach ($filei as $cnum => $cell) {
if (is_array($cell)) {
unset($filei[$cnum]['sv']);
}
}
$files[$rnum] = $filei;
}
$pre = join('', module_invoke_all('filebrowser_pre', $subfolder));
return theme('filebrowser_page', $files, $headers, $pre);
}
function theme_filebrowser_page(&$files, $header = NULL, $pre = NULL) {
if ($files) {
return '<div id="filebrowser-page">' . $pre . theme("table", $header, $files) . '</div>';
}
else {
return '';
}
}
function filebrowser_get_list($subfolder = '') {
global $base_path;
$folder = filebrowser_safe_folder($subfolder);
$inroot = $folder == variable_get('filebrowser_root', '');
if (!(file_exists($folder) && is_dir($folder) && ($dir = opendir($folder)))) {
return FALSE;
}
$files = $folders = array();
$infofile = FALSE;
while (($entry = readdir($dir)) !== FALSE) {
if (is_dir("{$folder}/{$entry}")) {
if (!in_array($entry, array(
".svn",
"CVS",
))) {
$folders[] = $entry;
}
}
else {
if ($entry == '.htaccess') {
continue;
}
if (in_array(strtolower($entry), array(
"descript.ion",
"files.bbs",
))) {
$infofile = $entry;
if (!variable_get('filebrowser_hide_description_files', 0)) {
$files[] = $entry;
}
}
else {
$files[] = $entry;
}
}
}
closedir($dir);
sort($folders);
sort($files);
$files = array_merge($folders, $files);
if ($infofile) {
$info = filebrowser_get_fileinfo("{$folder}/{$infofile}", $subfolder);
$count = count(filebrowser_get_fileinfo());
$emptyinfo = $count ? array_fill(0, $count, '') : array();
}
else {
$info = $emptyinfo = array();
}
$details = array();
foreach ($files as $file) {
$extrainfo = isset($info[$file]) ? $info[$file] : $emptyinfo;
if (!in_array($file, array(
".",
"..",
))) {
$completepath = "{$folder}/{$file}";
if ($stat = stat($completepath)) {
$icon = filebrowser_get_icon($completepath);
$age = time() - $stat['mtime'];
if (is_dir($completepath)) {
$link = l("{$icon} {$file}", filebrowser_proper_path("{$subfolder}/{$file}"), array(), NULL, NULL, FALSE, TRUE);
$size = '';
}
else {
$link = "<a href=\"{$base_path}{$completepath}\">{$icon} {$file}</a>";
$size = format_size($stat['size']);
}
$details[] = array_merge(array(
array(
'data' => $link,
'class' => 'filename',
'sv' => $file,
),
array(
'data' => $size,
'sv' => $size ? $stat['size'] : 0,
),
array(
'data' => format_interval($age),
'sv' => $age,
),
), $extrainfo);
}
}
elseif ($file == ".." && !$inroot) {
$icon = filebrowser_get_icon(NULL, 'folder');
$link = "{$icon} {$file}";
$parts = explode("/", $subfolder);
array_pop($parts);
$up = t('up');
$link = l("{$icon} {$file} <{$up}>", filebrowser_proper_path(join("/", $parts)), array(), NULL, NULL, FALSE, TRUE);
$details[] = array_merge(array(
array(
'data' => $link,
'class' => 'filename',
'sv' => $file,
),
array(
'data' => '',
'sv' => 0,
),
array(
'data' => '',
'sv' => 0,
),
), $extrainfo);
}
}
return $details;
}
function filebrowser_get_fileinfo($fullpath = NULL, $subfolder = '') {
static $metacols = array();
if (!isset($fullpath)) {
return $metacols;
}
$metainfo = array();
if (is_readable($fullpath) && ($file = file($fullpath))) {
foreach ($file as $line) {
if (trim($line) == '' || strpos(trim($line), '#') === 0) {
continue;
}
list($name, $description) = explode(" ", $line, 2);
if (isset($metainfo[$name])) {
$metainfo[$name] .= trim($description) . " ";
}
else {
$metainfo[$name] = trim($description) . " ";
}
}
$callback = FALSE;
if (isset($metainfo['*callback*']) && function_exists(trim($metainfo['*callback*']))) {
$callback = trim($metainfo['*callback*']);
unset($metainfo['*callback*']);
}
if (isset($metainfo['.'])) {
filebrowser_help(NULL, $metainfo['.']);
unset($metainfo['.']);
}
foreach ($metainfo as $name => $description) {
$metainfo[$name] = $callback ? $callback(trim($description), $subfolder, $name) : array(
trim($description),
);
}
$metacols = $callback ? $callback() : array(
t('Description'),
);
}
return $metainfo;
}
function filebrowser_get_icon($fullpath = NULL, $iconname = NULL) {
if (isset($fullpath)) {
$iconname = is_dir($fullpath) ? 'folder' : preg_replace("!^.+\\.([^\\.]+)\$!", "\\1", $fullpath);
}
elseif (!isset($iconname)) {
$iconname = 'default';
}
$iconfiles = array(
variable_get('filebrowser_icons', '') . "/file-{$iconname}.png",
variable_get('filebrowser_icons', '') . "/file-default.png",
);
foreach ($iconfiles as $icon) {
if (file_exists($icon)) {
return theme("image", $icon);
}
}
return '';
}
function filebrowser_safe_folder($subfolder) {
$folder = variable_get('filebrowser_root', '') . "/{$subfolder}";
while (TRUE) {
$safer = str_replace(array(
"\\",
"../",
"/.svn",
"/CVS",
"..",
), array(
"/",
"",
"",
"",
"",
), $folder);
if ($safer !== $folder) {
$folder = $safer;
}
else {
break;
}
}
$folder = preg_replace("!^/*([^/].+[^/])/*\$!", "\\1", $folder);
return preg_replace("!/+!", "/", $folder);
}
function filebrowser_proper_path($path) {
return str_replace("//", "/", "filebrowser/{$path}");
}
function filebrowser_sort_table($a, $b = NULL) {
static $orderby = 0;
static $sort = '';
if (!isset($b)) {
$orderby = (int) $a[0]['sql'] - 1;
$sort = $a[1];
}
elseif (is_array($a) && isset($a[$orderby]) && isset($a[$orderby]['sv'])) {
if ($a[$orderby]['sv'] == $b[$orderby]['sv']) {
return 0;
}
if ($sort == 'asc') {
return $a[$orderby]['sv'] > $b[$orderby]['sv'];
}
else {
return $a[$orderby]['sv'] < $b[$orderby]['sv'];
}
}
}