0

How can I get the list of the folders inside public:// (or sites/default/files) location?

I have to show all the folder names to users, so that they can choose the subdirectory where they prefer to upload their documents.

I tried with the following code, but it returns the path together the folder name.

$directories = glob($somePath . '/*' , GLOB_ONLYDIR);

The value returned from my code is similar to the following one.

    [0] => sites/default/files//folder_name
    [1] => sites/default/files//new1
    [2] => sites/default/files//newfolder
2
  • May be this Stackoverflow question helps you.
    – NTT
    Jul 29, 2016 at 11:39
  • There is a Drupal function to get what the OP wants. So, that question could help the OP, but it would be better to teach the OP how to properly use the API Drupal makes available.
    – apaderno
    Jul 29, 2016 at 11:42

2 Answers 2

1

You can ready the directory using read() function and drupal_realpath('public://') will give you the actual path to the public files folder.

$path = drupal_realpath('public://');
$dirs = array();
// directory handle
$dir = dir($path);

while (false !== ($entry = $dir->read())) {
    if ($entry != '.' && $entry != '..') {
       if (is_dir($path . '/' .$entry)) {
            $dirs[] = $entry; 
       }
    }
}

echo '<pre>';print_r($dirs);echo '</pre>';
1

I was going to suggest to use file_scan_directory(), but it returns only files. I am then going to suggest a modified version.

function scan_for_directories($dir, $mask, $options = array()) {
  // Merge in defaults.
  $options += array(
    'nomask' => '/(\.\.?|CVS)$/',
    'recurse' => FALSE,
    'key' => 'filename',
  );

  $options['key'] = in_array($options['key'], array('uri', 'filename', 'name')) ? $options['key'] : 'uri';
  $dirs = array();
  if (is_dir($dir) && $handle = opendir($dir)) {
    while (FALSE !== ($filename = readdir($handle))) {
      if (!preg_match($options['nomask'], $filename) && $filename[0] != '.') {
        $uri = "$dir/$filename";
        $uri = file_stream_wrapper_uri_normalize($uri);
        if (is_dir($uri)) {
          if ($options['recurse']) {
            // Give priority to files in this folder by merging them in after any subdirectory files.
            $dirs = array_merge(file_scan_directory($uri, $mask, $options), $dirs);
          }
          if (preg_match($mask, $filename)) {
            $dir = new stdClass();
            $dir->uri = $uri;
            $dir->filename = $filename;
            $dir->name = pathinfo($filename, PATHINFO_FILENAME);
            $key = $options['key'];
            $dirs[$dir->$key] = $dir;
          }
        }
      }
    }

    closedir($handle);
  }

  return $dirs;
}

Call it as $dirs = scan_for_directories('public://', '/.*/'); and it will returns a list of all the directories contained in public://; call it as $dirs = scan_for_directories('public://', '/.*/', array('recurse' => TRUE));, and it will return you the directories inside over directories.
By default, the returned array has the following format.

'directory name' => object with the uri, filename, and name properties

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.