Forums / All Other Contributions/Addons / Simple Category Tree

Simple Category Tree

Results 1 to 20 of 249
09 Feb 2008, 19:40
#1
yellow1912 avatar

yellow1912

Totally Zenned

Join Date:
Oct 2006
Posts:
5,422
Plugin Contributions:
0

Simple Category Tree

1. Loosely based on the Flyout Category Tree mod, use one single sql to query categories, hence reduce the load on server (especially those with large number of categories)
2. Allow users to specify the parent, child tag instead of having to use ul, li
3. Allow the use of session to further reduce the load on server
4. Can build any branch of the category tree.
5. A number of users wanted to list all products in all sub-categories of a specific category, they can take advantage of this mod as well, since it stores all sub-cats of a specific cat in $tree['cat_id']['sub_cats'] array, however, it currently stores the first sub-level, so you have to write a small function to go thru the tree and gather the deepest cats (assuming you understand what I mean ^^)

I wrote this class for my own use, and have no intention to write a detailed instruction, nor provide a downloadable package, nor provide any support at all. Just think that some of you may need it, so I post the code here:

includes/classes/simple_categories_tree_generator.php
[PHP]<?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','false');
class simple_categories_generator{
var $category_tree = array();

function simple_categories_generator() {
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);

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'];
if($categories->fields['parent_id'] > 0){
$this->category_tree[$categories->fields['categories_id']]['path'] = array_merge($this->category_tree[$categories->fields['parent_id']]['path'],$this->category_tree[$categories->fields['categories_id']]['path']);
}
$this->category_tree[$categories->fields['categories_id']]['cPath'] = implode('_',$this->category_tree[$categories->fields['categories_id']]['path']);
$categories->MoveNext();
}
// add sub 'class' for print-out purpose
foreach($this->category_tree as $key => $value){
$this->category_tree[$key]['sub'] = isset($this->category_tree[$key]['sub_cats']) ? 'has_sub' : 'no_sub';
}
}
}

function build_category_string($parent_tag = 'div', $child_tag = 'span', $categories_id = 0, $include_root = false){
if(!is_int($categories_id)){
$temp = explode('_',$categories_id);
$categories_id = $temp(count($temp)-1);
}
$result = '';
$level = 0;
$sub = $this->category_tree[$categories_id]['sub'];
if(isset($this->category_tree[$categories_id])){
if($include_root && $categories_id > 0){
$result .= "<$parent_tag class='level_$level $sub'><$child_tag class='level_$level $sub'>".$this->_build_category_string($categories_id,$parent_tag,$child_tag)."</$child_tag></$parent_tag>";
}
else{
if(isset($this->category_tree[$categories_id]['sub_cats'])){
$result .= "<$parent_tag class='level_$level $sub'>";
foreach($this->category_tree[$categories_id]['sub_cats'] as $key => $value){
$sub = $this->category_tree[$value]['sub'];
$result .= "<$child_tag class='level_$level $sub'>".$this->_build_category_string($value,$parent_tag,$child_tag)."</$child_tag>";
}
$result .= "</$parent_tag>";
}
}

}
$result = str_replace(array('<>','</>'), '', $result);
return $result;
}

function _build_category_string($categories_id = 0, $parent_tag = 'div', $child_tag = 'span', $level = 0){
$result = $this->build_category_link($this->category_tree[$categories_id]['name'],$this->category_tree[$categories_id]['cPath']);
$level++;
$sub = $this->category_tree[$categories_id]['sub'];
if(isset($this->category_tree[$categories_id]['sub_cats'])){
$result .= "<$parent_tag class='level_$level $sub'>";
foreach($this->category_tree[$categories_id]['sub_cats'] as $key => $value){
$sub = $this->category_tree[$value]['sub'];
$result .= "<$child_tag class='level_$level $sub'>".$this->_build_category_string($value,$parent_tag,$child_tag, $level)."</$child_tag>";
}
$result .= "</$parent_tag>";
}
return $result;
}

