0

I am trying to represent the whole array returned from Amazon S3 bucket in a tree structure one can browse.

The array example is following

$files[0] = 'container/798/';
$files[1] = 'container/798/logo.png';
$files[2] = 'container/798/test folder/';
$files[3] = 'container/798/test folder/another folder/';
$files[4] = 'container/798/test folder/another folder/again test/';
$files[5] = 'container/798/test folder/another folder/test me/';
$files[6] = 'container/798/test two/';
$files[7] = 'container/798/test two/logo2.png';

and this is what i am trying to achieve

https://i.stack.imgur.com/HBjvE.png   

so far i have only achieved differing the files and folder but not on different level with parent-child relation. The above mentioned array resides in $keys['files']. The code is following

$keys = json_decode($result,true);
$folders = array();
$files = array();
$i =0;
foreach ($keys['files'] as $key){
    if(endsWith($key, "/")){
        $exploded = explode('container/'.$_SESSION['id_user'].'/',$key);
        if(!empty($exploded[1]))
        $folders[$i]['name'] = substr($exploded[1],0,-1);
    }
    else{
        $exploded = explode('container/'.$_SESSION['id_user'].'/',$key);
        $files[$i]['name'] = $exploded[1];
        $files[$i]['size'] = "";
        $files[$i]['date'] = "";
        $files[$i]['preview_icon'] = "";
        $files[$i]['dimensions'] = "";
        $files[$i]['url'] = "";
    }
    $i++;
}

This is code just to show i am trying but its not complete or accurate. I don't know how to approach a logic that can give me the hierarchy i am showing the picture. Any help would be greatly appreciated.

Shaonline
  • 1,597
  • 6
  • 18
  • 36
  • Possible duplicate of [Build a tree from a flat array in PHP](http://stackoverflow.com/questions/8840319/build-a-tree-from-a-flat-array-in-php) – B001ᛦ Feb 02 '16 at 09:15
  • There is no parent_id in my example, which makes it a bit hard for me. – Shaonline Feb 02 '16 at 11:26

1 Answers1

2

I don't know if this is the 'correct' way to do this, but if you want to make a recursive structure, then the easy way is to use a recursive function:

$root = array('name'=>'/', 'children' => array(), 'href'=>'');

function store_file($filename, &$parent){

    if(empty($filename)) return;

    $matches = array();

    if(preg_match('|^([^/]+)/(.*)$|', $filename, $matches)){

        $nextdir = $matches[1];

        if(!isset($parent['children'][$nextdir])){
            $parent['children'][$nextdir] = array('name' => $nextdir,
                'children' => array(),
                'href' => $parent['href'] . '/' . $nextdir);
        }

        store_file($matches[2], $parent['children'][$nextdir]);
    } else {
        $parent['children'][$filename] = array('name' => $filename,
            'size' => '...', 
            'href' => $parent['href'] . '/' . $filename);
    }
}

foreach($files as $file){
    store_file($file, $root);
}

Now, every element of root['children'] is an associative array that hash either information about a file or its own children array.

millinon
  • 1,528
  • 1
  • 20
  • 31
  • This is what i needed, Thank you. But now i am kinda stuck how to display it as shown in the picture. – Shaonline Feb 03 '16 at 11:06
  • Listing the files is recursive too: to list a file, first print the file's name (and metadata), then list each of the file's children. If, instead of printing, we append to a vertical layout, while keeping track of each file's depth to add indentation, we can create a hierarchical view. – millinon Feb 03 '16 at 13:30
  • I did it. Great help, Thank you. :) – Shaonline Feb 03 '16 at 13:39
  • @million I want to save the url to the folder as well in the array, just like name or size. I can't figure out how to assign the full path or url to each file or folder. Could you help me please? – Shaonline Feb 03 '16 at 15:43
  • There are a few easy ways to do that since the list of files includes the full path for each. Let's say that we want to add a `href` field to each entry. First, manually set `$root['href']` to whatever the base path or URL should be - something like `https://s3.amazonaws.com/yourbucket/...`. You can also just initialize it to an empty string to get paths instead of URLs. Now, from what we know about how paths work, whenever we create a new child entry, we can assign `$child['href']` to be its parent's path with a slash and the child's name appended. – millinon Feb 03 '16 at 16:31
  • @million Can you please take a look at this. I would really appreciate that http://stackoverflow.com/questions/35183445/how-to-keep-track-of-path-of-a-tree-array. – Shaonline Feb 03 '16 at 17:15
  • I just edited in the `href` attribute - try changing the `'href'=>''` value in `root`'s declaration. – millinon Feb 03 '16 at 22:05
  • you have been such a great help @million. Saved my life, Thank you! ;) – Shaonline Feb 04 '16 at 11:08