? LICENSE.txt
? filebrowser.mysql
Index: README.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filebrowser/README.txt,v
retrieving revision 1.1
diff -u -r1.1 README.txt
--- README.txt	1 Feb 2005 17:29:19 -0000	1.1
+++ README.txt	22 Feb 2005 19:19:41 -0000
@@ -19,18 +19,19 @@
 ------------------------------------------------------------------------------
  
   - Copy filebrowser.module to your Drupal modules folder
+  - Install the database table defined in filebrowser.mysql
   - Enable the module as usual on Drupal's admin page
   - Provide the module settings on the administration >> settings >> filebrowser page
  
 Configuration
 ------------------------------------------------------------------------------
 
-  - You need to provide a root folder for filebrowser, from where the
-    folder lists will be generated.
   - The icon folder should have icons for file types used. The icons
     should be named file-txt.png, file-gif.png, etc. The default
-	icon used is file-default.png if an icon is not present for 
-	a particular file extension.
+    icon used is file-default.png if an icon is not present for 
+    a particular file extension.
+  - You need to create 'filebrowser directory' nodes and provide a root folder
+    for each one, from where the folder lists will be generated.
 
 Description file format, and custom format parsing
 ------------------------------------------------------------------------------
@@ -40,6 +41,7 @@
 
 README.txt         Detailed information about the project
 filebrowser.module Module source code
+filebrowser.mysql  Database table definition for nodes
 
 Multiple descriptions for a file are concatenated into one. You can also
 have help for a folder, (which is displayed as Drupal help text) with
@@ -112,4 +114,7 @@
 
 This module was created for the Hungarian Drupal Homepage as a browser
 for our local Subversion repository, where we work on the interface
-translations. The author of the module is Gabor Hojtsy (goba[at]php.net).
\ No newline at end of file
+translations. The author of the module is Gabor Hojtsy (goba[at]php.net).
+This module was node-ified by Mark Howell (mark(a_t)nullcraft.org) to function
+as a client-facing extranet where files could be easily shared and node_access
+permissions could be applied to different browsing directories.
\ No newline at end of file
Index: filebrowser.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/filebrowser/filebrowser.module,v
retrieving revision 1.1
diff -u -r1.1 filebrowser.module
--- filebrowser.module	1 Feb 2005 17:29:19 -0000	1.1
+++ filebrowser.module	22 Feb 2005 19:19:41 -0000
@@ -3,6 +3,15 @@
 /**
  * @file
  * Enables users with appropriate permissions to browse a folder of files (FTP-like).
+ * 
+ * Table structure:
+ * @code
+ * create table filebrowser (
+ *     nid int(10) unsigned NOT NULL default '0',
+ *     filebrowser_root varchar(255) NOT NULL default '',
+ *     PRIMARY KEY  (nid)
+ *   )
+ * @endcode
  */
 
 /**
@@ -17,6 +26,8 @@
     switch ($section) {
       case 'admin/modules#description':
         return t('Provides FTP-like browsing capabilities.');
+      case 'node/add#filebrowser':
+        return t('Shared directory for browsing files.');
       case $_GET['q']:
         if ($pagehelp) {
           return $pagehelp;
@@ -26,19 +37,46 @@
 }
 
 /**
- * Implementation of hook_settings().
+ * Implementation of hook_node_name().
  */