function build_category_link($categories_name, $cPath){
return '<a href="' . zen_href_link(FILENAME_DEFAULT, 'cPath=' . $cPath) . '">'.$categories_name.'</a>';
}
}[/PHP]
09 Feb 2008, 19:41
#2
yellow1912 avatar

yellow1912

Totally Zenned

Join Date:
Oct 2006
Posts:
5,422
Plugin Contributions:
0

Re: Simple Category Tree

includes/auto_loaders/config.simple_categories_tree_generator.php

[PHP]<?php
/**
* ch_categories_tree_generator
* @Version:
* @Authour:
* @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
*/
if (!defined('IS_ADMIN_FLAG')) {
die('Illegal Access');
}
$autoLoadConfig[0][] = array('autoType'=>'class', 'loadFile'=> 'simple_categories_tree_generator.php');
$autoLoadConfig[180][] = array('autoType'=>'classInstantiate',
'className'=>'simple_categories_generator',
'objectName'=>'category_tree',
'checkInstantiated'=>true,
'classSession'=>true);

?>[/PHP]
10 Feb 2008, 01:45
#3
yellow1912 avatar

yellow1912

Totally Zenned

Join Date:
Oct 2006
Posts:
5,422
Plugin Contributions:
0

Re: Simple Category Tree

A version that let you specify the depth level of the tree:

i.e: To print out just all the top categories:
[PHP]
<?php
// 0 is the TOP node of the tree, and 1 is the max_level, so print only categories below 0, and go only 1 level deep.
echo $_SESSION['category_tree']->build_category_string('ul','li',0, 1);
?>[/PHP]

NOTE: Level should be greater than 0, I did not put a check there since I assume you should know what you are doing.
[PHP]<?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','false');
class simple_categories_generator{
var $category_tree = array();

function simple_categories_generator() {
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);

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'];
if($categories->fields['parent_id'] > 0){
$this->category_tree[$categories->fields['categories_id']]['path'] = array_merge($this->category_tree[$categories->fields['parent_id']]['path'],$this->category_tree[$categories->fields['categories_id']]['path']);
}
$this->category_tree[$categories->fields['categories_id']]['cPath'] = implode('_',$this->category_tree[$categories->fields['categories_id']]['path']);
$categories->MoveNext();
}
// add sub 'class' for print-out purpose
foreach($this->category_tree as $key => $value){
$this->category_tree[$key]['sub'] = isset($this->category_tree[$key]['sub_cats']) ? 'has_sub' : 'no_sub';
}
}
}

// 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', $categories_id = 0, $max_level = 9, $include_root = false){
if(!is_int($categories_id)){
$temp = explode('_',$categories_id);
$categories_id = $temp(count($temp)-1);
}
$result = '';
$level = 0;
$sub = $this->category_tree[$categories_id]['sub'];
// 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])){
if($include_root && $categories_id > 0){
$result .= "<$parent_tag class='level_$level $sub'><$child_tag class='level_$level $sub'>".$this->_build_category_string($categories_id,$parent_tag,$child_tag,$level,$max_level)."</$child_tag></$parent_tag>";
}
else{
if(isset($this->category_tree[$categories_id]['sub_cats'])){
$result .= "<$parent_tag class='level_$level $sub'>";
foreach($this->category_tree[$categories_id]['sub_cats'] as $key => $value){
$sub = $this->category_tree[$value]['sub'];
$result .= "<$child_tag class='level_$level $sub'>".$this->_build_category_string($value,$parent_tag,$child_tag,$level,$max_level)."</$child_tag>";
}
$result .= "</$parent_tag>";
}
}
$result = str_replace(array('<>','</>'), '', $result);
}
return $result;
}

