Find last child in recursive function


im trying to achieve above condition.

i have successful list parent and multi-level child title in tab title section

Now in Tab Content im trying to list content for the title listed in Tab title In Tab Content if parent have multi-level child then only last child content should display but if parent does have any child then parent content should display

But im getting content for all title parent as well as nested child here i want last child content only but if parent does have child then parent content should be displayed

how to check if parent have any child, if parent have child then display content for last child only, if parent doesn’t have child then display parent content

Code for displaying Multi-level-nested child Title in Tab Title
Working with solution provided by Drummin

$categoryMulti = array(
'categories' => array(),
'parent_cats' => array()
);   

$sql = "SELECT `id`, `parent_id`, `name`, `content` FROM categories";
$query = $conn->query($sql);
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
   $categoryMulti['categories'][$row['id']] = $row;
    $categoryMulti['parent_cats'][$row['parent_id']][] = $row['id'];
}


//title for tabs
function listCategoryTree($parent, $category)
{
    $css_class = ($parent == 0 ? "parent" : "child");   
    
    $html = '';
    if (isset($category['parent_cats'][$parent])) {
        $html .= '<ul class="im-'.$css_class.'">'."\n";
        foreach ($category['parent_cats'][$parent] as $cat_id) {
            if (!isset($category['parent_cats'][$cat_id])) {
                $html .= '<li id="">
                <a href="" data-cap= "'.$css_class.'-'.$cat_id.'">'
                 . $category['categories'][$cat_id]['name'] . 
                 '</a>';
                 '</li>'."\r";
            } else {
                $html .= '<li id="">
                 <a href="" data-cap= "'.$css_class.'-'.$cat_id.'">'


                . $category['categories'][$cat_id]['name'] . 

                '</a> <span>arrow icon </span>'."\r";
                $html .= listCategoryTree($cat_id, $category);
                $html .= '</li>'."\r";
            }
        }
        $html .= '</ul>'."\n";
    }
    return $html;
}

ode trying to display last child content if parent have multi-level-nested child and if parent does have any child display parent content but its display content for all nested-child and parent content too.

//content for tabs
$contentTab = array(
    'contentCat' => array(),
    'contentChild' => array()
);   
$sql = "SELECT `id`, `parent_id`, `name`, `content` FROM categories";
$query = $conn->query($sql);
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
   $contentTab['contentCat'][$row['id']] = $row;
    $contentTab['contentChild'][$row['parent_id']][] = $row['id'];
}

function listContentTree($parent, $category)
{
    $css_class = ($parent == 0 ? "parent" : "child");   
    
    $html = '';
    if (isset($category['contentChild'][$parent])) {
        $html .= '<ul class="im-'.$css_class.'">'."\n";
        foreach ($category['contentChild'][$parent] as $cat_id) {
            if (!isset($category['contentChild'][$cat_id])) {
                $html .= '<li id="'.$css_class.'-'.$cat_id.'">
                <a href="" data-cap= "">im child content test---'
                 . $category['contentCat'][$cat_id]['content'] . 
                 '</a>';
                 '</li>'."\r";
            } else {
                $html .= '<li id="'.$css_class.'-'.$cat_id.'">
                 <a href="" data-cap= "">hello parent test------'


                . $category['contentCat'][$cat_id]['content'] . 

                '</a>'."\r";
                $html .= listContentTree($cat_id, $category);
                $html .= '</li>'."\r";
            }
        }
        $html .= '</ul>'."\n";
    }
    return $html;
}

how check to for last child.

if(has last child){
//multi-level child if its 4level nested child then only 4th(last child) content should display
  then display content of last child
}else{
//where parent doesn't have any child
  display content of parent
}
1 Like

Looking at this list where all content is shown you can see that the last child might not be a deepest child in the tree.
contenttree1

Attempting to apply your condition to the list you might wish to keep only this content.
contenttree2
Using your condition I am not even sure if you would want “Second Sub Child No.3” shown as there is a THIRD Sub Child in this Parent No.2 line.

The result of this list butchering would be an improper <ul> <li> list.
At the moment I am not sure what the best approach would be.

3 Likes

I suppose this is close to what you are looking for as it doesn’t show the parent if it has a child but doesn’t address the last child issue.

function listContentTree($parent, $category)
{
    $css_class = ($parent == 0 ? "parent" : "child");   
    
    $html = '';
    if (isset($category['parent_cats'][$parent])) {
        $html .= '<ul class="im-'.$css_class.'">'."\n";
        foreach ($category['parent_cats'][$parent] as $cat_id) {
            if (!isset($category['parent_cats'][$cat_id])) {
                $html .= '<li id="'.$css_class.'-'.$cat_id.'">' . $category['categories'][$cat_id]['content'] . '</li>'."\r";
            } else {
                //$html .= '<li id="'.$css_class.'-'.$cat_id.'">' . $category['categories'][$cat_id]['content'] . "\r";
                $html .= listContentTree($cat_id, $category);
                //$html .= '</li>'."\r";
            }
        }
        $html .= '</ul>'."\n";
    }
    return $html;
} 
echo listContentTree(0, $categoryMulti);

