View source
<?php
function _filebrowser_get_path(&$node) {
$result = $node->folder_path;
if (module_exists("token")) {
$result = token_replace($result, $type = 'node', $node, $leading = '[', $trailing = ']');
}
return $result;
}
function _filebrowser_convert_from_fs_encoding($node, $source) {
if (!is_string($node->folder_presentation->encoding) || strcasecmp($node->folder_presentation->encoding, 'UTF-8')) {
return $source;
}
else {
return mb_convert_encoding($source, "UTF-8", $node->folder_presentation->encoding);
}
}
function _filebrowser_convert_to_fs_encoding($node, $source) {
if (!is_string($node->folder_presentation->encoding) || strcasecmp($node->folder_presentation->encoding, 'UTF-8')) {
return $source;
}
else {
return mb_convert_encoding($source, $node->folder_presentation->encoding, "UTF-8");
}
}
function _filebrowser_load_files(&$node, $fid = NULL, $rebuild = FALSE) {
global $user, $base_url;
if (!$fid && (arg(0) == 'node' && is_numeric(arg(2)))) {
$fid = arg(2);
}
if ($fid) {
$content = _filebrowser_node_content_load($fid);
if (!$content) {
drupal_goto("node/{$node->nid}");
}
$relative_path = $content['path'];
}
else {
$relative_path = '/';
}
$is_subdir = $relative_path != '/';
if ($is_subdir && !_filebrowser_can_explore_subfolders($node)) {
drupal_set_message(t('You\'re not allowed to browse sub folders.'), 'error');
return;
}
if (!empty($relative_path)) {
$dirs = explode('/', $relative_path);
foreach ($dirs as $dir) {
if (!empty($dir)) {
if (_filebrowser_cant_view_file($node, $dir)) {
drupal_set_message(t("You're not allowed to view '%dir'.", array(
'%dir' => $dir,
)), 'error');
return;
}
}
}
}
static $cache = array();
$cid = "{$node->nid}::{$relative_path}";
if ($rebuild) {
unset($cache[$cid]);
unset($node->file_listing);
}
if (isset($cache[$cid])) {
return $node->file_listing = $cache[$cid];
}
$db_content = array();
$cursor = db_query("SELECT * FROM {node_dir_listing_content} where nid=%d and root = '%s'", $node->nid, $relative_path);
while ($data = db_fetch_array($cursor)) {
$db_content[$data['path']] = $data;
}
$fs_root = _filebrowser_convert_to_fs_encoding($node, _filebrowser_get_path($node));
$fs_root = realpath($fs_root);
if ($fs_root === FALSE) {
drupal_set_message(t('Configured folder is not readable or is not a directory.'), 'error');
return;
}
$fs_root = realpath($fs_root . "/" . _filebrowser_convert_to_fs_encoding($node, $relative_path)) . "/";
$file_metadata = array();
$files = array();
$files_count = 0;
$total_size = 0;
$folder_count = 0;
if (is_dir($fs_root) && ($handler = opendir($fs_root))) {
while (($fs_filename = readdir($handler)) !== FALSE) {
$fs_file_full_path = $fs_root . $fs_filename;
if (!is_readable($fs_file_full_path)) {
continue;
}
if ($fs_filename == '.' || $fs_filename == '..') {
if ($fs_filename == '..' && !$is_subdir) {
continue;
}
}
else {
if (is_dir($fs_file_full_path) && !_filebrowser_can_explore_subfolders($node)) {
continue;
}
if (is_file($fs_file_full_path) && !_filebrowser_can_view_file($node, $fs_filename)) {
continue;
}
if (_filebrowser_cant_view_file($node, $fs_filename)) {
continue;
}
}
$filename = _filebrowser_convert_from_fs_encoding($node, $fs_filename);
if ($filename == '.') {
$file_relative_path = $relative_path;
}
elseif ($filename == '..') {
$file_relative_path = _filebrowser_safe_dirname($relative_path);
$content = db_fetch_array(db_query("SELECT * from {node_dir_listing_content} WHERE nid=%d and path='%s'", $node->nid, $file_relative_path));
if ($content) {
$db_content[$file_relative_path] =& $content;
}
}
else {
$file_relative_path = $relative_path . ($relative_path != '/' ? '/' : '') . $filename;
}
if (!isset($db_content[$file_relative_path])) {
$db_content[$file_relative_path] = array(
'exists' => TRUE,
'nid' => $node->nid,
'root' => $relative_path,
'path' => $file_relative_path,
);
}
$db_content[$file_relative_path]['exists'] = TRUE;
$db_content[$file_relative_path]['display-name'] = $filename;
$files[$filename] = array(
'nid' => $node->nid,
'display-name' => $filename,
'relative-path' => $file_relative_path,
'full-path' => rtrim($fs_root, '/') . "/" . $fs_filename,
'status' => MARK_READ,
);
$result = module_invoke_all('filebrowser_metadata_get', $files[$filename]);
if ($result && is_array($result)) {
$files[$filename] = array_merge($files[$filename], $result);
}
if ($files[$filename]['kind'] == 0) {
$total_size += $files[$filename]['size'];
$files_count++;
}
else {
if ($fs_filename != '.') {
$folder_count++;
}
}
if ($user->uid) {
if ($user->access < $files[$filename]['created']) {
$files[$filename]['status'] = MARK_NEW;
}
elseif ($user->access < $files[$filename]['modified']) {
$files[$filename]['status'] = MARK_UPDATED;
}
}
if ($fs_filename == '..') {
$files[$filename]['mime-type'] .= "/parent";
$files[$filename]['kind'] = 2;
}
$file_path = array();
if ($fs_filename == '..') {
$parent_folder = dirname($relative_path);
if ($parent_folder != "/") {
$file_path['path'] = $parent_folder;
}
}
else {
$file_path['path'] = $relative_path . $fs_filename;
}
}
$files['.']['size'] = $total_size;
$files['.']['files_count'] = $files_count;
$files['.']['folders_count'] = $folder_count;
$files['.']['relative-path'] = $relative_path;
closedir($handler);
}
$to_delete = array();
foreach ($db_content as $path => &$record) {
if (!isset($record['exists'])) {
$to_delete[] = $record['fid'];
}
else {
if (!isset($record['fid'])) {
drupal_write_record('node_dir_listing_content', $record);
}
$key = $record['display-name'];
$files[$key]['fid'] = $record['fid'];
if ($files[$key]['kind'] != 0) {
$files[$key]['url'] = _filebrowser_folder_url("node/{$node->nid}" . ($record['path'] != '/' ? "/{$record['fid']}" : ""), array(
'absolute' => TRUE,
));
}
else {
$files[$key]['url'] = _filebrowser_file_url($node, $record);
}
}
}
if (count($to_delete)) {
db_query("DELETE FROM {node_dir_listing_content} where fid in (" . implode(",", $to_delete) . ")");
}
$cache[$relative_path] =& $files;
$node->file_listing = $files;
}
function _filebrowser_safe_basename($path) {
$path = rtrim($path, '/');
$path = explode('/', $path);
return end($path);
}
function _filebrowser_safe_dirname($path) {
$path = rtrim($path, '/');
$path = explode('/', $path);
array_pop($path);
$result = implode("/", $path);
if ($result == '') {
return '/';
}
return $result;
}