Use Case:
A number of users with a higher level of access, but a moderate level of trust and skill need to be able to upload pictures used in nodes. IMCE Restricted Mode + Upload (default) solves this, but it isn't elegant or all contained in one location.

Full mode gives them too much freedom, they can put pictures anywhere, even make new folders to put them if they want. I'm using a specific directory structure to control certain image types, through a view that filters on the path. For instance if a user uploads a background to "files/buttons" instead of "files/backgrounds" this will make it impossible for the system to offer the background as an option from the view (and will could theoretically break the buttons display, which expects the images to be a certain size).

Basically I altered imce.inc to allow a third restriction option "Restricted Plus" which allows upload and delete, but doesn't allow browsing or mkdir.

The solution was easy enough that I thought I should share my changes:

--- "imce.inc"
+++ "imce.inc"
@@ -82,6 +82,7 @@ function filefield_source_imce_settings($op, $instance) {
       '#options' => array(
         0 => t('Restricted: Users can only browse the field directory. No file operations are allowed.'),
         1 => t('Full: Browsable directories are defined by <a href="!imce-admin-url">IMCE configuration profiles</a>. File operations are allowed.', array('!imce-admin-url' => url('admin/config/media/imce'))),
+        2 => t('RestrictedPlus: Users can browse the field directory, and upload to it. No other file operations are allowed.'),
       ),
       '#default_value' => isset($settings['source_imce']['imce_mode']) ? $settings['source_imce']['imce_mode'] : 0,
     );
@@ -204,9 +205,14 @@ function filefield_source_imce_page($entity_type, $bundle_name, $field_name) {
   $field = field_info_field($field_name);
 
   // Full mode
-  if (!empty($instance['widget']['settings']['filefield_sources']['source_imce']['imce_mode'])) {
+  if ( $instance['widget']['settings']['filefield_sources']['source_imce']['imce_mode'] == 1 ) {
     $conf['imce_custom_scan'] = 'filefield_source_imce_custom_scan_full';
   }
+  // Restricted Plus mode
+  else if( $instance['widget']['settings']['filefield_sources']['source_imce']['imce_mode'] == 2 ) {
+    $conf['imce_custom_scan'] = 'filefield_source_imce_custom_scan_restricted_plus';
+    $conf['imce_custom_field'] = $field + array('_uri' => file_field_widget_uri($field, $instance));
+  }
   // Restricted mode
   else {
     $conf['imce_custom_scan'] = 'filefield_source_imce_custom_scan_restricted';
@@ -306,6 +312,61 @@ function filefield_source_imce_custom_scan_restricted($dirname, &$imce) {
  }
 
 /**
+ * Scan directory and return file list, subdirectories, and total size for Restricted Mode Plus.
+ */
+function filefield_source_imce_custom_scan_restricted_plus($dirname, &$imce) {
+  $field = $GLOBALS['conf']['imce_custom_field'];
+  $root = $imce['scheme'] . '://';
+  $field_uri = $field['_uri'];
+  $is_root = $field_uri == $root;
+
+  // Process IMCE. Make field directory the only accessible one.
+  $imce['dir'] = $is_root ? '.' : substr($field_uri, strlen($root));
+  $imce['directories'] = array();
+  if (!empty($imce['perm'])) {
+    filefield_source_imce_disable_perms($imce, array('browse','upload','delete'));
+  }
+
+  // Create directory info
+  $directory = array('dirsize' => 0, 'files' => array(), 'subdirectories' => array(), 'error' => FALSE);
+
+  if (isset($field['storage']['details']['sql']['FIELD_LOAD_CURRENT'])) {
+    $storage = $field['storage']['details']['sql']['FIELD_LOAD_CURRENT'];
+    $table_info = reset($storage);
+    $table = key($storage);
+    $sql_uri = $field_uri . ($is_root ? '' : '/');
+    $query = db_select($table, 'cf');
+    $query->innerJoin('file_managed', 'f', 'f.fid = cf.' . $table_info['fid']);
+    $result = $query->fields('f')
+      ->condition('f.status', 1)
+      ->condition('f.uri', $sql_uri . '%', 'LIKE')
+      ->condition('f.uri', $sql_uri . '%/%', 'NOT LIKE')
+      ->execute();
+    foreach ($result as $file) {
+      // Get real name
+      $name = basename($file->uri);
+      // Get dimensions
+      $width = $height = 0;
+      if ($img = imce_image_info($file->uri)) {
+        $width = $img['width'];
+        $height = $img['height'];
+      }
+      $directory['files'][$name] = array(
+        'name' => $name,
+        'size' => $file->filesize,
+        'width' => $width,
+        'height' => $height,
+        'date' => $file->timestamp,
+      );
+      $directory['dirsize'] += $file->filesize;
+    }
+  }
+
+   return $directory;
+ }
+
+
+/**
  * Disable IMCE profile permissions.
  */
 function filefield_source_imce_disable_perms(&$imce, $exceptions = array()) {

Comments

Anonymous’s picture

If this works it is exactly what I am looking for -- testing it now. Thanks!