-function filebrowser_settings() {
- $output = form_textfield(t('Root directory'), 'filebrowser_root', variable_get('filebrowser_root', ''), 70, 100, 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".'));
- $output .= form_textfield(t('Icon directory'), 'filebrowser_icons', variable_get('filebrowser_icons', ''), 70, 100, 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".'));
- return $output;
+function filebrowser_node_name($node) {
+  return t('filebrowser directory');
+}
+
+/**
+ * Implementation of hook_access().
+ */
+function filebrowser_access($op, $node) {
+  global $user;
+
+  if ($op == 'create') {
+    // Only users with permission to do so may create this node type.
+    return user_access('create filebrowser node');
+  }
+
+  // Users who create a node may edit or delete it later, assuming they have the
+  // necessary permissions.
+  if ($op == 'update' || $op == 'delete') {
+    if (user_access('edit own filebrowser nodes') && ($user->uid == $node->uid)) {
+      return TRUE;
+    }
+  }
 }
 
 /**
  * Implementation of hook_perm().
  */
 function filebrowser_perm() {
-  return array('access filebrowser');
+  return array('create filebrowser node', 'edit own filebrowser nodes', 'access filebrowser');
+}
+
+
+/**
+ * Implementation of hook_settings().
+ */
+function filebrowser_settings() {
+ $output .= form_textfield(t('Icon directory'), 'filebrowser_icons', variable_get('filebrowser_icons', ''), 70, 100, 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".'));
+ return $output;
 }
 
 /**
@@ -51,31 +89,140 @@
       'access' => user_access('access filebrowser'), 'callback' => 'filebrowser_page',
       'type' => MENU_CALLBACK);
   }
+  else {
+    $items[] = array('path' => 'node/add/filebrowser', 'title' => t('filebrowser'),
+      'access' => user_access('create filebrowser node'), 'callback' => 'node_page',
+      'type' => MENU_CALLBACK);
+  }
+
   return $items;
 }
 
 /**
+ * Implementation of hook_form().
+ */
+function filebrowser_form(&$node, &$error) {
+  $output = '';
+
+  // In order to be able to attach taxonomy terms to this node, we need
+  // to display the appropriate form elements.
+  if (function_exists('taxonomy_node_form')) {
+    $output .= implode('', taxonomy_node_form('filebrowser', $node));
+  }
+
+  $output .= form_textfield(t('Root Directory'), 'filebrowser_root', $node->filebrowser_root, 60, 128, 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".'));
+
+  return $output;
+}
+
+/**
+ * Implementation of hook_validate().
+ */
+function filebrowser_validate(&$node) {
+  if ($node->filebrowser_root) {
+    if (!(is_dir($node->filebrowser_root) && is_readable($node->filebrowser_root))) {
+      form_set_error('filebrowser_root', t('Filebrowser Root Directory must exist and be readable by the web server.'));
+    }
+  }
+  elseif ($_POST['edit']) {
+    form_set_error('filebrowser_root', t('Filebrowser Root Directory must be specified.'));
+  }
+}
+
+/**
+ * Implementation of hook_insert().
+ */
+function filebrowser_insert($node) {
+  db_query("INSERT INTO {filebrowser} (nid, filebrowser_root) VALUES (%d, '%s')", $node->nid, $node->filebrowser_root);
+}
+
+/**
+ * Implementation of hook_update().
+ */
+function filebrowser_update($node) {
+  db_query("UPDATE {filebrowser} SET filebrowser_root = '%s' WHERE nid = %d", $node->filebrowser_root, $node->nid);
+}
+
+/**
+ * Implementation of hook_delete().
+ */
+function filebrowser_delete($node) {
+  db_query('DELETE FROM {filebrowser} WHERE nid = %d', $node->nid);
+}
+
+/**
+ * Implementation of hook_load().
+ */
+function filebrowser_load($node) {
+  $additions = db_fetch_object(db_query('SELECT filebrowser_root FROM {filebrowser} WHERE nid = %d', $node->nid));
+  return $additions;
+}
+
+/**
+ * Implementation of hook_view().
+ *
+ * This is a typical implementation that simply runs the node text through
+ * the output filters.
+ */
+function filebrowser_view(&$node, $teaser = FALSE, $page = FALSE) {
+  if(!$teaser) {
+    $node->body = filebrowser_page($node);
+  }
+  //$node->teaser .= $node->filebrowser_root; // security risk?
+}
+
+/**
  * Prints a folder layout
  */
-function filebrowser_page() {
+function filebrowser_page($node=NULL) {
+  // load node from arg list
+  if(!is_object($node) && is_numeric($node)) {
+    $node = node_load(array('nid'=>$node));
+  }
+  elseif(!is_object($node) && is_numeric(arg(1))) {
+    $node = node_load(array('nid'=>arg(1)));
+  }
+  else {
+    $do_return = true;
+  }
+  
+  if(!node_access('view', $node)) {
+    if($do_return) {
+      return message_access();
+    }
+    else {
+      print(theme('page', message_access()));
+      return;
+    }
+  }
+  if(!$node->filebrowser_root) {
+    print theme("page", '<div>' . t('Root Directory Not Set') . '</div>', t('Root Directory Not Set'));
+    return;
+  }
+  
   // Build breadcrumb list for uplevel folders
-  $subfolder = preg_replace("!^filebrowser/*!", "", $_GET['q']);
+  if (arg(0) != 'filebrowser') {
+    $subfolder = '';
+  }
+  else {
+    $subfolder = preg_replace("!^filebrowser/[0-9]+/*!", "", $_GET['q']);
+  }
   $parts = explode("/", $subfolder);
   $breadcrumb = array();
-  $dirname = t('root');
+  $dirname = $node->title;
   if ($subfolder) {
     $dirname = array_pop($parts);
     while (count($parts)) {
-      $breadcrumb[] = l($parts[count($parts) -1], filebrowser_proper_path(join("/", $parts)));
+      $breadcrumb[] = l($parts[count($parts) -1], filebrowser_proper_path(join("/", $parts), $node));
       array_pop($parts);
     }
-    $breadcrumb[] = l(t('Filebrowser root'), 'filebrowser');
+    $breadcrumb[] = l($node->title, 'filebrowser/'.$node->nid);
   }
   $breadcrumb[] = l(t('Home'), NULL);
   
   // Get file list and generate output for this folder
   $output = '';
-  if (!($files = filebrowser_get_list($subfolder))) {
+  if (!($files = filebrowser_get_list($subfolder, $node))) {
     drupal_set_message(t('Unable to get files for this directory'));
   }
   else {
@@ -114,8 +261,18 @@
     $output .= theme("table", $headers, $files);
   }
   
+  drupal_set_breadcrumb(array_reverse($breadcrumb));
+  drupal_set_title(t('%dirname directory', array("%dirname" => $dirname)));
+  
   // Note: CSS can hook on this ID to style table elements differently
-  print theme("page", '<div id="filebrowser-page">' . $output . '</div>', t('%dirname directory', array("%dirname" => $dirname)), array_reverse($breadcrumb));
+  $output = '<div id="filebrowser-page">' . $output . '</div>';
+  
+  if($do_return) {
+    return $output;
+  }
+  else {
+    print(theme('page', $output));
+  }
 }
 
 /**
@@ -124,9 +281,9 @@
  * modification) is added, plus a metafile is parsed to gather
  * more information, if available.
  */
-function filebrowser_get_list($subfolder = '') {
-  $folder = filebrowser_safe_folder($subfolder);
-  $inroot = ($folder == variable_get('filebrowser_root', ''));
+function filebrowser_get_list($subfolder = '', $node) {
+  $folder = filebrowser_safe_folder($subfolder, $node);
+  $inroot = ($folder == $node->filebrowser_root);
   
   // Signal error in case of bogus directory name
   if (!(file_exists($folder) && is_dir($folder) && ($dir = opendir($folder)))) {
@@ -174,7 +331,7 @@
       if ($stat = stat($completepath)) {
         $icon = filebrowser_get_icon($completepath);
         if (is_dir($completepath)) {
-          $link = l("$icon $file", filebrowser_proper_path("$subfolder/$file"));
+          $link = l("$icon $file", filebrowser_proper_path("$subfolder/$file", $node));
           $size = '';
         }
         else {
@@ -196,7 +353,7 @@
       $parts = explode("/", $subfolder);
       array_pop($parts);
       $up = t('up');
-      $link = l("$icon $file &lt;$up&gt;", filebrowser_proper_path(join("/", $parts)));
+      $link = l("$icon $file &lt;$up&gt;", filebrowser_proper_path(join("/", $parts), $node));
       $details[] = array_merge(array(
         array('data' => $link, 'class' => 'filename', 'sv' => $file),
         array('data' => '', 'sv' => 0),
@@ -285,8 +442,8 @@
  * repeatedly, and try to catch and eliminate path walkback attemepts.
  * Also prevent from accessing version control system folders.
  */
-function filebrowser_safe_folder($subfolder) {
-  $folder = variable_get('filebrowser_root', '') . "/$subfolder";
+function filebrowser_safe_folder($subfolder, $node) {
+  $folder = $node->filebrowser_root . "/$subfolder";
   while (TRUE) {
     $safer = str_replace(array("\\", "../", "/.svn", "/CVS"), array("/", "", "", ""), $folder);
     if ($safer !== $folder) {
@@ -303,8 +460,8 @@
 /**
  * Allows easy path generation even if $path has a leading slash.
  */
-function filebrowser_proper_path($path) {
-  return str_replace("//", "/", "filebrowser/$path");
+function filebrowser_proper_path($path, $node) {
+  return str_replace("//", "/", "filebrowser/$node->nid/$path");
 }
 
 function filebrowser_sort_table($a, $b = NULL) {