function _build_category_string($categories_id = 0, $parent_tag = 'div', $child_tag = 'span', $level = 0, $max_level = 9){
$result = $this->build_category_link($this->category_tree[$categories_id]['name'],$this->category_tree[$categories_id]['cPath']);
$level++;
if($level < $max_level){
$sub = $this->category_tree[$categories_id]['sub'];
if(isset($this->category_tree[$categories_id]['sub_cats'])){
$result .= "<$parent_tag class='level_$level $sub'>";
foreach($this->category_tree[$categories_id]['sub_cats'] as $key => $value){
$sub = $this->category_tree[$value]['sub'];
$result .= "<$child_tag class='level_$level $sub'>".$this->_build_category_string($value,$parent_tag,$child_tag, $level,$max_level)."</$child_tag>";
}
$result .= "</$parent_tag>";
}
}
return $result;
}

function build_category_link($categories_name, $cPath){
return '<a href="' . zen_href_link(FILENAME_DEFAULT, 'cPath=' . $cPath) . '">'.$categories_name.'</a>';
}
}[/PHP]
10 Feb 2008, 22:00
#4
yellow1912 avatar

yellow1912

Totally Zenned

Join Date:
Oct 2006
Posts:
5,422
Plugin Contributions:
0

Re: Simple Category Tree

A new version with code improvement, and the ability to insert a delimiter between the children.
[PHP]
<?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','false');
class simple_categories_generator{
var $category_tree = array();
var $parent_open_tag = '';
var $parent_close_tag = '';
var $child_open_tag = '';
var $child_close_tag = '';
function simple_categories_generator() {
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);

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'];
if($categories->fields['parent_id'] > 0){
$this->category_tree[$categories->fields['categories_id']]['path'] = array_merge($this->category_tree[$categories->fields['parent_id']]['path'],$this->category_tree[$categories->fields['categories_id']]['path']);
}
$this->category_tree[$categories->fields['categories_id']]['cPath'] = implode('_',$this->category_tree[$categories->fields['categories_id']]['path']);
$categories->MoveNext();
}
// add sub 'class' for print-out purpose
foreach($this->category_tree as $key => $value){
$this->category_tree[$key]['sub'] = isset($this->category_tree[$key]['sub_cats']) ? 'has_sub' : 'no_sub';
}
}
}

// 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){
if(!is_int($categories_id)){
$temp = explode('_',$categories_id);
$categories_id = $temp(count($temp)-1);
}

$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_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[$value]['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>';
}
}[/PHP]
10 Feb 2008, 22:24
#5
quentinjs avatar

quentinjs

Zen Follower

Join Date:
Mar 2004
Posts:
289
Plugin Contributions:
0

Re: Simple Category Tree

This looks very cool, and might solve my problem. One question is you showed a line to show how it works, but where would someone put this within the zc files?

and I want to show the first 2 levels all the time, but still allow the user to dig in deeper in the sub cat they are interested in, will tis still allow that?
10 Feb 2008, 23:05
#6
yellow1912 avatar

yellow1912

Totally Zenned

Join Date:
Oct 2006
Posts:
5,422
Plugin Contributions:
0

Re: Simple Category Tree

1. but where would someone put this within the zc files?
--> Put it any place you want to show the navigation bar

2. and I want to show the first 2 levels all the time, but still allow the user to dig in deeper in the sub cat they are interested in, will tis still allow that?

You can, just do something like this for instance:

[PHP]<?php echo $_SESSION['category_tree']->build_category_string('ul','li','',isset($_GET['cPath'])?$_GET['cPath']:0, 2);?>
[/PHP]

The sample code above does something like this:
If cPath (categories_id) is on the link, then use that as a root, otherwise use 0 (the root of the tree).
11 Feb 2008, 08:10
#7
quentinjs avatar

quentinjs

Zen Follower

Join Date:
Mar 2004
Posts:
289
Plugin Contributions:
0

Re: Simple Category Tree

Both classes/simple_categories_tree_generator.php examples are missing the end PHP tag.

