ExpressionEngine CMS
Open, Free, Amazing

Thread

This is an archived forum and the content is probably no longer relevant, but is provided here for posterity.

The active forums are here.

HTree Hierarchial Model

May 07, 2008 3:57am

Subscribe [6]
  • #1 / May 07, 2008 3:57am

    Lone's avatar

    Lone

    350 posts

    We have decided to release one of our own major libraries (well model in this case) to all of the great CodeIgniter coders out there so we can give back to the community here and help some others save a heap of time.

    We needed a class that would retrieve a block of data with parent/child relationships from mySQL and store it in an array which correctly represents the three dimensional nature of the parent/child relationships. The class needed to also have methods for add, deleting and moving entries within and between categories.

    This model is perfect for the management of a menu for a website that has multiple or single levels of navigation.


    What is the model for?

    Essentially we want to turn this:

    PK  parent  name 
    ------------------------- 
    1   0       Animals 
    2   1       Cat

    Into this:

    Array 
    ( 
        [0] => Array 
            ( 
             [PK] => 1 
             [parent] => 0 
             [name] => Animals 
             [childs] => Array 
                            ( 
                            [0] => Array 
                                ( 
                                 [PK] => 2 
                                 [parent] => 1 
                                 [name] => Cat 
                            ) 
            ) 
    )

    And also be able to manage the data set easily as well.


    What can it do ?

    The model contains simple functions to manage the data items such as:

    $this->HModel->add_item("test item", 3); 
    $this->HModel->delete_item(53); 
    $this->HModel->move_item_down(14); 
    $this->HModel->is_item_live(21);


    How do I get it?

    Checkout our blog post for more information or below are some quick links to the code and documentation:

    Model PHP Code

    Documentation


    I need some help!

    Then feel free to reply in here or to our original blog post. Myself or David (pawz) will be more then help out or even take any suggestions on how to improve this model.

  • #2 / May 07, 2008 4:12am

    xwero

    4145 posts

    Where differs your library from the MPTtree library?

  • #3 / May 07, 2008 4:26am

    wiredesignz's avatar

    wiredesignz

    2882 posts

    It appears to be hierarchial ajacency model xwero. Rather than nested sets.

  • #4 / May 07, 2008 4:35am

    Lone's avatar

    Lone

    350 posts

    The key difference I can see is the database structure as ours uses the ‘Adjacency List’ method as opposed to the Nested Set approach (http://dev.mysql.com/tech-resources/articles/hierarchical-data.html)

    We preferred this method as the data in the DB in our opinions is still easy to understand as opposed to using right and left columns - especially when all we are using this for is the menu output on our client’s sites.

    The biggest concern people see with using this method instead of the Nested Sets method is the extra processing time it can use when used on a large hierarchical structure. I dont know the exact difference but in our opinions it should be unnoticeable for most menu structures that are only two levels deep and say under 50 items - I would be interested to test this out though!.

    But this being said we use a ‘Cache’ feature in our own system that saves the menu cache upon any changes on the management side and when the menu is shown on a website it just uses the menu cache which is just one sql query (and a serialized array) - removing any need to worry about performance issues.

    http://lab.pxwebdesign.com.au/releases/htree/guide/#otherfeatures


    Although I don’t know customisable MPTtree is I can mention that you can name your DB fields whatever you please for this model along with being able to specify additional fields to be selected when extracting items from the DB (look for attribute_fields in the documentation).

  • #5 / May 07, 2008 1:41pm

    m4rw3r's avatar

    m4rw3r

    647 posts

    Personally I think MPTtree is very customizable, you can call your field names whatever you want (but there are defaults, if you want), and any number of columns is accepted (it extracts all by default, but you can use the ActiveRecord “helpers” to filter columns/rows/etc. in database).
    MPTtree also supports ORM (and relational ORM through IgnitedRecord, which I can improve some).
    One thing I think is nice is my get_descendants() function, it returns an array with all records and can return them with a level column (good if you don’t want to use recursion).
    I have not implemented any type of cache system (a small one in the ORM, only for current request (not in IgnitedRecord)), which I think is better because then the “user” can implement his own, for example caching a generated menu.

    One disadvantage is that MPTtree only has support for MySQL (as far as I know, the queries are made for MySQL), but the Adjacency model have got easier queries so I guess db compatibility will be easier to achieve there.

    One thing you might consider is renaming the table property, it will probably overwrite the table lib from CI.

    A benchmark would be nice, I haven’t made one myself (if you want, you can use both the “standard” methods and the ORM, but I don’t think it would be much difference between them (as long as I didn’t screw up somewhere)).

    (BTW. one child, many children)

  • #6 / May 27, 2008 12:40pm

    Auro

    3 posts

    Hey, it is nice class and very easy to implement.

    One thing I found missing is that I am unable to flattern an array of
    3 or more levels using example provided in documentation, I have spent whole day to fix that, but without luck:(

    anyway - I still love this code, thanks.

  • #7 / May 27, 2008 7:53pm

    Lone's avatar

    Lone

    350 posts

    We haven’t atually done up to three levels (yet) but I would imagine its just a case of adding another loop within the first one for sub items?

  • #8 / May 27, 2008 9:24pm

    tobben's avatar

    tobben

    94 posts

    But can’t all this be done without the query in a recuring (!?) recursion event.

    If im not mistaking by something like:

    function index()
        {    
            $query = $this->db->get('menu');
    
            foreach ($query->result() as $row)
            {
                $menu_array[$row->id] = array('name' => $row->slug,'parent' => $row->parent);
            }
    
            $this->_generate_menu($menu_array, 0);
        }
    
        function _generate_menu($arr, $parent)
        {    
            $has_childs = false;
    
            foreach($arr as $key => $value)
            {
                if ($value['parent'] == $parent) 
                {       
                    if ($has_childs === false)
                    {
                        $has_childs = true;
    
                        echo '<ul>';
                    }
    
                    echo '<li><a href="/url/"> . '" title=""]' . $value['name'] . '</a>';
    
                    $this->_generate_menu($arr, $key);
    
                    echo '</li>';
                }
    
            }
    
            if ($has_childs === true) echo '</ul>';
        }
  • #9 / May 27, 2008 9:51pm

    Lone's avatar

    Lone

    350 posts

    tobben: That is a good way of outputing the menu and we hope to further enhance this model with suggestions like this

    What this model’s real aim is to make the management of a Hierachial Tree easier more then the output of a menu array etc.

    Things like deleting an item in the middle of an ordered section where everything needs to be reordered and moving items up and down in an order.

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases