9

I have an array of file-path strings like this

  • videos/funny/jelloman.wmv
  • videos/funny/bellydance.flv
  • videos/abc.mp4
  • videos/june.mp4
  • videos/cleaver.mp4
  • audio/uptown.mp3
  • audio/juicy.mp3
  • fun.wmv
  • jimmy.wmv
  • herman.wmv

End goal is to get them to jsTree. I built a prototype tree from the above sample strings. check it out: http://jsfiddle.net/ecropolis/pAqas/

3
  • You should fix up the formatting... Paste all the code then use the {} button to get the indentations right. (Or indent everything 4 spaces). Commented Feb 13, 2011 at 23:12
  • 2
    I don't see the recursiveness in your structure... Commented Feb 13, 2011 at 23:23
  • The folder 'funny' is nested inside of the folder 'videos' I just nested one level but could keep going. I never can seem to figure out the fomatting! sorry. Commented Feb 14, 2011 at 0:36

3 Answers 3

16

Firstly I would create a recursive function to iterate through your directory into an array

function ReadFolderDirectory($dir,$listDir= array())
{
    $listDir = array();
    if($handler = opendir($dir))
    {
        while (($sub = readdir($handler)) !== FALSE)
        {
            if ($sub != "." && $sub != ".." && $sub != "Thumb.db")
            {
                if(is_file($dir."/".$sub))
                {
                    $listDir[] = $sub;
                }elseif(is_dir($dir."/".$sub))
                {
                    $listDir[$sub] = $this->ReadFolderDirectory($dir."/".$sub); 
                } 
            } 
        }    
        closedir($handler); 
    } 
    return $listDir;    
}

and then output the array with json_encode.

Source used from: http://www.php.net/manual/en/function.readdir.php#87733

Sign up to request clarification or add additional context in comments.

3 Comments

I have the filenames above as strings in an array. Since I'm not reading an actual directory with PHP I don't have access to functions like is_file maybe that's all I really need to get around. In my case if I split on '/' the file is the last element of the exploded string to array. (The file strings are coming from a query to Amazon S3)
@RobertPitt Trying to achieve similar result with RecursiveIterator. Thanks for any help in stackoverflow.com/questions/24121723/…
This throws an error PHP Fatal error: Uncaught Error: Using $this when not in object context
3

I was able to use this excellent solution (the bottom one posted by @Casablanca) to process the above strings into a recursive array structure. Convert array of paths into UL list

<?php
    $paths = array('videos/funny/jelloman.wmv','videos/funny/bellydance.flv','videos/abc.mp4','videos/june.mp4','videos/cleaver.mp4','audio/uptown.mp3','audio/juicy.mp3','fun.wmv', 'jimmy.wmv','herman.wmv');
    sort($paths); 
    $array = array();
    foreach ($paths as $path) {
      $path = trim($path, '/');
      $list = explode('/', $path);
      $n = count($list);

      $arrayRef = &$array; // start from the root
      for ($i = 0; $i < $n; $i++) {
        $key = $list[$i];
        $arrayRef = &$arrayRef[$key]; // index into the next level
      }
    }

    function buildUL($array, $prefix,$firstrun) {     
        $c = count($array);
      foreach ($array as $key => $value) {
            $path_parts = pathinfo($key);
            if($path_parts['extension'] != '') {
                $extension = $path_parts['extension'];
            } else {
                $extension = 'folder';
            }
            if ($prefix == '') { //its a folder
                echo ' { "data":"'.$key.'"';
            } else { //its a file
                echo '{"data" : {"title":"'.$key.'"},"attr":{"href": "'.$prefix.$key.'","id": "1239"},
                "icon": "images\/'.$extension.'-icon.gif"';
            }
            // if the value is another array, recursively build the list$key
            if (is_array($value)) {
                echo ',"children" : [ ';
                buildUL($value, "$prefix$key/",false);
            }
            echo "}";
            $c = $c-1;
            if($c != 0) {
                echo ",";
            }
      } //end foreach
     if($firstrun != true) 
      echo "]";
    }

    echo '{ "data" : [';
    buildUL($array, '',true);
    echo '] }';
?> 

1 Comment

I have down-voted you for trying to manually create a json object using nothing but concatenation, please refer to the complexity json_encode actually provides
1

I fixed the concatenation answer chosen by @Ecropolis to use arrays. His initial example helped me, but I agree with @RobertPitt that i needs a json_encode to really be properly a good solution.

  $filesArray = array('videos/funny/jelloman.wmv','videos/funny/bellydance.flv','videos/abc.mp4','videos/june.mp4','videos/cleaver.mp4','audio/uptown.mp3','audio/juicy.mp3','fun.wmv', 'jimmy.wmv','herman.wmv');
  $finalTree = $this->parseArrayToTree($filesArray);

  $finalJsonTree = json_encode($finalTree);

  function parseArrayToTree($paths) {
    sort($paths);
    $array = array();
    foreach ($paths as $path)
    {
      $path = trim($path, '/');
      $list = explode('/', $path);
      $n = count($list);

      $arrayRef = &$array; // start from the root
      for ($i = 0; $i < $n; $i++)
      {
        $key = $list[$i];
        $arrayRef = &$arrayRef[$key]; // index into the next level
      }
    }

    $dataArray = array();
    $dataArray['data'] = array();
    $dataArray['data'] = $this->buildUL($array, '');
    return $dataArray;
  }

  function buildUL($array, $prefix) {
    $finalArray = array();

    foreach ($array as $key => $value)
    {
      $levelArray = array();
      $path_parts = pathinfo($key);
      if (!empty($path_parts['extension']) && $path_parts['extension'] != '')
      {
        $extension = $path_parts['extension'];
      }
      else
      {
        if (empty($value))
        {
          $extension = "";
        }
        else if (is_array($value))
        {
          $extension = 'folder';
        }
      }

      if (is_array($value))
      { //its a folder
        $levelArray['data'] = $key;
      }
      else
      { //its a file
        $levelArray['data']['title'] = $key;
        $levelArray['attr']['href'] = $prefix . $key;
        $levelArray['attr']['id'] = $prefix . $key;
        $levelArray['icon'] = "images/" . $extension . "-icon.gif";
      }

      // if the value is another array, recursively build the list$key
      if (is_array($value))
      {
        $levelArray['children'] = $this->buildUL($value, $prefix . $key . "/");
      }

      $finalArray[] = $levelArray;
    } //end foreach

    return $finalArray;
  }

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.