You are here

function _filebrowser_load_files in Filebrowser 7.2

Same name and namespace in other branches
  1. 8 filebrowser.common.inc \_filebrowser_load_files()
  2. 6.2 includes/filesystem.inc \_filebrowser_load_files()
  3. 7.4 filebrowser.common.inc \_filebrowser_load_files()
  4. 7.3 filebrowser.common.inc \_filebrowser_load_files()

Load data from current path.

Parameters

source node:

11 calls to _filebrowser_load_files()
filebrowser_form_create_folder_submit in ./filebrowser.module
create folder submition.
filebrowser_form_create_folder_validate in ./filebrowser.module
Implements hook_validate() for creating a folder
filebrowser_form_metadata in ./filebrowser.pages.inc
filebrowser_form_upload in ./filebrowser.module
upload form definition.
filebrowser_form_upload_submit in ./filebrowser.module
uploads submition.

... See full list

File

./filebrowser.common.inc, line 253
Misc filebrowser common functions.

Code

function _filebrowser_load_files(&$node, $fid = NULL, $rebuild = FALSE) {
  global $user, $base_url;

  // folder path are node/NID/FID?QUERY
  if (!$fid && (arg(0) == 'node' && is_numeric(arg(2)))) {
    $fid = arg(2);
  }

  // Select current file record according to fid
  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 we shouldn't be in a subdirectory, redirect to root_dir.
  if ($is_subdir && !_filebrowser_can_explore_subfolders($node)) {
    drupal_set_message(t('You\'re not allowed to browse sub folders.'), 'error');
    return;
  }

  // More advanced check to make sure no parent directories match our files.
  // blacklist
  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;
        }
      }
    }
  }

  // If this folder has already been processed, take it result
  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];
  }

  // Load database folder content
  $db_content = array();
  $query = db_query("SELECT * FROM {node_dir_listing_content} where nid = :nid and root = :root", array(
    ':nid' => $node->nid,
    ':root' => $relative_path,
  ));
  foreach ($query as $data) {
    $db_content[$data->path] = (array) $data;
  }

  // Build full path
  $fs_root = _filebrowser_encoding_to_fs($node, _filebrowser_get_node_root($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_encoding_to_fs($node, $relative_path)) . "/";

  // Load meta-data
  $file_metadata = array();

  // Iterate over files
  $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;

      // Check FS reading rights
      if (!is_readable($fs_file_full_path)) {
        continue;
      }

      // First file filtering
      if ($fs_filename == '.' || $fs_filename == '..') {

        // We are in the root folder, so we don't need an "up" entry
        if ($fs_filename == '..' && !$is_subdir) {
          continue;
        }
      }
      else {

        // Check subfolder rights
        if (is_dir($fs_file_full_path) && !_filebrowser_can_explore_subfolders($node)) {
          continue;
        }

        // This file is not filtered
        if (is_file($fs_file_full_path) && !_filebrowser_can_view_file($node, $fs_filename)) {
          continue;
        }

        // This file is not allowed
        if (_filebrowser_cant_view_file($node, $fs_filename)) {
          continue;
        }
      }

      // Build file relative path
      $filename = _filebrowser_encoding_from_fs($node, $fs_filename);
      if ($filename == '.') {
        $file_relative_path = $relative_path;
      }
      elseif ($filename == '..') {
        $file_relative_path = _filebrowser_safe_dirname($relative_path);
        $content = (array) db_query("\n            SELECT *\n            FROM {node_dir_listing_content}\n            WHERE nid=:nid and path=:path", array(
          ':nid' => $node->nid,
          ':path' => $file_relative_path,
        ))
          ->fetch();
        if ($content) {
          $db_content[$file_relative_path] =& $content;
        }
      }
      else {
        $file_relative_path = $relative_path . ($relative_path != '/' ? '/' : '') . $filename;
      }

      // Build database file record
      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;
      }
    }

    // Set global folder properties
    $files['.']['size'] = $total_size;
    $files['.']['files_count'] = $files_count;
    $files['.']['folders_count'] = $folder_count;
    $files['.']['relative-path'] = $relative_path;
    closedir($handler);
  }

  // Synchronize what we seen on filesystem with what is stored in database
  // We also build an access URL for each file as it is why we stored this stuff
  // in DB (have a unique ID for each file and path) to get rid of nationnal character
  // mess in URLS.
  $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'] = url('filebrowser/download/' . $record['fid'], array(
          'absolute' => TRUE,
        ));
      }
    }
  }

  // A quick way to drip obsolete records (FIXME not quite sure there is no limit in the number of
  // items in the list
  if (count($to_delete)) {
    db_query("DELETE FROM {node_dir_listing_content} WHERE fid IN (" . implode(",", $to_delete) . ")");
  }

  // Cache update
  // FIXME : what of two nodes point to the same folder ?
  $cache[$relative_path] =& $files;

  // Add all this data to the node
  $node->file_listing = $files;
}