EllisLab text mark
Advanced Search
9 of 10
9
   
MPTtree, Hieararchical trees in a database table
Posted: 28 June 2011 09:50 AM   [ # 131 ]   [ Rating: 0 ]
Avatar
Joined: 2008-11-04
4489 posts

A node is the parent of another node if $child->lft > $parent->lft and $child->rgt < $parent->rgt.

Note that this is true for any parent of the child node, not only for the immediate parent. If you only need the immediate parent, you need to query the database, get all records where lft < $child[‘lft’], rgt > $child[‘rgt’], order ASC on rgt, and LIMIT 1 to get the parent node.

 Signature 

Me: WanWizard.eu | My company: Exite | Datamapper: DataMapper ORM <= LOOKING FOR A NEW MAINTAINER!

 
Posted: 28 June 2011 11:12 AM   [ # 132 ]   [ Rating: 0 ]
Joined: 2011-06-28
5 posts

Thank you for getting back to me so quickly. Armed with your response and the fact that while generating the menu I am aware what the current page is, I was able to use the current page’s lft and rgt values against the node I was outputting like so:

if ($current['lft'>= $node['lft'&& $current['rgt'<= $node['rgt']{
   $classes[] 
'active';

This seems to be working and I’m now trying hard to understand the logic.

The only down side is that all of the nodes are children of “Home” and so on every page “Home” is also highlighted. I’ve put a temporary hack in place until I can think of a better solution.

 
Posted: 28 June 2011 12:13 PM   [ # 133 ]   [ Rating: 0 ]
Avatar
Joined: 2008-11-04
4489 posts

Since you’re storing the result in an array, why not loop over it, and wipe all ‘active’ entries but the last one?

 Signature 

Me: WanWizard.eu | My company: Exite | Datamapper: DataMapper ORM <= LOOKING FOR A NEW MAINTAINER!

 
Posted: 28 June 2011 12:58 PM   [ # 134 ]   [ Rating: 0 ]
Joined: 2011-06-28
5 posts

Not entirely sure I follow. A better snippet might have been…

foreach ($tree as $node{
   $classes 
= array();
   if ((
$current['lft'>= $node['lft'&& $current['rgt'<= $node['rgt']{
      $classes[] 
'active';
   
}
   $str 
.= '<li' . (count($classes) ? ' class="' implode(' '$classes) . '"' '') . '><a href="' . ($node['url']) . '">' $node['menu_title''</a>';

   if (
$CI->page_tree->count_children($node['lft']$node['rgt'])) {
      $str 
.= get_menu($CI->page_tree->get_children_where($node['lft']$node['rgt'], array('hidden' => 0'date(publish_date) <=' => date("Y-m-d"), 'show_in_menu' => 1)), $current$level+1$max_level);
   
}

   $str 
.= '</li>';
   
$i++;
 
Posted: 28 June 2011 01:28 PM   [ # 135 ]   [ Rating: 0 ]
Avatar
Joined: 2008-11-04
4489 posts

I don’t understand this code. If you have three parents, you’ll end up with ‘active active active’ in the last <li>?

Why not:

// first the direct parent node of the current node
$active false;
foreach (
$tree as $index => $node{
   
if (($current['lft'>= $node['lft'&& $current['rgt'<= $node['rgt']{
      $active 
$index;
   
}
}

foreach ($tree as $index => $node{
   $str 
.= '<li' . ($index == $active) ? ' class="active"' '') . '><a href="' . ($node['url']) . '">' $node['menu_title''</a>';

   if (
$CI->page_tree->count_children($node['lft']$node['rgt'])) {
      $str 
.= get_menu($CI->page_tree->get_children_where($node['lft']$node['rgt'], array('hidden' => 0'date(publish_date) <=' => date("Y-m-d"), 'show_in_menu' => 1)), $current$level+1$max_level);
   
}

   $str 
.= '</li>';
   
$i++;
 Signature 

Me: WanWizard.eu | My company: Exite | Datamapper: DataMapper ORM <= LOOKING FOR A NEW MAINTAINER!

 
Posted: 28 June 2011 01:42 PM   [ # 136 ]   [ Rating: 0 ]
Joined: 2011-06-28
5 posts

The code snippet is within a get_menu function, which is called recursively to process all child nodes.

If for example, you’re on page “One A” the menu output ends up looking like (I’ve removed a tags this post won’t send otherwise):

<ol>
   <
li>Home</li>
   <
li class="active">Item One
      
<ol>
         <
li class="active">One A</li>
         <
li>One B</li>   
      </
ol>
   </
li>
   <
li>Item Two</li>
   <
li>Item Three</li>
</
ol

This allows me to highlight the top level parent item “Item One” in the menu

 
Posted: 22 April 2012 08:04 PM   [ # 137 ]   [ Rating: 0 ]
Joined: 2012-04-17
1 posts

Hi to all!
I am pretty new at CI, but in the past two months I managed to learn quite a bit, and I already successfully completed two medium-size web project with this incredible framework.

This is my first serious approach at MVC pattern, and so fa I have to say that CI is really great because of his small footprint, loose dependencies and GREAT documentation.

I became interested in hyerarchical data representation in mysql, and I found this great library.

I am on CI 2.1.0, php 5.3.

I managed to adapt this 1.7.x library to work with CI 2.1 and I am currently correcting few bugs in the code, implementing some new methods and trying to implement transactions.

I am quite a newbie in (my)sql, but if I’m not wrong, it seems that this library does not play well with unstable mysql servers-connections: table locking is implemented but not transactions, and because the queries does not use the “select for update” statement, I think this library is not transaction-safe. There is risk of leaving gaps or breaking the tree if every single query is automatically auto-committed.

I am still a newbie in sql, so I didn’t want to go through an entire query rewriting to remove table locks and rewrite every query in the form of “select for update” statement, to make them transacton and concurrency safe, so I decided to remove internal table locking and manually lock-unlock the tables when calling the library and executing an updating statement. At the same time, setting an autocommit = 0, a commit/rollback and an unlock tables at the right places seems to do the trick well.

Unfortunately I have not documented my editings on mpttree code, but If you confirm me that my work is going in the right direction, I could manage to take some time to tidy up my work and post an updated-modifyed version of mpttree, 2.1.x ready and with some new functions implemented.

For example, I doubled every function making an ***_byid($id) version, because pointing a node with his lft attribute doesn’t play well with concurrency: InnoDB never assigns two identical Ids, but a $lft value intended to point a deleted node could erroneously point at a new/wrong node.. and this is obviously an unwanted behaviour.

I also tested and slightly edited the insert_sorted function, that I see it’s not documented in the manual.
This function allows to insert a node at a specified place, and to order same-level children alphabetically.
This is a GREAT feature, because this way there’s no need to alphabetically order the results of a traversing query, making for a slightly slower insert but for a super fast alphabetically ordered displaying. Great!


==> Let me know if you are interested in some contribution, but please keep in mind that I am quite a newbie in php-sql-ci, so I take no responsibility for problems or anti-patterns I may use.

Thank you smile

 
Posted: 23 April 2013 09:00 AM   [ # 138 ]   [ Rating: 0 ]
Joined: 2011-12-05
11 posts

Not sure if i am just being a spanner but I can’t find a download of this library.
I followed this url http://ellislab.com/forums/viewthread/74114/P60/#481805

That says “For all those who are asking for the 1.6-fix2 version (the latest, which was posted on CI base), here it is.” but there is no link.

Can anyone provide an updated link?

thanks
toby

 
Posted: 01 October 2013 12:36 PM   [ # 139 ]   [ Rating: 0 ]
Joined: 2011-05-30
28 posts

Where is the download link? Can’t find it anywhere

 
9 of 10
9