View source
<?php
function filebrowser_menu() {
$items = array();
$qry = db_query('SELECT path, location FROM {filebrowser}');
while ($o = db_fetch_object($qry)) {
$items[$o->path] = array(
'page callback' => 'filebrowser_page',
'page arguments' => array(
$o->path,
),
'access arguments' => array(
'view directory listing',
),
'type' => MENU_CALLBACK,
);
}
$items['admin/settings/filebrowser'] = array(
'title' => 'Filebrowser',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'filebrowser_admin_settings',
),
'access arguments' => array(
'access administration pages',
),
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
function filebrowser_page($path) {
global $user;
$listing = db_fetch_object(db_query("SELECT location, can_explore FROM {filebrowser} WHERE path = '%s'", $path));
$listing->can_explore = (bool) (int) $listing->can_explore;
$listing->path = $path;
$curr_dir = str_replace($listing->path, $listing->location, $_GET['q']);
$is_subdir = $listing->location != $curr_dir;
if ($is_subdir && !$listing->can_explore) {
drupal_set_message(t('You\'re not allowed to view subdirectories.'), 'error');
drupal_goto($listing->path);
}
drupal_set_title(t('Displaying contents of directory %dir', array(
'%dir' => $curr_dir,
)));
$dir = $curr_dir;
$files = array();
$total_size = 0;
if (is_dir($dir) && ($dh = opendir($dir))) {
while (($file = readdir($dh)) !== false && is_readable($dir . '/' . $file)) {
$full_path = $dir . '/' . $file;
if (is_file($full_path)) {
$f_stats = stat($full_path);
if ($f_stats !== false) {
$total_size += $f_stats['size'];
$mark_value = MARK_READ;
if ($user->access < $f_stats['ctime']) {
$mark_value = MARK_NEW;
}
else {
if ($user->access < $f_stats['mtime']) {
$mark_value = MARK_UPDATED;
}
}
$files[] = array(
l($file, $full_path) . theme('mark', $mark_value),
format_size($f_stats['size']),
);
}
else {
$files[] = array(
l($file, $full_path),
t('Unknown'),
);
}
}
else {
if (is_dir($full_path)) {
if ($listing->can_explore) {
$dirs[] = $file;
}
}
}
}
closedir($dh);
}
if ($listing->can_explore) {
rsort($dirs);
foreach ($dirs as $dir) {
if ($dir == '.') {
continue;
}
if (!$is_subdir && $dir == '..') {
continue;
}
$dir_row = array(
l($dir, $_GET['q'] . '/' . $dir),
t('Directory'),
);
array_unshift($files, $dir_row);
}
}
$header = array(
t('Name'),
t('Size'),
);
$output = theme('filebrowser_page', $files, $header, $total_size);
return $output;
}
function filebrowser_admin_settings() {
$form = array();
$form['listings'] = array(
'#type' => 'fieldset',
'#title' => t('Directory listings'),
);
$qry = db_query('SELECT path, location, can_explore FROM {filebrowser}');
$paths = array();
while ($o = db_fetch_object($qry)) {
$form['paths'][$o->path] = array(
'#type' => 'value',
'#value' => $o->path,
);
$form['locations'][$o->path] = array(
'#type' => 'value',
'#value' => $o->location,
);
$form['can_explore'][$o->path] = array(
'#type' => 'value',
'#value' => (bool) (int) $o->can_explore,
);
$paths[$o->path] = '';
}
if (!empty($paths)) {
$form['listing_checks'] = array(
'#type' => 'checkboxes',
'#options' => $paths,
);
$form['listings']['submit'] = array(
'#type' => 'submit',
'#value' => t('Update directory listings'),
'#weight' => 10,
'#submit' => array(
'filebrowser_admin_settings_submit_update',
),
);
}
else {
$form['listings']['listing_status'] = array(
'#type' => 'markup',
'#value' => '<p>' . t('No listings exist.') . '</p>',
);
}
$form['new_listing'] = array(
'#type' => 'fieldset',
'#title' => t('Add listing'),
);
$form['new_listing']['path'] = array(
'#type' => 'textfield',
'#title' => t('Drupal path'),
'#description' => t('Path that users can view this directory listing at.'),
'#required' => true,
);
$form['new_listing']['location'] = array(
'#type' => 'textfield',
'#title' => t('File system directory'),
'#description' => t('File system path to a directory.'),
'#required' => true,
);
$form['new_listing']['can_explore'] = array(
'#type' => 'checkbox',
'#title' => t('Do you want to allow exploring subdirectories?'),
);
$form['new_listing']['submit'] = array(
'#type' => 'submit',
'#value' => t('Add listing'),
'#validate' => array(
'filebrowser_admin_settings_validate_add',
),
'#submit' => array(
'filebrowser_admin_settings_submit_add',
),
);
$form['#after_build'] = array(
'filebrowser_strip_requirements',
);
return $form;
}
function filebrowser_strip_requirements($form, $form_state) {
if (isset($form_state['clicked_button']) && $form_state['clicked_button']['#value'] == t('Update directory listings')) {
$form['new_listing']['path']['#required'] = false;
$form['new_listing']['location']['#required'] = false;
}
return $form;
}
function filebrowser_admin_settings_validate_add($form, &$form_state) {
$path = $form_state['values']['path'];
$location = $form_state['values']['location'];
$path_exists = db_result(db_query('SELECT COUNT(1) FROM {menu_router} mr, {menu_links} ml WHERE mr.path = "%s" OR ml.link_path = "%s"', $path, $path));
if ($path_exists) {
form_set_error('path', t('You must specify an unused Drupal path'));
}
if (!is_dir($location)) {
form_set_error('location', t('You must specify a valid directory.'));
}
if (!is_readable($location)) {
form_set_error('location', t('The directory %dir is not readable.', array(
'%dir' => $location,
)));
}
}
function filebrowser_admin_settings_submit_add($form, &$form_state) {
db_query('INSERT INTO {filebrowser} (path, location, can_explore) VALUES ("%s", "%s", %d)', $form_state['values']['path'], $form_state['values']['location'], $form_state['values']['can_explore']);
menu_rebuild();
drupal_set_message(t('Your directory listing has been added'));
}
function filebrowser_admin_settings_submit_update($form, &$form_state) {
foreach ($form_state['values']['listing_checks'] as $check) {
if ($check) {
db_query('DELETE FROM {filebrowser} WHERE path = "%s"', $check);
}
}
menu_rebuild();
drupal_set_message(t('Your directory listing has been updated'));
}
function theme_filebrowser_admin_settings($form) {
$rows = array();
if (isset($form['paths'])) {
foreach (element_children($form['paths']) as $key) {
$row = array();
$row[] = l($form['paths'][$key]['#value'], $form['paths'][$key]['#value']);
$row[] = $form['locations'][$key]['#value'];
$stats = _filebrowser_dir_stats($form['locations'][$key]['#value']);
$row[] = $stats['file_count'];
$row[] = format_size($stats['total_size']);
$row[] = $form['can_explore'][$key]['#value'] ? t('Yes') : t('No');
$row[] = drupal_render($form['listing_checks'][$key]);
$rows[] = $row;
}
$headers = array(
t('Path'),
t('Location'),
t('Files'),
t('Size'),
t('Explorable'),
t('Delete'),
);
$form['listings']['listings'] = array(
'#value' => theme('table', $headers, $rows),
);
}
$output = drupal_render($form);
return $output;
}
function filebrowser_theme() {
return array(
'filebrowser_page' => array(
'arguments' => array(
'files' => NULL,
'header' => array(),
'total_size' => 0,
),
),
'filebrowser_admin_settings' => array(
'arguments' => array(
'form' => NULL,
),
),
);
}
function filebrowser_perm() {
return array(
'view directory listing',
);
}
function _filebrowser_dir_stats($dir) {
$file_count = 0;
$total_size = 0;
if (is_dir($dir) && ($dh = opendir($dir))) {
while (($file = readdir($dh)) !== false && is_readable($dir . '/' . $file)) {
if ($file == '.' || $file == '..') {
continue;
}
$full_path = $dir . '/' . $file;
$f_size = filesize($full_path);
$total_size += $f_size;
++$file_count;
}
closedir($dh);
}
return array(
'file_count' => $file_count,
'total_size' => $total_size,
);
}
function theme_filebrowser_page(&$files, $header = array(), $total_size = 0) {
$output = '';
if ($files) {
$output .= theme('table', $header, $files, array(
'id' => 'filebrowser-table',
));
$output .= '<p>' . t('Contains @fc files totaling @ds in size', array(
'@fc' => count($files),
'@ds' => format_size($total_size),
)) . '</p>';
}
else {
$output .= '<p>' . t('This directory is empty.') . '</p>';
}
return $output;
}