Revision #4 has been created by jonah on Jan 19, 2010, 5:27:11 AM with the memo:
removed breaks
Creating a database-driven hierarchical Structure combined with CMenu and superfish
[...]
At first, we create our SQL-Table containing our hierarchical data like this:
~~~
[sql]
CREATE TABLE `Hierarchy` ( <br />
`id` int(11) NOT NULL auto_increment,
<br />
`sort` int(11) NOT NULL,
<br />
`parent` int(11) default NULL,
<br />
`title` varchar(255) default NULL,
<br />
PRIMARY KEY (`id`)
) ENGINE=InnoDB[...]
~~~
$ php protected/yiic shell <br />
Yii Interactive Tool v1.1 (based on Yii v1.1.0)
<br />
Please type 'help' for help. Type 'exit' to quit.
<br />
>> model Hierarchy
<br />
>> crud Hierarchy
<br />
~~~[...]
```php
public function relations() <br />
{ <br />
{
return array(
<br />
'getparent' => array(self::BELONGS_TO, 'Hierarchy', 'parent'),
<br />
'childs' => array(self::HAS_MANY, 'Hierarchy', 'parent', 'order' => 'sort ASC'),
<br />
);
<br />
```[...]
~~~
[sql]
insert into Hierarchy (id, sort, parent, title) values(1, 0, 0, 'root'); <br />
insert into Hierarchy (id, sort, parent, title) values(2, 0, 1, 'First Entry');
<br />
insert into Hierarchy (id, sort, parent, title) values(3, 0, 1, 'Second Entry withoud Childs');
<br />
insert into Hierarchy (id, sort, parent, title) values(4, 0, 1, 'Third Entry');
<br />
insert into Hierarchy (id, sort, parent, title) values(5, 0, 3, 'Child of the third Entry');
<br />
insert into Hierarchy (id, sort, parent, title) values(6, 0, 5, 'Child of the Child of the third Entry');
<br />
insert into Hierarchy (id, sort, parent, title) values(7, 0, 1, 'Child of the first Entry');
<br />
~~~[...]
```php
$model = Hierarchy::model()->findByPk(7); <br />
$parent = $model->parent;
<br />
echo $parent->title;
<br />
// returns 'First Entry'
<br />
```[...]
```php
$model = Hierarchy::model()->findByPk(1); <br />
print_r($model->childs);
<br />
```[...]
```php
public function getListed() { <br />
$subitems = array();
<br />
if($this->childs) foreach($this->childs as $child) {
<br />
$subitems[] = $child->getListed();
<br />
} <br />
}
$returnarray = array('label' => $this->headline, 'url' => array('Hierarchy/view', 'id' => $this->id));
<br />
if($subitems != array()) $returnarray = array_merge($returnarray, array('items' => $subitems));
<br />
return $returnarray;
<br />
} <br />
}
```[...]
```php
$model = Hierarchy::model()->findByPk(1); <br />
$items[] = $model->getListed(); // note that the [] is important, otherwise CMenu will crash.
<br />
<br />
$this->widget('zii.widgets.CMenu',array(
<br />
'items'=>$items,
<br />
'htmlOptions' => array('class' => 'sf-menu') // needed for superfish integration, see below...
<br />
)); <br />
));
```[...]
~~~
[html]
<link rel="stylesheet" type="text/css" media="screen" href="superfish.css" /> <br />
<script type="text/javascript" src="hoverIntent.js"></script> // <-- optional
<br />
<script type="text/javascript" src="superfish.js">
<br />
~~~[...]
~~~
[html]
<script type="text/javascript"> <br />
<br />
$(document).ready(function(){
<br />
$("ul.sf-menu").superfish();
<br />
});
<br />
<br />
</script>
<br />
~~~
Since we have defined the class of our ul-element to be 'sf-menu', this script snippet will replace our structure with the power of superfish. Note the bunch of effects and options (like drop-shadow) you can configure with superfish.[...]
```php
$data = Hierarchy::model()->findAll('parent=:parent', array('parent' => '0')); <br />
foreach($data as $child) {
<br />
$subchilds = $child->childs;
<br />
foreach($subchilds as $subchild) {
<br />
$subchild->title = $subchild->getparent->title . "|" . $subchild->title;
<br />
$data = array_merge($data, $child->childs);
<br />
} <br />
} <br />
<br />
}
}
$rootobj = new Hierarchy;
<br />
$rootobj->id = 0;
<br />
$rootobj->title = "root level";
<br />
$root = array($rootobj);
<br />
$data = array_merge($root, $data);
<br />
if(isset($model->id) && $model->id == 1) {
<br />
echo "This is the root node and can't be moved.";
<br />
$model->parent = 0;
<br />
} <br />
}
else {
<br />
if(isset($_GET['hierarchyParent']))
<br />
echo CHtml::DropDownList('Hierarchy[parent]', $_GET['HierarchyParent'], CHtml::listData($data, 'id', 'title'));
<br />
else if($update)
<br />
echo CHtml::DropDownList('Hierarchy[parent]', $model->parent, CHtml::listData($data, 'id', 'title'));
<br />
else
<br />
echo CHtml::DropDownList('Hierarchy[parent]', 1, CHtml::listData($data, 'id', 'title'));
<br />
} <br />
}
```[...]
```php
if(isset($_GET['hierarchyParent'])) <br />
echo CHtml::DropDownList('Hierarchy[parent]', $_GET['HierarchyParent'], CHtml::listData($data, 'id', 'title'));
<br />
```[...]
```php
if(!Yii::app()->User->isguest) <br />
echo CHtml::link("Add a new element", array('Hierarchy/create', 'hierarchyParent' => $model->id));
<br />
```
Place this lines somewhere at views/Hierarchy/view.php .
I hope my small tutorial was helpful for you. There are some points that can be made even better, for example someone could change the admin CGridView to be collapsable, and the elements could be moved around by drag & drop. In the next version of this Tutorial i will use the nestedset extension to achieve the Hierarchy Structure. Thank you for reading & trying, and[...]