I AM ALMOST THERE PLEASE HELP IF YOU CAN
Lets say that I have multiple strings of files directory and files...
$files = '2021/Dec/File1.doc,
2021/Dec/File2.doc,
2021/Dec/File3.doc,
2021/Nov/File1.doc,
2021/Nov/File2.doc,
2021/Nov/File3.doc,
2021/Nov/File4.doc,
2020/Jan/File1.doc,
2020/Jan/File2.doc,
2020/Jan/File3.doc';
// Make it as an array
$files = explode(',', $files);
...First I want to split every file string and extract directories and file
$data = [];
foreach($files as $key => $file)
{
$separator = explode('/', $file); // Output: [0 => '2021', 1 => 'Dec', 2 => 'File1.doc'];
$file_name = end($separator); // Get file name as last element
array_pop($separator); // Remove file name from array
$files = [];
$files[] = [
'name' => $file_name,
'folder' => $separator,
];
$node = [];
foreach ($files as $row)
{
$node['id'] = $key;
// This is main folder (root)
if (empty($row['folder']))
{
$node['file'] = $row['name'];
$node['parent_id'] = 0;
}
else
{
// THIS IS PROBLEMATIC HOW TO NOW GET PARENT ID AND FOLDER NAME
foreach ($row['folder'] as $fkey => $frow)
{
// I NEED HERE A PARENT_ID FROM PREVIOUS CHILD AND FILE NAME OF CURRENT FOLDER
}
}
}
$data[] = $node;
}
... Now I need to get folder names and check if folder has subfolder and set parent_id = id of folder.
...How to produce this array structure from the foreach loop above?
[
[
'id' => 1,
'file' => '2021',
'parent_id' => 0, // Main folder (2021)
],
[
'id' => 2,
'file' => 'Dec',
'parent_id' => 1, // Child of 2021
],
[
'id' => 3,
'file' => 'File1.doc',
'parent_id' => 2, // Child of Dec
],
[
'id' => 4,
'file' => 'File2.doc',
'parent_id' => 2, // Child of Dec
],
[
'id' => 5,
'file' => 'File3.doc',
'parent_id' => 2, // Child of Dec
],
[
'id' => 6,
'file' => 'Nov',
'parent_id' => 1, // Child of 2021
],
[
'id' => 7,
'file' => 'File1.doc',
'parent_id' => 6, // Child of Nov
],
[
'id' => 8,
'file' => 'File2.doc',
'parent_id' => 6, // Child of Nov
],
[
'id' => 9,
'file' => 'Fil3.doc',
'parent_id' => 6, // Child of Nov
],
[
'id' => 10,
'file' => 'File4.doc',
'parent_id' => 6, // Child of Nov
],
[
'id' => 11,
'file' => '2020',
'parent_id' => 0, // Main folder (2020)
],
[
'id' => 12,
'file' => 'Jan',
'parent_id' => 11, // Child of 2020
],
[
'id' => 13,
'file' => 'File1.doc',
'parent_id' => 11, // Child of jan
],
[
'id' => 14,
'file' => 'File2.doc',
'parent_id' => 11, // Child of jan
],
[
'id' => 15,
'file' => 'File3.doc',
'parent_id' => 11, // Child of jan
],
];
Here is how final structure needs to looks like and how I plan to use recursive function to get tree-level array.
CodePudding user response:
I rewrote the code but this does the trick:
<?php
$files = '2021/Dec/File1.doc,
2021/Dec/File2.doc,
2021/Dec/File3.doc,
2021/Nov/File1.doc,
2021/Nov/File2.doc,
2021/Nov/File3.doc,
2021/Nov/File4.doc,
2020/Jan/File1.doc,
2020/Jan/File2.doc,
2020/Jan/File3.doc';
// Make it as an array
$files = explode(",\n", $files);
$out = [];
foreach ($files as $line) {
[$year, $month, $file] = explode('/', $line);
if (!$year_id = get_id($out, $year)) {
$year_id = add_value($out, $year);
}
if (!$month_id = get_id($out, $month)) {
$month_id = add_value($out, $month, $year_id);
}
add_value($out, $file, $month_id);
}
var_dump($out);
function add_value(&$out, $name, $parent_id = null)
{
$last_id = end($out)['id'] ?? 0;
$new_id = $last_id 1;
array_push($out, [
'id' => $new_id,
'file' => $name,
'parent_id' => $parent_id ?? 0,
]);
return $new_id;
}
function get_id($out, $name)
{
foreach ($out as $item) {
if ($item['file'] == $name) {
return $item['id'];
}
}
return null;
}
->
[
{
"id": 1,
"file": "2021",
"parent_id": 0
},
{
"id": 2,
"file": "Dec",
"parent_id": 1
},
{
"id": 3,
"file": "File1.doc",
"parent_id": 2
},
{
"id": 4,
"file": "File2.doc",
"parent_id": 2
},
{
"id": 5,
"file": "File3.doc",
"parent_id": 2
},
{
"id": 6,
"file": "Nov",
"parent_id": 1
},
{
"id": 7,
"file": "File1.doc",
"parent_id": 6
},
{
"id": 8,
"file": "File2.doc",
"parent_id": 6
},
{
"id": 9,
"file": "File3.doc",
"parent_id": 6
},
{
"id": 10,
"file": "File4.doc",
"parent_id": 6
},
{
"id": 11,
"file": "2020",
"parent_id": 0
},
{
"id": 12,
"file": "Jan",
"parent_id": 11
},
{
"id": 13,
"file": "File1.doc",
"parent_id": 12
},
{
"id": 14,
"file": "File2.doc",
"parent_id": 12
},
{
"id": 15,
"file": "File3.doc",
"parent_id": 12
}
]
CodePudding user response:
Hopefully this will give you required output after managing data in level wise hierarchy
<?php
$files = '
2021/Dec/File1.doc,
2021/Dec/File2.doc,
2021/Dec/File3.doc,
2021/Nov/File1.doc,
2021/Nov/File2.doc,
2021/Nov/File3.doc,
2021/Nov/File4.doc,
2020/Jan/File1.doc,
2020/Jan/File2.doc,
2020/Jan/File3.doc';
// Make it as an array
$files = explode(',', $files);
$data = [];
$autoIncreamentId = 0;
$level = [];
$parent_ids = [];
foreach($files as $key => $file)
{
$separator = explode('/', $file); // Output: [0 => '2021', 1 => 'Dec', 2 => 'File1.doc'];
$node = [];
foreach ($separator as $ind=>$row)
{
$row = trim($row);
$isDir = 1;
if (preg_match('/[^\/]*\.(doc|txt)/', $row, $o))
{
$isDir = 0;
}
//if directory already used then just pull id for child use
if($isDir && isset($level[$ind.'_'.$row])){
//maintain ids of the parent hirachy to use in child files
$node[$ind] = array(
'id'=>(int)$level[$ind.'_'.$row]
);
}else{
//add node using previous level id
$autoIncreamentId =1;
$parent_id = (int)@$node[$ind-1]['id'];
$node[$ind] = array(
'id'=>$autoIncreamentId,
'file'=> $row,
'parent_id' => $parent_id
);
//save level wise id to use in future
$level[$ind.'_'.$row] = $autoIncreamentId;
}
}
//add in data just node and ignore empty nodes
foreach($node as $item){
if(isset($item['file'])){
$data[] = $item;
}
}
}
print_r(json_encode($data));
