-
Re: Simple Category Tree
Bug fixes, added new function to retrieve the deepest cats easily:
function retrieve_deepest_cats_array (accept cid and cpath)
PHP Code:
<?php
/**
* Simple Category Tree
* @Version: Beta 1
* @Authour: yellow1912
* @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
*/
define ('SCT_REBUILD_TREE','true');
class simple_categories_generator{
var $category_tree = array();
var $is_deepest_cats_built = false;
var $parent_open_tag = '';
var $parent_close_tag = '';
var $child_open_tag = '';
var $child_close_tag = '';
function simple_categories_generator() {}
function init(){
if(SCT_REBUILD_TREE != 'false' || count($this->category_tree) == 0){
global $languages_id, $db;
$categories_query = "select c.categories_id, cd.categories_name, c.parent_id
from " . TABLE_CATEGORIES . " c, " . TABLE_CATEGORIES_DESCRIPTION . " cd
where c.categories_id = cd.categories_id
and c.categories_status=1
and cd.language_id = '" . (int)$_SESSION['languages_id'] . "'
order by c.parent_id, c.sort_order, cd.categories_name";
$categories = $db->Execute($categories_query);
// reset the tree first
$this->category_tree = array();
$this->is_deepest_cats_built = false;
while (!$categories->EOF) {
$this->category_tree[$categories->fields['categories_id']] = array('name' => $categories->fields['categories_name'],
'parent_id' => $categories->fields['parent_id']);
$this->category_tree[$categories->fields['categories_id']]['path'][] = $categories->fields['categories_id'];
$this->category_tree[$categories->fields['parent_id']]['sub_cats'][] = $categories->fields['categories_id'];
$categories->MoveNext();
}
// walk through the array and build sub/cPath and other addtional info needed
foreach($this->category_tree as $key => $value){
// add sub 'class' for print-out purpose
$this->category_tree[$key]['sub'] = isset($this->category_tree[$key]['sub_cats']) ? 'has_sub' : 'no_sub';
// only merge if parent cat is not 0
if(isset($this->category_tree[$key]['parent_id']) && $this->category_tree[$key]['parent_id'] > 0){
if(is_array($this->category_tree[$this->category_tree[$key]['parent_id']]['path']) && count($this->category_tree[$this->category_tree[$key]['parent_id']]['path'])> 0)
$this->category_tree[$key]['path'] = array_merge($this->category_tree[$this->category_tree[$key]['parent_id']]['path'],$this->category_tree[$key]['path']);
}
$this->category_tree[$key]['cPath'] = isset($this->category_tree[$key]['path']) ? implode('_',$this->category_tree[$key]['path']) : $key;
}
// for debugging using super global mod
// $_POST['category_tree'] = $this->category_tree;
}
}
function retrieve_categories_tree_array(){
return $this->category_tree;
}
function retrieve_deepest_cats_array($categories_id){
$categories_id = $this->_get_categories_id($categories_id);
return (isset($this->category_tree[$categories_id]['deepest_cats']) ? $this->category_tree[$categories_id]['deepest_cats'] : array());
}
// 9 is a ridiculous level already. If you go deeper than that, you have some problem with performance + structure
// Max level should be around 3
function build_category_string($parent_tag = 'div', $child_tag = 'span', $divider = '', $categories_id = 0, $max_level = 9, $include_root = false){
$categories_id = $this->_get_categories_id($categories_id);
$result = '';
// don't check if max_level = 0, since we assume store owners are not crazy enough to do that
// --> less check = faster
if(isset($this->category_tree[$categories_id])){
//
$sub = $this->category_tree[$categories_id]['sub'];
$level = 0;
$class = "level_$level $sub";
$this->_build_tags($parent_tag, $child_tag);
// check if we should include the root or only its branches
if($include_root && $categories_id > 0){
$result = sprintf($this->parent_open_tag, $class).sprintf($this->child_open_tag, $class);
$result .= $this->_build_category_string($categories_id, $level, $max_level, $divider);
$result .= $this->child_close_tag.$this->parent_close_tag;
}
else{
$result .= $this->__build_category_string($categories_id, $level, $max_level, $divider);
}
}
return $result;
}
function build_deepest_level_children(){
if(!$this->is_deepest_cats_built)
$this->_build_deepest_level_children(0);
// for debugging using super global mod
// $_POST['category_tree'] = $this->category_tree;
}
// The functions below are internal and should not be called.
function _build_category_string($categories_id, $level, $max_level, $divider){
$result = $this->_build_category_link($this->category_tree[$categories_id]['name'],$this->category_tree[$categories_id]['cPath']);
$level++;
$result .= $this->__build_category_string($categories_id, $level, $max_level, $divider);
return $result;
}
function __build_category_string($categories_id, $level, $max_level, $divider){
$result = '';
if($level < $max_level){
$sub = $this->category_tree[$categories_id]['sub'];
$class = "level_$level $sub";
if(isset($this->category_tree[$categories_id]['sub_cats'])){
$result .= sprintf($this->parent_open_tag, $class);
$count = count($this->category_tree[$categories_id]['sub_cats']);
for($i=0; $i < $count; $i++){
$sub = $this->category_tree[$this->category_tree[$categories_id]['sub_cats'][$i]]['sub'];
$class = "level_$level $sub";
$result .= sprintf($this->child_open_tag, $class).$this->_build_category_string($this->category_tree[$categories_id]['sub_cats'][$i],$level,$max_level, $divider).$this->child_close_tag;
$result .= ($i < ($count-1)) ? $divider : '';
}
$result .= $this->parent_close_tag;
}
}
return $result;
}
function _build_tags($parent_tag, $child_tag){
if(!empty($parent_tag)){
$this->parent_open_tag = "<$parent_tag class='%s'>";
$this->parent_close_tag = "</$parent_tag>";
}
else{
$this->parent_open_tag = $this->parent_close_tag = '';
}
if(!empty($child_tag)){
$this->child_open_tag = "<$child_tag class='%s'>";
$this->child_close_tag = "</$child_tag>";
}
else{
$this->child_open_tag = $this->child_close_tag = '';
}
}
function _build_category_link($categories_name, $cPath){
return '<a href="' . zen_href_link(FILENAME_DEFAULT, 'cPath=' . $cPath) . '">'.$categories_name.'</a>';
}
function _build_deepest_level_children($categories_id){
$parent_id = isset($this->category_tree[$categories_id]['parent_id']) ? $this->category_tree[$categories_id]['parent_id'] : -1;
if(isset($this->category_tree[$categories_id]['sub_cats'])){
foreach($this->category_tree[$categories_id]['sub_cats'] as $sub_cat){
// we now need to loop thru these cats, and find if they have sub_cats
$this->_build_deepest_level_children($sub_cat);
}
}
elseif($parent_id > 0){
$this->category_tree[$parent_id]['deepest_cats'][] = $categories_id;
}
if($parent_id >= 0 && isset($this->category_tree[$categories_id]['deepest_cats'])){
if(isset($this->category_tree[$parent_id]['deepest_cats']))
$this->category_tree[$parent_id]['deepest_cats'] = array_merge($this->category_tree[$parent_id]['deepest_cats'],$this->category_tree[$categories_id]['deepest_cats']);
else
$this->category_tree[$parent_id]['deepest_cats'] = $this->category_tree[$categories_id]['deepest_cats'];
}
}
function _get_categories_id($categories_id){
if(!is_int($categories_id)){
$temp = explode('_',$categories_id);
$categories_id = end($temp);
}
return $categories_id;
}
}
?>
-
Re: Simple Category Tree
Code now posted on svn, latest version can be found here:
https://svn.rubikintegration.com/zen...tegories_tree/
-
Re: Simple Category Tree
Critical bug fixed:
1 missing statement causes the class to append the tree forever if function build_deepest_level_children is used and SCT_REBUILD_TREE set to false.
-
Re: Simple Category Tree
New version updated:
-> Allow you to always display only first n level of cats, also allow you to go deeper into any branch
--> Add class 'current' to the currently selected cat (for styling purpose)
https://svn.rubikintegration.com/zen...tegories_tree/
-
Re: Simple Category Tree
Basic documentation added. This is it. Unless there is any bug found, Im not gonna work on this for a while.
GLuck with this module. I started this as something to use on my own site, then build several add-on features that may be useful for others.
-
Re: Simple Category Tree
I always notice that what one makes for ones self is never quite everyone else would like :-)
If I wanted to show the first 2 levels always, but drill down, what would need to be changed to this code which sits in the tpl_categories.php
PHP Code:
if(isset($_GET['cPath']))
$content .= $_SESSION['category_tree']->build_category_string('ul', 'li', '', $_GET['cPath'], 2);
else
$content .= $_SESSION['category_tree']->build_category_string('ul', 'li', '', 0, 2);
-
Re: Simple Category Tree
And that doesnt work for u? Link to that specific page/site where I can see it?
-
Re: Simple Category Tree
Since my site needs this function (again *_*), I added this:
The class is now also in the link
example:
Code:
<a 'class="something here" 'href="link here">category name</a>
Before you ask anything, read this:
https://svn.rubikintegration.com/zen...ies_tree/docs/
New version can be found at:
https://svn.rubikintegration.com/zen...tegories_tree/
Demo:
http://demo.rubikintegration.com/zencart/
-
Re: Simple Category Tree
Since simple category is an adapted version of css flyout, it should be able to fly as well:
http://demo.rubikintegration.com/zencart/
Certain changes needed to be made tho: the level starts from 0 instead of 1 (blah, my coding habit), and the class names are not the same.
Brief tut:
https://svn.rubikintegration.com/zen...t_menucode.txt
Special thanks to the Jade True, creator of css flyout tree for the code.
-
Re: Simple Category Tree
Very handy class! And great support. Have you ever checked to see if there is any performance over your category vs the built in?