contenttree3

2 Likes

In this version I looped through our data arrays to define which ids we would display and placed them in a new subcategory called displayids.

$categoryMulti = array(
    'categories' => array(),
    'parent_cats' => array(),
	'displayids' => array()
);	 
$sql = "SELECT `id`, `parent_id`, `title`, `content` FROM categories";
$query = $conn->query($sql);
while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
    $categoryMulti['categories'][$row['id']] = $row;
    $categoryMulti['parent_cats'][$row['parent_id']][] = $row['id'];
}


foreach($categoryMulti['categories'] as $cat_id => $arr):
	if($arr['parent_id'] == 0 && !array_key_exists($cat_id,$categoryMulti['parent_cats'])):
		$categoryMulti['displayids'][] = $cat_id;
	endif; 
endforeach;

foreach($categoryMulti['parent_cats'] as $parent => $arr):
	if(!in_array(end($arr),$categoryMulti['displayids']) && !array_key_exists(end($arr),$categoryMulti['parent_cats'])):
		$categoryMulti['displayids'][]  = end($arr);
	endif;
endforeach;

Using my set of data I end up with 5 ids in this array.

Array
(
    [0] => 1
    [1] => 6
    [2] => 10
    [3] => 11
    [4] => 12
)

In the listContentTree function I loop through the data much like we did before but add an IF condition to see if the $cat_id is in the displayids array using

in_array($cat_id, $category['displayids'])

Notice I needed to add this a few times to encapsulate multiple lines without messing with the recursive function call.

function listContentTree($parent, $category)
{
    $css_class = ($parent == 0 ? "parent" : "child");	
	
	$html = '';
    if (isset($category['parent_cats'][$parent])) {
        $html .= '<ul class="im-'.$css_class.'">'."\n";
        foreach ($category['parent_cats'][$parent] as $cat_id) { 
		
            if (!isset($category['parent_cats'][$cat_id]) && in_array($cat_id, $category['displayids'])) {			
                $html .= '<li id="'.$css_class.'-'.$cat_id.'">' . $category['categories'][$cat_id]['content'] . '</li>'."\r";
            } else {
			  	
				if(in_array($cat_id, $category['displayids'])):
                	$html .= '<li id="'.$css_class.'-'.$cat_id.'">'."\r";
					$html .= $category['categories'][$cat_id]['content'] . ' <span><!-- arrow icon --></span>'."\r";	
				endif;
                $html .= listContentTree($cat_id, $category);
				
				if(in_array($cat_id, $category['displayids'])):
                	$html .= '</li>'."\r"; 	
				endif;
            }
        }
        $html .= '</ul>'."\n";
    }
    return $html;
} 

echo listContentTree(0, $categoryMulti);

