Reputation: 5309
I need to list folder name and sub folder name using mysql query. The depth of subfolders is unknown. That is a parent folder may have n level of sub folders. Please refer the sample folder structue below:
.
├── PHP
│ ├── Developer
│ │ ├── Junior
│ │ └── Senior
│ └── Tester
├── Java
│ └── Test Engineer
└── Android
The folder structure may vary..
My table is look like
I want to load the folder name in a select box like parent and their child manner.
PHP
Developer
Junior
Senior
Tester
Java
Test Engineer
Android
What I tried?
$fOption="";
$parentFolders = $db->query("SELECT * FROM jp_emp_folder WHERE parent_id='0' AND emp_id='".$empId."'");
while($parentRows = $db->fetch_array($parentFolders)){
$fOption .= "<option value='".$parentRows['id']."'>".$parentRows['folder_name']."</option>";
$child = $db->query("SELECT * FROM jp_emp_folder WHERE parent_id='".$parentRows['id']."' AND emp_id='".$empId."'");
while($childRows = $db->fetch_array($child)){
$fOption .= "<option value='".$childRows['id']."'>".$childRows['folder_name']."</option>";
}
}
echo $fOption;
I know this only give the 2 level folder structure. But I have n level. How can I acheive this? Please suggest..
Upvotes: 1
Views: 1221
Reputation: 614
Check this.
$all_folders = $db->query("SELECT * FROM jp_emp_folder WHERE emp_id='".$empId."'");
$array_column = array_column($all_folders, 'parent_id');
$all_parent0_dir = array_keys($array_column, "0"); //get all base folders
foreach ($all_parent0_dir as $value) {
$dir = $all_folders[$value];
echo '<option value="'.$dir['id'].'">'.$dir['foler_name'].'</option>';
$parent_id = $dir['id'];
$nodeNumber = 1;
$lastElem = FALSE;//is this last element of the folder
$nodeArray = [];//save all the nodes of the folder
while ( $parent_id != $dir['id'] || $lastElem == FALSE) {
/*************************************************************/
//get details of a specific folder
$last = 1;
$sub_dir_ids = array_keys($array_column, $parent_id);
if($sub_dir_ids)
{
$sub_dir = isset($sub_dir_ids[$nodeNumber-1])? $sub_dir_ids[$nodeNumber-1] : null;
if($sub_dir){
$res = $all_folders[$sub_dir];
echo '<option value="'.$res['id'].'">'.$res['foler_name'].'</option>';
if($res){$last = 0; }
}
}
/*************************************************************/
if($last == 1){
if($parent_id != $dir['id']){//if $parent_id didn't reach the first element (starting point)
$lastElement = array_pop($nodeArray);
$parent_id = $lastElement[0];
$nodeNumber = $lastElement[1] + 1;
}else{$lastElem = TRUE;}
}else{
$lastElem = FALSE;
array_push($nodeArray, array($parent_id,$nodeNumber));
$parent_id = $res['id'];//$parent_id for inner folder
$nodeNumber = 1;//go to next step - inner folder
}
}
}
Output
<option value="1">PHP</option>
<option value="5">DEVELOPER</option>
<option value="7">JUNIOR</option>
<option value="8">SENIOR</option>
<option value="6">TESTER</option>
<option value="2">JAVA</option>
<option value="4">TEST ENG</option>
<option value="3">ANDROID</option>
Upvotes: 0
Reputation: 54212
You can use this approach to construct your hierarchy.
Step 1: Build up the $data in PHP
$data = array();
$results = $db->query("SELECT * FROM jp_emp_folder WHERE emp_id=" . (int)$empId);
while($rows = $db->fetch_array($results)) {
$data[$row['id']] = $rows;
}
Step 2: Recursively read the $data to construct hierarchy
function readData($parent_id = 0) {
global $data; // I'm just lazy, avoid using "global"
foreach($data as $id => $item) {
if($parent_id > 0 && $item['parent_id'] != $parent_id) {
continue;
}
echo '<option value="' . $id . '">' . $item['folder_name'] . '</option>' . PHP_EOL;
unset($data[$id]); // Remove echo-ed contents
if($item['parent_id'] > 0) {
readData((int)$id);
}
}
}
readData(); // Start reading $data
which will output the following:
<option value="1">PHP</option>
<option value="2">Java</option>
<option value="3">Android</option>
<option value="4">Test Engineer</option>
<option value="5">Developer</option>
<option value="7">Junior</option>
<option value="6">Tester</option>
Upvotes: 1