As well I've dropped both files in place, fixed the end tag, but zencart dies. Remove the auto load and all is fine again.

I should also mention I've not put in any code to actually execute the display, only added the 2 files.
11 Feb 2008, 08:12
#8
yellow1912 avatar

yellow1912

Totally Zenned

Join Date:
Oct 2006
Posts:
5,422
Plugin Contributions:
0

Re: Simple Category Tree

The forum dropped the end tags for some reason, anyway, you need to turn on strict error report to see what went wrong.

https://www.zen-cart.com/tutorials/index.php?article=82
11 Feb 2008, 09:20
#9
quentinjs avatar

quentinjs

Zen Follower

Join Date:
Mar 2004
Posts:
289
Plugin Contributions:
0

Re: Simple Category Tree

Here is what I get with the debug tool.

[11-Feb-2008 02:22:00] PHP Warning: array_merge() [<a href='function.array-merge'>function.array-merge</a>]: Argument #1 is not an array in

includes\classes\simple_categories_tree_generator.php on line 35

[11-Feb-2008 02:22:00] PHP Warning: implode() [<a href='function.implode'>function.implode</a>]: Invalid arguments passed in includes\classes\simple_categories_tree_generator.php on line 37

hope this helps.
11 Feb 2008, 09:34
#10
yellow1912 avatar

yellow1912

Totally Zenned

Join Date:
Oct 2006
Posts:
5,422
Plugin Contributions:
0

Re: Simple Category Tree

Do you see any fatal error? Warning should not be a problem

The updated code below should fix the first warning, the second warning should never happen though, weird.

[PHP]<?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','false');
class simple_categories_generator{
var $category_tree = array();
var $parent_open_tag = '';
var $parent_close_tag = '';
var $child_open_tag = '';
var $child_close_tag = '';
function simple_categories_generator() {
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);

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'];
if($categories->fields['parent_id'] > 0){
if(!isset($this->category_tree[$categories->fields['parent_id']]['path']))
$this->category_tree[$categories->fields['parent_id']]['path'] = array();
elseif(count($this->category_tree[$categories->fields['parent_id']]['path'])> 0)
$this->category_tree[$categories->fields['categories_id']]['path'] = array_merge($this->category_tree[$categories->fields['parent_id']]['path'],$this->category_tree[$categories->fields['categories_id']]['path']);
}
$this->category_tree[$categories->fields['categories_id']]['cPath'] = implode('_',$this->category_tree[$categories->fields['categories_id']]['path']);
$categories->MoveNext();
}
// add sub 'class' for print-out purpose
foreach($this->category_tree as $key => $value){
$this->category_tree[$key]['sub'] = isset($this->category_tree[$key]['sub_cats']) ? 'has_sub' : 'no_sub';
}
}
}

// 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){
if(!is_int($categories_id)){
$temp = explode('_',$categories_id);
$categories_id = $temp(count($temp)-1);
}

$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_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[$value]['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>';
}
?>
}[/PHP]
11 Feb 2008, 09:37
#11
yellow1912 avatar

yellow1912

Totally Zenned

Join Date:
Oct 2006
Posts:
5,422
Plugin Contributions:
0

Re: Simple Category Tree

Also, dont forget to clear cache/session or set define ('SCT_REBUILD_TREE','true'); when you test the new code.
Otherwise the mod will use the prebuilt tree.
11 Feb 2008, 10:12
#12
quentinjs avatar

quentinjs

Zen Follower

Join Date:
Mar 2004
Posts:
289
Plugin Contributions:
0

Re: Simple Category Tree

Okay I'm puzzled....

did the change, that message went away. Now no messages, just a blank page, even with e_strict, with the debug turned on, the display_on, etc, and nada, nothing....
11 Feb 2008, 10:13
#13
yellow1912 avatar

yellow1912

Totally Zenned

Join Date:
Oct 2006
Posts:
5,422
Plugin Contributions:
0

Re: Simple Category Tree

