My Ride
Started: Thursday 20th June 2013 7:06am
Distance: 13.36km
Duration: 00:30:30
Rest Time: 00:13:55
Climb: 100m
Max Speed: 56.52kmph
Average Speed: 26.29kmphInstagrams
-
Recent Posts
Recent Comments
Archives
- February 2013
- December 2012
- September 2012
- July 2012
- January 2012
- September 2011
- August 2011
- February 2011
- January 2011
- November 2010
- October 2010
- August 2010
- June 2010
- May 2010
- April 2010
- March 2010
- February 2010
- January 2010
- December 2009
- November 2009
- October 2009
- September 2009
- August 2009
- July 2009
- June 2009
- May 2009
- April 2009
- March 2009
- February 2009
- January 2009
- December 2008
- November 2008
- October 2008
- September 2008
- August 2008
- July 2008
- June 2008
- May 2008
- April 2008
Categories
Meta
My CakePHP Category Tree Helper
April 8, 2009,
2,378 views
Hey everyone. Not so much a tutorial here, but more so a snippet of code to help some of you out. My problem was with the CakePHP tree component. The way that the tree organised data in CakePHP works is through establishing a neighbour like system, where the elements are located through analysing not only the parent and children relationships but through where each element is located according to its neighbour. The problem i found with this when it comes to categories is that CakePHP does not seem to have a way to ignore this left and right neighbour checks, and in turn order the data.
So after asking around a bit i decided to write my own method of ordering my tree data in the database, which was a Category list to be used in a select box. My helper came out to be:
/app/views/helpers/tree.php
<?php
class TreeHelper extends AppHelper {
function indentTree($array, $counter=0){
$ret = '';
$array2 = array();
$pre = '';
for($i = 1;$i < $counter; $i++){
$pre .= '--';
}
foreach($array as $key => $value){
if($key == 'children'){
if(isset($value['Category']) || (isset($value['children']) && sizeof($value['children']) > 0)){
$indented[] = $this->indentTree($value, ++$counter);
} else {
if(sizeof($value) > 0) {
$indented[] = $this->indentTree($value, $counter);
}
}
} elseif($key == 'Category'){
$indented[$value['id']] = ' '.$pre.' '.$value['name'];
} elseif(isset($value['Category']['name'])){
$indented[] = $this->indentTree($value, $counter);
}
}
return $this->flatten_array($indented, 2);
}
function flatten_array($array, $preserve_keys = 0, &$out = array()) {
foreach($array as $key => $child){
if(is_array($child)){
$out = $this->flatten_array($child, $preserve_keys, $out);
} elseif($preserve_keys + is_string($key) > 1){
$out[$key] = $child;
} else {
$out[] = $child;
}
}
return $out;
}
}
?>
To use this simply include the helper in your controller via:
var $helpers = array('Html', 'Form', 'Text', 'Javascript', 'Tree');
And then within your action you must select the data in a threaded form, the same as GenerateTreeList would do, however pre-ordered:
$categories = $this->Category->find('threaded', array('order' => array('Category.name' => 'ASC')));
$this->set('categoriesList', $categories);
Next up you use the helper in your view via:
echo $form->input('parent_id', array('type'=>'select', 'options'=>$tree->indentTree($categoriesList), 'empty'=>'--------', 'div'=>'row'));
And thats it!
For me this will return an ordered flattened array of my categories to be used within the select box!
I know this explanation is a bit low but it should be enough to get you started! If you have any questions please comment and i will see what i can do to help you out!






2 Comments
Thanks for the helper !
Very useful when the Tree & Translate behaviors are needed together.
generatetreelist doesn’t seems to work with the Translate behaviors.
Thanks, exactly what I was looking for!
I made a change to the “indentTree” funciton on my end to make it a little more re-usable with different models:
function indentTree($array, $modelName = "Category", $displayField = "name", $childField = "children", $counter=0){
$ret = '';
$array2 = array();
$pre = '';
for($i = 1;$i $value){
if($key == $childField){
if(isset($value[$modelName]) || (isset($value[$childField]) && sizeof($value[$childField]) > 0)){
$indented[] = $this->indentTree($value, $modelName, $displayField, $childField, ++$counter);
} else {
if(sizeof($value) > 0) {
$indented[] = $this->indentTree($value, $modelName, $displayField, $childField, $counter);
}
}
} elseif($key == $modelName){
$indented[$value['id']] = ' '.$pre.' '.$value[$displayField];
} elseif(isset($value[$modelName][$displayField])){
$indented[] = $this->indentTree($value, $modelName, $displayField, $childField, $counter);
}
}
return $this->flatten_array($indented, 2);
}