This gives me this result.
contenttree4
Each were the last record for their level of the list tree. (See post #4)

1 Like

im writing on behalf of @esu above solution give us what we are trying to achieve,
Sir, we are grateful for your help.
We appreciate your time and effort you spend on our problems, being our Mentor and guiding us and helping us. We thank you from our hearts.

2 Likes

We have successfully achieve required content with your help. In same form we have gallery (multi-image) section, we are able enter in separate table all upload image data.

table for page content (table_name: parent_table)

id parent_id title content
1 0 im first parent id-1 im content for parent id-1
2 0 im second parent id-2 im content for second id-2
3 2 im child of second parent id-2 im content for child of second parent id-2

table for image gallery (table name: gallery)
where parent_id = id of parent_table (primary id)

gallery_id parent_id image_name image_caption
1 1 im image path for parent id-1 from table name :parent_table im image caption for parent id-1 from table name :parent_table
2 3 im image path for child of second parent id-2 im image caption for child of second parent id-2

we are storing gallery image by page id as table for page and gallery section are different.
so we are trying to enter gallery section loop inside listContentTree(0, $categoryMulti) so that we can easily get gallery by page id with page content, but we could achieve it. As we need to multi-level child too, so we need listContentTree(0, $categoryMulti) where it will gives us page content along with gallery-image from gallery table.

we have achieve simply the gallery image by page-id with code below but how can we achieve image-gallery with page content.

<?php 
     //page-table
      $data = $conn->query("SELECT * FROM parentable ORDER BY id");
      while($rows = $data->fetch(PDO::FETCH_OBJ) ):
      $gallery_id = $rows->id;
     
     //gallery-table getting page-id from page-table
     $gal = $conn->query("SELECT * FROM galimage WHERE parent_id = $gallery_id");
          while($pro = $gal->fetch(PDO::FETCH_OBJ) ):
              $gall_id = $pro->parent_id;
              $gal_image = $pro->image;
              $gal_caption = $pro->caption;
      ?>
            <img src="upload/<?php echo $gal_image; ?>.jpg" alt="gallery">
            
            <h2><?php echo $gal_caption; ?></h2>
                    
<?php endwhile;endwhile;?>  

we can retrieve gallery-image by page id.
But how can we insert this gallery section in listContentTree(0, $categoryMulti) so that we can retrieve both page content and gallery-image.

Is the table parent_table or parenttable the same table as what we were calling categories earlier in this thread? You are also calling things pages which to me is an individual record from the categories or parent_table but if it were me I would call the table pages as that it what this table holds. Any other DB table referencing the “pages” table would use a field page_id, which refers to the field id of the pages table.

Another thing to note about the code you posted is nested queries which should be avoided if at all possible.

In MHO in your code you are creating $gallery_id which doesn’t represent the value it holds. In my mind gallery_id would represent id of the galley table. Again any images for a page should have a page_id for the id of the pages` table.

Consistency of terms is important across a project so do your best name tables, fields and variables with names that make sense.
Keeping this in mind you can do a joined query of the galley table with the same table we are already grabbing content from , which I will now call pages.

$sql = "SELECT 
  p.id
, p.parent_id
, p.title
, p.content
, g.id AS 'gallery_id' 
, g.image 
, g.caption 
FROM pages p 
	LEFT JOIN gallery g 
		ON g.page_id = p.id";

After adding a few images to the gallery table and Printing the query result we can see the image and caption information.

Array
(
    [id] => 1
    [parent_id] => 0
    [title] => Parent No.1
    [content] => Content for Parent No.1
    [gallery_id] => 1
    [image] => image1.jpg
    [caption] => image1 caption
)

Array
(
    [id] => 1
    [parent_id] => 0
    [title] => Parent No.1
    [content] => Content for Parent No.1
    [gallery_id] => 2
    [image] => image2.jpg
    [caption] => image2 caption
)

Now in our previous version we defined the categories array like this placing the id as the array KEY.

$categoryMulti['categories'][$row['id']] = $row;

because both query result records (shown above with images) have the same id, the second record overwrites the first one resulting in only the last one shown.

Array
(
    [1] => Array
        (
            [id] => 1
            [parent_id] => 0
            [title] => Parent No.1
            [content] => Content for Parent No.1
            [gallery_id] => 2
            [image] => image2.jpg
            [caption] => image2 caption
        )

The most simple approach to address this would be to add a new array key called images for holding page gallery data.

$categoryMulti = array(
    'categories' => array(),
    'parent_cats' => array(),
	'displayids' => array(),
	'images' => array()
);	

Like before we will use the page id as the primary key then the gallery_id as the secondary key followed by a gallery field. Do this for the 3 fields called in the query.

	    $categoryMulti['images'][$row['id']][$row['gallery_id']]['gallery_id'] = $row['gallery_id']; 
	    $categoryMulti['images'][$row['id']][$row['gallery_id']]['image'] = $row['image']; 
	    $categoryMulti['images'][$row['id']][$row['gallery_id']]['caption'] = $row['caption'];

Because not every page will have images we should wrap this array building section in an IF condition like so.

	if(!empty($row['gallery_id'])):
	    $categoryMulti['images'][$row['id']][$row['gallery_id']]['gallery_id'] = $row['gallery_id']; 
	    $categoryMulti['images'][$row['id']][$row['gallery_id']]['image'] = $row['image']; 
	    $categoryMulti['images'][$row['id']][$row['gallery_id']]['caption'] = $row['caption']; 
	endif;

This will produce an array like this for all pages that have images. In contrast pages that do not have images will NOT have the page id in this array.

Array
(
    [1] => Array
        (
            [1] => Array
                (
                    [gallery_id] => 1
                    [image] => image1.jpg
                    [caption] => image1 caption
                )

            [2] => Array
                (
                    [gallery_id] => 2
                    [image] => image2.jpg
                    [caption] => image2 caption
                )

        )

)

Remember that first key is the page id and so it is quite simple to check if this id exists in the images array within our recursive function using

array_key_exists($cat_id,$category['images'])

exactly how you want images displayed is for another topic but I will just apply your example to what we had for content.

function listContentTree($parent, $category)
{
    $css_class = ($parent == 0 ? "parent" : "child");	
	
	$html = '';
    if (isset($category['parent_cats'][$parent])) {
        $html .= '<ul class="im-'.$css_class.'">'."\n";
        foreach ($category['parent_cats'][$parent] as $cat_id) { 
		
            if (!isset($category['parent_cats'][$cat_id]) && in_array($cat_id, $category['displayids'])) {			
                $html .= '<li id="'.$css_class.'-'.$cat_id.'">' . $category['categories'][$cat_id]['content'];
				
				if(array_key_exists($cat_id,$category['images'])): 
					foreach($category['images'][$cat_id] as $img):
						$html .= '<br /><img src="upload/'. $img['image'] .'" alt="'.$img['caption'].'" width="75" height="112" >'."\r";
						$html .= '<h2>'.$img['caption'].'</h2>'."\r";
					endforeach;
				endif; 
				
				$html .= '</li>'."\r";
            } else {
			  	
				if(in_array($cat_id, $category['displayids'])):
                	$html .= '<li id="'.$css_class.'-'.$cat_id.'">'."\r";
					$html .= $category['categories'][$cat_id]['content'] . ' <span><!-- arrow icon --></span>'."\r";
					
					if(array_key_exists($cat_id,$category['images'])):
						foreach($category['images'][$cat_id] as $img): 
							$html .= '<br /><img src="upload/'. $img['image'] .'" alt="'.$img['caption'].'" width="75" height="112">'."\r";
							$html .= '<h2>'.$img['caption'].'</h2>'."\r";
						endforeach;
					endif;
						
				endif;
                $html .= listContentTree($cat_id, $category);
				
				if(in_array($cat_id, $category['displayids'])):
                	$html .= '</li>'."\r"; 	
				endif;
            }
        }
        $html .= '</ul>'."\n";
    }
    return $html;
}

resulting in something like this.

Complete update:

$categoryMulti = array(
    'categories' => array(),
    'parent_cats' => array(),
	'displayids' => array(),
	'images' => array()
);	 
 
$sql = "SELECT 
  p.id
, p.parent_id
, p.title
, p.content
, g.id AS 'gallery_id' 
, g.image 
, g.caption 
FROM pages p 
	LEFT JOIN gallery g 
		ON g.page_id = p.id";

$query = $conn->query($sql);

while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
    $categoryMulti['categories'][$row['id']] = $row; 
	if(!empty($row['gallery_id'])):
	    $categoryMulti['images'][$row['id']][$row['gallery_id']]['gallery_id'] = $row['gallery_id']; 
	    $categoryMulti['images'][$row['id']][$row['gallery_id']]['image'] = $row['image']; 
	    $categoryMulti['images'][$row['id']][$row['gallery_id']]['caption'] = $row['caption']; 
	endif; 
    $categoryMulti['parent_cats'][$row['parent_id']][$row['id']] = $row['id'];
}


foreach($categoryMulti['categories'] as $cat_id => $arr):
	if($arr['parent_id'] == 0 && !array_key_exists($cat_id,$categoryMulti['parent_cats'])):
		$categoryMulti['displayids'][] = $cat_id;
	endif; 
endforeach;	

foreach($categoryMulti['parent_cats'] as $parent => $arr):
	if(!in_array(end($arr),$categoryMulti['displayids']) && !array_key_exists(end($arr),$categoryMulti['parent_cats'])):
		$categoryMulti['displayids'][]  = end($arr);
	endif;
endforeach;	

function listContentTree($parent, $category)
{
    $css_class = ($parent == 0 ? "parent" : "child");	
	
	$html = '';
    if (isset($category['parent_cats'][$parent])) {
        $html .= '<ul class="im-'.$css_class.'">'."\n";
        foreach ($category['parent_cats'][$parent] as $cat_id) { 
		
            if (!isset($category['parent_cats'][$cat_id]) && in_array($cat_id, $category['displayids'])) {			
                $html .= '<li id="'.$css_class.'-'.$cat_id.'">' . $category['categories'][$cat_id]['content'];
				
				if(array_key_exists($cat_id,$category['images'])): 
					foreach($category['images'][$cat_id] as $img):
						$html .= '<br /><img src="upload/'. $img['image'] .'" alt="'.$img['caption'].'" width="75" height="112" >'."\r";
						$html .= '<h2>'.$img['caption'].'</h2>'."\r";
					endforeach;
				endif; 
				
				$html .= '</li>'."\r";
            } else {
			  	
				if(in_array($cat_id, $category['displayids'])):
                	$html .= '<li id="'.$css_class.'-'.$cat_id.'">'."\r";
					$html .= $category['categories'][$cat_id]['content'] . ' <span><!-- arrow icon --></span>'."\r";
					
					if(array_key_exists($cat_id,$category['images'])):
						foreach($category['images'][$cat_id] as $img): 
							$html .= '<br /><img src="upload/'. $img['image'] .'" alt="'.$img['caption'].'" width="75" height="112">'."\r";
							$html .= '<h2>'.$img['caption'].'</h2>'."\r";
						endforeach;
					endif;
						
				endif;
                $html .= listContentTree($cat_id, $category);
				
				if(in_array($cat_id, $category['displayids'])):
                	$html .= '</li>'."\r"; 	
				endif;
            }
        }
        $html .= '</ul>'."\n";
    }
    return $html;
} 

echo listContentTree(0, $categoryMulti);

Sir, categories ealier we have been working is test version, now with your MENTORSHIP we have move to finalizing our project,above post for multi-image have been bit mess, so final project tables are as below.

Page table(is name = parent_table)

id parent_id title content
1 0 im first parent id-1 im content for parent id-1
2 0 im second parent id-2 im content for second id-2
3 2 im child of second parent id-2 im content for child of second parent id-2

Gallery tables (is name = gallery )

gid gallery_id image caption
1 0 image first parent id-1 im caption-1
2 0 image second parent id-2 im caption-2
3 2 image child of second parent id-2 im caption for child-page

Where gallery_id = id (primary key of parent_table)
We have store image in database with in gallery-table with help parent_table primary key(id), so when we pull of primay-id from parent_table, gallery will also be displayed.

Sir, your solution for image-gallery works fine, but we have small issue regarding parent which we couldnt figure it out.

In image above we can see that when we insert image-gallery for child-page it displays in serial -order. in picture primary-id 101 is child of primary-id-99 which ok. it’s displaying in Ascending order while inserting image-gallery its display as Ascending order but when we insert image-gallery in parent page, image-appears at Top-most level, in picture above we can see primary-id-103 is parent without any child which image is suppose to appear after primary id 102 but its appears at the top but its should have aapear after primary id 102 but if post parent page without image there is no issue it works according to Ascending order but if insert image-gallery in parent page is keeping appearing at top but its suppose to appear at the bottom.

Our code is as below, what did we missing:

//content for tabs
$categoryMulti = array(
    'categories' => array(),
    'parent_cats' => array(),
    'displayids' => array(),
    'images' => array()
);   
 
$sql = "SELECT 
  p.id
, p.parent_id
, p.title
, p.content
, g.gid 
, g.gallery_id
, g.image 
, g.caption 
FROM parent_table p 
    LEFT JOIN gallery g 
        ON g.gallery_id = p.id";
//where gallery_id (from gallery-table) =  id (primary-id of parent_Table)
$query = $conn->query($sql);

while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
    $categoryMulti['categories'][$row['id']] = $row; 
    $categoryMulti['parent_cats'][$row['parent_id']][$row['id']] = $row['id'];
    if(!empty($row['gid'])):
        $categoryMulti['images'][$row['id']][$row['gid']]['gid'] = $row['gid']; 
        $categoryMulti['images'][$row['id']][$row['gid']]['image'] = $row['image']; 
        $categoryMulti['images'][$row['id']][$row['gid']]['caption'] = $row['caption']; 
    endif; 
}


foreach($categoryMulti['categories'] as $cat_id => $arr):
    if($arr['parent_id'] == 0 && !array_key_exists($cat_id,$categoryMulti['parent_cats'])):
        $categoryMulti['displayids'][] = $cat_id;
    endif; 
endforeach; 

foreach($categoryMulti['parent_cats'] as $parent => $arr):
    if(!in_array(end($arr),$categoryMulti['displayids']) && !array_key_exists(end($arr),$categoryMulti['parent_cats'])):
        $categoryMulti['displayids'][]  = end($arr);
    endif;
endforeach; 

function listContentTree($parent, $category)
{
    $css_class = ($parent == 0 ? "parent" : "child");   
    
    $html = '';
    if (isset($category['parent_cats'][$parent])) {
        $html .= '<ul class="im-'.$css_class.'">'."\n";
        foreach ($category['parent_cats'][$parent] as $cat_id) { 
        
            if (!isset($category['parent_cats'][$cat_id]) && in_array($cat_id, $category['displayids'])) {          
                $html .= '<li id="'.$css_class.'-'.$cat_id.'">' . $category['categories'][$cat_id]['id'].'-'. $category['categories'][$cat_id]['content'];
                
                if(array_key_exists($cat_id,$category['images'])): 
                    foreach($category['images'][$cat_id] as $img):
                        $html .= '<br /><img src="'. $img['image'] .'" alt="'.$img['caption'].'" width="75" height="112" >'."\r";
                        $html .= '<h2>'.$img['caption'].'</h2>'."\r";
                    endforeach;
                endif; 
                
                $html .= '</li>'."\r";
            } else {
                
                if(in_array($cat_id, $category['displayids'])):
                    $html .= '<li id="'.$css_class.'-'.$cat_id.'">'."\r";
                    $html .= $category['categories'][$cat_id]['content'] . ' <span><!-- arrow icon --></span>'."\r";
                    
                    if(array_key_exists($cat_id,$category['images'])):
                        foreach($category['images'][$cat_id] as $img): 
                            $html .= '<br /><img src="'. $img['image'] .'" alt="'.$img['caption'].'" width="75" height="112">'."\r";
                            $html .= '<h2>'.$img['caption'].'</h2>'."\r";
                        endforeach;
                    endif;
                        
                endif;
                $html .= listContentTree($cat_id, $category);
                
                if(in_array($cat_id, $category['displayids'])):
                    $html .= '</li>'."\r";  
                endif;
            }
        }
        $html .= '</ul>'."\n";
    }
    return $html;
} 

//echo listContentTree(0, $categoryMulti);

Did we miss something in code…? thats why parent image-gallery in appear in top which is suppose to appear in bottom as following Ascending order

What I am wondering is why the menu tree and content tree are listed in a different order when they should be using the same query. There is no need for separate queries. As far as ordering results, just add ORDER BY to your query.

$sql = "SELECT 
  p.id
, p.parent_id
, p.title
, p.content
, g.gid
, g.gallery_id 
, g.image 
, g.caption 
FROM parent_table p 
	LEFT JOIN gallery g 
		ON g.gallery_id = p.id
ORDER BY p.id ASC";

Also note that database queries, functions, and form processing etc should in most cases be above output to the browser i.e. <html>, so the data building is done at the top of the page and in this case where your functions are building html to display from the same query result you call these 2 functions in your display section. So for the most part keep php and html separate.

(Note I saw your image caption processing post and your code needs fixing with this regard. Also just noting that your save or update coding would go above where you query the database so your update reflects the changes.)

2 Likes

We are still debuging error and refactoring code, thank you for pointing out

With displayids method its not display content for all child but its displaying last child content only.

it should have displayed content for all siblings children of id-152.
but its displaying content for last child of id-152 only which is id-155. How can we displayed content for all child…

//content for tabs
    $categoryMulti = array(
    'categories' => array(),
    'parent_cats' => array(),
    'displayids' => array(),
    'images' => array()
    );   
 
$sql = "SELECT 
  p.id
, p.parent_id
, p.title
, p.content
, g.gid 
, g.gallery_id
, g.image 
, g.caption 
FROM parentable p 
    LEFT JOIN galimage g 
        ON g.gallery_id = p.id ORDER BY p.id ASC";

$query = $conn->query($sql);

while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
    $categoryMulti['categories'][$row['id']] = $row; 
    
    if(!empty($row['gid'])):
        $categoryMulti['images'][$row['id']][$row['gid']]['gid'] = $row['gid']; 
        $categoryMulti['images'][$row['id']][$row['gid']]['image'] = $row['image']; 
        $categoryMulti['images'][$row['id']][$row['gid']]['caption'] = $row['caption']; 
    endif; 
    $categoryMulti['parent_cats'][$row['parent_id']][$row['id']] = $row['id'];
    
}

foreach($categoryMulti['categories'] as $cat_id => $arr):
    if($arr['parent_id'] == 0 && !array_key_exists($cat_id,$categoryMulti['parent_cats'])):
        $categoryMulti['displayids'][] = $cat_id;
    endif; 
endforeach; 

foreach($categoryMulti['parent_cats'] as $parent => $arr):
    if(!in_array(end($arr),$categoryMulti['displayids']) && !array_key_exists(end($arr),$categoryMulti['parent_cats'])):
        $categoryMulti['displayids'][]  = end($arr);
    endif;
endforeach; 

function listContentTree($parent, $category)
{
    $css_class = ($parent == 0 ? "parent" : "child");   
    
    $html = '';
    if (isset($category['parent_cats'][$parent])) {
        $html .= '<ul class="im-'.$css_class.'">'."\n";
        foreach ($category['parent_cats'][$parent] as $cat_id) { 
        
            if (!isset($category['parent_cats'][$cat_id]) && in_array($cat_id, $category['displayids'])) {          
                $html .= '<li id="'.$css_class.'-'.$cat_id.'">' . $category['categories'][$cat_id]['id'].'-'. $category['categories'][$cat_id]['content'];
                
                if(array_key_exists($cat_id,$category['images'])): 
                    foreach($category['images'][$cat_id] as $img):
                        $html .= '<br /><img src="'. $img['image'] .'" alt="'.$img['caption'].'" width="75" height="112" >'."\r";
                        $html .= '<h2>'.$img['caption'].'</h2>'."\r";
                    endforeach;
                endif; 
                
                $html .= '</li>'."\r";
            } else {
                
                if(in_array($cat_id, $category['displayids'])):
                    $html .= '<li id="'.$css_class.'-'.$cat_id.'">'."\r";
                    $html .= $category['categories'][$cat_id]['content'] . ' <span><!-- arrow icon --></span>'."\r";
                    
                    if(array_key_exists($cat_id,$category['images'])):
                        foreach($category['images'][$cat_id] as $img): 
                            $html .= '<br /><img src="'. $img['image'] .'" alt="'.$img['caption'].'" width="75" height="112">'."\r";
                            $html .= '<h2>'.$img['caption'].'</h2>'."\r";
                        endforeach;
                    endif;
                        
                endif;
                $html .= listContentTree($cat_id, $category);
                
                if(in_array($cat_id, $category['displayids'])):
                    $html .= '</li>'."\r";  
                endif;
            }
        }
        $html .= '</ul>'."\n";
    }
    return $html;
} 

echo listContentTree(0, $categoryMulti);

We gave a try with your old code without displayids methods its displaying all child content but if we upload multiple image then its dulpicating the content.

//content for tabs
    $contentTab = array(
    'contentCat' => array(),
    'contentChild' => array(),
    'images' => array()

    );   

        $sql = "SELECT 
  p.id
, p.parent_id
, p.title
, p.content
, g.gid 
, g.gallery_id
, g.image 
, g.caption 
FROM parentable p 
    LEFT JOIN galimage g 
        ON g.gallery_id = p.id ORDER BY p.id ASC";

        $query = $conn->query($sql);
        while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
          $contentTab['contentCat'][$row['id']] = $row;
          if(!empty($row['gid'])):
        $contentTab['images'][$row['id']][$row['gid']]['gid'] = $row['gid']; 
        $contentTab['images'][$row['id']][$row['gid']]['image'] = $row['image']; 
        $contentTab['images'][$row['id']][$row['gid']]['caption'] = $row['caption']; 
    endif; 
           $contentTab['contentChild'][$row['parent_id']][] = $row['id'];
           
        }

        
        function listContentTree($parent, $category)
        {
            $css_class = ($parent == 0 ? "parent" : "child");   
            
            $html = '';
            if (isset($category['contentChild'][$parent])) {
                //$html .= '<ul class="im-'.$css_class.'">'."\n";
                foreach ($category['contentChild'][$parent] as $cat_id) {
                    if (!isset($category['contentChild'][$cat_id])) {
                        
                        $html .= '<div id="'.$css_class.'-'.$cat_id.'" class="sub-net">' 
                        . $category['contentCat'][$cat_id]['id'].'-' 
                        . $category['contentCat'][$cat_id]['content']; 
                        //displaying image start
                        if(array_key_exists($cat_id,$category['images'])): 
                            foreach($category['images'][$cat_id] as $img):
                                $html .= '<br /><img src="upload/'. $img['image'] .'" alt="'.$img['caption'].'" width="75" height="112" >'."\r";
                                $html .= '<h2>'.$img['caption'].'</h2>'."\r";
                            endforeach;
                        endif; 
                        //displaying image ends
                        '</div>'."\r";
                    } else {
                        // $html .= '<li id="'.$css_class.'-'.$cat_id.'">' . $category['contentCat'][$cat_id]['content'] . "\r";
                        $html .= listContentTree($cat_id, $category);
                        // $html .= '</li>'."\r";
                    }
                }
                //$html .= '</ul>'."\n";
            }
            return $html;
        }   

Without displayids methods every id is generated as nested child even its parents. it is suppose to display like below:
id-1 Im parent first
-id-2 im 1st child of parent first
-id-3 im 2nd child of parent first
-id-4 im 3rd child of parent first

But it’s displaying every child nested of every child like:
id-1 Im parent first
-id-2 im 1st child of parent first
-----id-3 im 2nd child of parent first
---------id-4 im 3rd child of parent first

But 153,154 and 155 are Not the last child of 152 as requested in this thread.

2 Likes

sir, then how can we get all child …???

As for now We are getting only one child which at last, how can we get all sibling (153,154)… on displayids methods

Function without displayids methods gives all child and grand child according we have been talking about but while uploading multiple image its generating duplicates, how can we avoid duplicates while uploading multiple image.

which function method do suggest us sir… method with displayids methods or without displayids methods we are trying figure out but being new to Recursive function its seems thought

So you want every record that doesn’t have a child instead the last child.

$categoryMulti = array(
    'categories' => array(),
    'parent_cats' => array(),
	'displayids' => array(),
	'images' => array()
);	 
 
$sql = "SELECT 
  p.id
, p.parent_id
, p.title
, p.content
, g.gid
, g.gallery_id 
, g.image 
, g.caption 
FROM parent_table p 
	LEFT JOIN gallery g 
		ON g.gallery_id = p.id
ORDER BY p.id ASC";

$query = $conn->query($sql);

while ($row = $query->fetch(PDO::FETCH_ASSOC)) {
    $categoryMulti['categories'][$row['id']] = $row; 
	if(!empty($row['gallery_id'])):
	    $categoryMulti['images'][$row['id']][$row['gid']]['gid'] = $row['gid']; 
	    $categoryMulti['images'][$row['id']][$row['gid']]['image'] = $row['image']; 
	    $categoryMulti['images'][$row['id']][$row['gid']]['caption'] = $row['caption']; 
	endif; 
    $categoryMulti['parent_cats'][$row['parent_id']][$row['id']] = $row['id'];
}

foreach($categoryMulti['categories'] as $cat_id => $arr):
	if(!array_key_exists($cat_id,$categoryMulti['parent_cats'])):
		$categoryMulti['displayids'][] = $cat_id;
	endif; 
endforeach;

function listContentTree($parent, $category)
{
    $css_class = ($parent == 0 ? "parent" : "child");	
	
	$html = '';
    if (isset($category['parent_cats'][$parent])) {
        $html .= '<ul class="im-'.$css_class.'">'."\n";
        foreach ($category['parent_cats'][$parent] as $cat_id) { 
		
            if (!isset($category['parent_cats'][$cat_id]) && in_array($cat_id, $category['displayids'])) {			
                $html .= '<li id="'.$css_class.'-'.$cat_id.'">' . $category['categories'][$cat_id]['content'];
				
				if(array_key_exists($cat_id,$category['images'])): 
					foreach($category['images'][$cat_id] as $img):
						$html .= '<br /><img src="upload/'. $img['image'] .'" alt="'.$img['caption'].'" width="75" height="112" >'."\r";
						$html .= '<h2>'.$img['caption'].'</h2>'."\r";
					endforeach;
				endif; 
				
				$html .= '</li>'."\r";
            } else {
			  	
				if(in_array($cat_id, $category['displayids'])):
                	$html .= '<li id="'.$css_class.'-'.$cat_id.'">'."\r";
					$html .= $category['categories'][$cat_id]['content'] . ' <span><!-- arrow icon --></span>'."\r";
					
					if(array_key_exists($cat_id,$category['images'])):
						foreach($category['images'][$cat_id] as $img): 
							$html .= '<br /><img src="upload/'. $img['image'] .'" alt="'.$img['caption'].'" width="75" height="112">'."\r";
							$html .= '<h2>'.$img['caption'].'</h2>'."\r";
						endforeach;
					endif;
						
				endif;
                $html .= listContentTree($cat_id, $category);
				
				if(in_array($cat_id, $category['displayids'])):
                	$html .= '</li>'."\r"; 	
				endif;
            }
        }
        $html .= '</ul>'."\n";
    }
    return $html;
} 

echo listContentTree(0, $categoryMulti);

Regarding display list depth (tabbing) it is exactly where it is within the tree structure. Compare top list showing all records and the limited version. The placement of shown items is the same.
contenttree7

This version only has <ul> tags when parent == 0 so display is a simple list.

function listContentTree($parent, $category)
{
    $css_class = ($parent == 0 ? "parent" : "child");
	
	$html = '';
    if (isset($category['parent_cats'][$parent])) {
		if($parent == 0):
	        $html .= '<ul class="im-'.$css_class.'">'."\n";
		endif;
        foreach ($category['parent_cats'][$parent] as $cat_id) { 
		
            if (!isset($category['parent_cats'][$cat_id]) && in_array($cat_id, $category['displayids'])) {			
                $html .= '<li id="'.$css_class.'-'.$cat_id.'">' . $category['categories'][$cat_id]['content'];
				
				if(array_key_exists($cat_id,$category['images'])): 
					foreach($category['images'][$cat_id] as $img):
						$html .= '<br /><img src="upload/'. $img['image'] .'" alt="'.$img['caption'].'" width="75" height="112" >'."\r";
						$html .= '<h2>'.$img['caption'].'</h2>'."\r";
					endforeach;
				endif; 
				
				$html .= '</li>'."\r";
            } else {
			  	
				if(in_array($cat_id, $category['displayids'])):
                	$html .= '<li id="'.$css_class.'-'.$cat_id.'">'."\r";
					$html .= $category['categories'][$cat_id]['content'] . ' <span><!-- arrow icon --></span>'."\r";
					
					if(array_key_exists($cat_id,$category['images'])):
						foreach($category['images'][$cat_id] as $img): 
							$html .= '<br /><img src="upload/'. $img['image'] .'" alt="'.$img['caption'].'" width="75" height="112">'."\r";
							$html .= '<h2>'.$img['caption'].'</h2>'."\r";
						endforeach;
					endif;
						
				endif;
                $html .= listContentTree($cat_id, $category);
				
				if(in_array($cat_id, $category['displayids'])):
                	$html .= '</li>'."\r"; 	
				endif;
            }
        }
		if($parent == 0):
        	$html .= '</ul>'."\n"; 
		endif;
    }
    return $html;
} 

echo listContentTree(0, $categoryMulti);

This image shows both versions.
contenttree8

2 Likes

You are a wonderful teacher, leader. One Could hardly find a good Mentor like you who is always ready help juniors. It would be impossible to count all the ways you’ve helped us in our project, for your contributions and efforts. We are finally here with our complete project. Thanks for being a good mentor and for guiding us on our project. Without you we could have completed our project. We will always be thankful to you. We will always be grateful to you for your support and kindness. :heart: :heart: :heart:

2 Likes