a link to the site?
11 Feb 2008, 10:19
#14
yellow1912 avatar

yellow1912

Totally Zenned

Join Date:
Oct 2006
Posts:
5,422
Plugin Contributions:
0

Re: Simple Category Tree

Oops *_*
11 Feb 2008, 10:24
#15
quentinjs avatar

quentinjs

Zen Follower

Join Date:
Mar 2004
Posts:
289
Plugin Contributions:
0

Re: Simple Category Tree

www.totalgarage.ca/products is the site, and just updated the files,

[11-Feb-2008 03:28:48] PHP Fatal error: Call to a member function init() on a non-object in Products\includes\autoload_func.php on line 90
11 Feb 2008, 10:25
#16
yellow1912 avatar

yellow1912

Totally Zenned

Join Date:
Oct 2006
Posts:
5,422
Plugin Contributions:
0

Re: Simple Category Tree

And is strict error turned on here?
11 Feb 2008, 10:29
#17
quentinjs avatar

quentinjs

Zen Follower

Join Date:
Mar 2004
Posts:
289
Plugin Contributions:
0

Re: Simple Category Tree

I created the /includes/local/configure.php file with the

<?php
define('STRICT_ERROR_REPORTING', true);
?>
11 Feb 2008, 10:35
#18
yellow1912 avatar

yellow1912

Totally Zenned

Join Date:
Oct 2006
Posts:
5,422
Plugin Contributions:
0

Re: Simple Category Tree

Huhm, it's weird seeing how nothing is printed out, since the class is working fine on my site (cant post link here since it's on localhost)

I just wonder why it doesnt print out any error though, weird, lol

Just to test, try putting this right below the <?php in the simple category class file:
die("blah");
I just wonder if the file is even read and executed, that's all.
If you see blah appears on the site, then you know it's read and excuted. Then you can cut that line and paste it somewhere below that, probably in the init function, and so on and so forth to see where the code stops executing.

Normally, turning on strict error report will point out where the error is right away, i dont know why it doesnt work here though.
11 Feb 2008, 10:37
#19
yellow1912 avatar

yellow1912

Totally Zenned

Join Date:
Oct 2006
Posts:
5,422
Plugin Contributions:
0

Re: Simple Category Tree

Also, below is the updated code that should fix the error with rebuild switch having no effect at all:

[PHP]
<?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 $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();
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($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'] = is_array($this->category_tree[$key]['path']) ? implode('_',$this->category_tree[$key]['path']) : $key;

}
// for debugging using super global mod
$_POST['category_tree'] = $this->category_tree;
}
}
// 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){
if(!is_int($categories_id)){
$temp = explode('_',$categories_id);
$categories_id = $temp(count($temp)-1);
}

$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_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[$value]['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>';
}
}
?>
[/PHP]


new auto loader:
[PHP]
<?php
/**
* ch_categories_tree_generator
* @Version:
* @Authour:
* @license http://www.zen-cart.com/license/2_0.txt GNU Public License V2.0
*/
if (!defined('IS_ADMIN_FLAG')) {
die('Illegal Access');
}
$autoLoadConfig[0][] = array('autoType'=>'class', 'loadFile'=> 'simple_categories_generator.php');
$autoLoadConfig[180][] = array('autoType'=>'classInstantiate',
'className'=>'simple_categories_generator',
'objectName'=>'category_tree',
'checkInstantiated'=>true,
'classSession'=>true);
$autoLoadConfig[180][] = array('autoType'=>'objectMethod',
'objectName'=>'category_tree',
'methodName' => 'init');

?>
[/PHP]
11 Feb 2008, 10:46
#20
quentinjs avatar

quentinjs

Zen Follower

Join Date:
Mar 2004
Posts:
289
Plugin Contributions:
0

Re: Simple Category Tree

die(..) worked.

I did have to change the file name in the auto loader as 'simple_categories_generator.php' was simple_categories_tree_generator.php