phparrayscodeignitermodel-view-controllerbreadcrumbs

Use successive database queries to get all breadcrumbs/ancestors of a given record in a CodeIgniter project


I have a database with the following structure

user_id | cat_name | cat_slug | parent_id
-------------------------------------------
1       |Tools     | tools    |     0    |
2       |Chainsaws |chainsaws |     1    |
etc...

My end goal is to essentially have an array that has a breadcrumb trail of sorts that shows the category path, it could have anywhere from no parents to 5 levels of category parenting.

I was able to kind of get what I want.. with a few errors along the way. I keep getting a Trying to get property of non-object error. Although all my other attempts at returning values have failed.

My solution outputs my (semi - desired) effect underneath the errors, and with additional category breaks ( symbolized by ">" ). I was just hoping someone could help me clean it up, because I'm at a breaking point, after going about this for a few hours with no solution.

Model

function get_parent_trail($parent_id){
    if ( $parent_id != 0 && $parent_id){
        $parent_trail = array();
        for( $i = 1; $i <= 4; $i ++ ) {
            $this -> db -> select ( '*' );
            $this -> db -> from ( 'categories' );
            $this -> db -> where ( 'cat_id' , $parent_id );
            $query = $this -> db -> get() -> row();

            array_unshift( $parent_trail, $query->cat_name ) ;
            
            $parent_id = $query->parents;
        }
        foreach( $parent_trail as $ti ) {
            if ( $ti ) {
                echo "<strong>" . $ti . "</strong> > ";
            }
        }
    } else {
        echo "<span style='color:red;'>No Parent Category</span>";
    }
}

View

<table class='admin_table'>
    <thead>
   <th>ID</th>
   <th>Name</th>
   <th>Parent</th>
"; echo "" . $cat['cat_id'] . ""; echo "" . $cat['cat_name'] . ""; echo ""; $this -> categories -> get_parent_trail( $cat['parents'] ); echo ""; echo ""; } ?>

NOTE: The '4' in the for loop doesn't need to be dynamic as I've set a hard limit of up to 5 categories, though there has been no need to go that far into sub-categories.

I also have an additional ">" at the end of my list, which I need to get rid of, I know the reason my way doesn't work, it's just the closest solution I could find for the time being.

End Result

Basically, I want my end result to look like;

With 2 'levels' of parent categories

id | name                |      slug             |        Parent(s)
-----------------------------------------------------------------------
1  | Electric Chainsaws  |   electric-chainsaws  |   Tools > Chainsaws

Solution

  • After much hair pulling and several bottles of very strong rum, I was able to finally figure this out. I'm still relatively novice at using codeigniter so my solution may have some unnecessary steps to it, but I feel obliged to share what I learned. Here is my entire function.

    function get_parent_trail($parent_id){
    
        if ( $parent_id != 0 && $parent_id){
    
            $parent_trail = array();
            $inc = 0;
    
            for( $i = 1; $i <= 4; $i ++ ) {
    
                if ( $parent_id != 0 && $parent_id){
                    $this -> db -> select ( '*' );
                    $this -> db -> from ( 'categories' );
                    $this -> db -> where ( 'cat_id' , $parent_id );
                    $query = $this -> db -> get();
                    $row = $query -> row_array();
    
                    array_unshift( $parent_trail, $row['cat_name'] ) ;
    
                    $parent_id = $row['parents'];
                } else {
                    $inc++;
                }
    
            }
    
            $popOff = array_pop($parent_trail);
    
            if ($inc > 2 ){
                echo "<span style='color:red;'>No Parent Category</span>";
            }
    
    
            $string  = '';
            foreach( $parent_trail as $ti ) {
                if ( $ti ) {
                    $string .=  $ti.' > ';
                }
            }
    
            (string) $test = substr($string, 0, -2);
            echo $test;
    
        } else {
    
            echo "<span style='color:red;'>No Parent Category</span>";
    
        }
    
    }