This generates two structures: a tree and a list of objects. Both are generated from the following standard parent/child database format:
These are two recursive functions that first build a tree structure. The second recursive function builds a sortable list of objects with their full category path as shown below:
For Cat3: Cat1 > Cat2 > Cat3
It's helpful to use a print_r on both objects to get a visual idea of what you've built.
Important Notes:
/************************************************************/
// Category Item class
class category_item
{
var $cat_id;
var $depth;
var $cat_title;
var $cat_parent_id;
var $cat_long_title;
function category_item($cat_id, $depth, $cat_title, $cat_parent_id, $cat_long_title = '')
{
$this->cat_id = $cat_id;
$this->depth = $depth;
$this->cat_title = $cat_title;
$this->cat_parent_id = $cat_parent_id;
$this->cat_long_title = $cat_long_title;
}
}
/*************************************************************/
// Builds the category list for the category select
$list = array();
function build_list($cat_array, $item = '', $depth = 0)
{
global $template;
global $list;
foreach($cat_array as $category)
{
$loop_item = "$item$category[cat_title]";
$category_item = new category_item($category[cat_id], $depth, $category[cat_title], $category[cat_parent_id], $loop_item);
$list[] = $category_item;
if(count($category[children]) > 0)
{
$depth++;
build_list($category[children], $loop_item." > ", $depth);
$depth--;
}
$loop_item = '';
}
return $list;
}
/*************************************************************/
// Adds the object to the children array of the object with
// a cat_id equal to $parent_id
function tree_add($tree, $parent_id, $object, $cat_id)
{
// Only start from the given cat_id, ignore all other roots
if($parent_id == '0' and $object[cat_id] == $cat_id)
{
$tree[$object[cat_id]] = $object;
return $tree;
}
if($tree)
{
foreach($tree as $key => $value)
{
$current = $tree[$key];
// If this is the parent, add the object to it's children array
if($current[cat_id] == $parent_id)
{
$tree[$key][children][$object[cat_id]] = $object;
}
else
{
// If it's not in this level, look a level deeper on the current object.
$tree[$key][children] = tree_add($current[children], $parent_id, $object, $cat_id);
}
}
}
return $tree;
}
/*************************************************************/
// This pulls the data from the database. This will not work without a
// database connection. This code is compatible with the phpBB2
// mySQL database class.
//
$query = "
select
*
from
categories
order by
cat_id
";
$result = $db->sql_query($query);
while($category = $db->sql_fetchrow($result))
{
$children = array();
$category[children] = $children;
$cat_id = $category[cat_id];
$cat_parent_id = $category[cat_parent_id];
$cat_tree = tree_add($cat_tree, $cat_parent_id, $category, $cat_id);
}
$cat_list = build_list($cat_tree);
I know you!
but I need to use the array like this: $cat_list[$x]['cat_title'] or $cat_list[$x]['cat_id'] for a cycle to be applied to select html option or screen printing.
I tried the solution of a double foreach, but I can not apply this example:$cat_list[$x]['cat_title'] or $cat_list[$x]['cat_id'].
can you please post a valid method? I'm really in trouble!
thanks for your time
I realise its a while since the last post but i got it working fairly easily.
I replaced -
"$query = "
select
*
from
categories
order by
cat_id
";
$result = $db->sql_query($query);
while($category = $db->sql_fetchrow($result))
{
"
with -
"$query = "
select
*
from
categories
order by
cat_id
";
$result = mysql_query($query);
while($category = @mysql_fetch_assoc($result))
{
"
My db connection is as follows;
"$dbhost = "";
$dbuname = "";
$dbpword = "";
$dbname = "";
$client_flags = 128;
$dbconnection = mysql_connect($dbhost, $dbuname, $dbpword, FALSE, $client_flags) or die("Connection Failure to Database");
mysql_select_db($dbname, $dbconnection) or die ("Database not found.");
"
I can then print_r on both arrays an get the following
print_r($cat_list);
with my sample data outputs:
Array ( [0] => category_item Object ( [cat_id] => 32 [depth] => 0 [cat_title] => Home Page (sample) [cat_parent_id] => 0 [cat_long_title] => Home Page (sample) ) [1] => category_item Object ( [cat_id] => 33 [depth] => 1 [cat_title] => test [cat_parent_id] => 32 [cat_long_title] => Home Page (sample) > test ) [2] => category_item Object ( [cat_id] => 34 [depth] => 0 [cat_title] => test2 [cat_parent_id] => 0 [cat_long_title] => test2 ) )
and print_r($cat_tree);
with my sample data outputs:
Array ( [32] => Array ( [cat_id] => 32 [cat_parent_id] => 0 [cat_title] => Home Page (sample) [home] => 0 [children] => Array ( [33] => Array ( [cat_id] => 33 [cat_parent_id] => 32 [cat_title] => test [home] => 0 [children] => Array ( ) ) ) ) [34] => Array ( [cat_id] => 34 [cat_parent_id] => 0 [cat_title] => test2 [home] => 0 [children] => Array ( ) ) )
What id like to know is how can I translate this into an
Thanks for the feedback ejgeske. I realize it's a bit confusing and difficult to implement. I wrote this years ago using the phpBB2 database class, so that explains the $db->sql_fetchrow. You have to download phpBB2 and grab the db/mysql.php and includes/db.php files to instigate the $db class. Or you could modify all the $db calls to work with your favorite database class.
There is only one table in this example. The "cat_long_title" doesn't even get used and isn't necessary at all. I'm not even sure why it made it into this snippet. The table only needs the following fields:
cat_id
cat_title
cat_parent_id
The depth is calculated in the code.
I hope this clears up any confusion and let me know if you have any luck with it.
in the following example, i will assign some variables that belong to a class. But are assigned inside one of the function/methods. If you only assign it as $example and not as $this->example, it does not assign that variable to the entire class, only in that method/function.
class myClass
{
var $example;
var $example2;
function say_what()
{
$example = 'Hi';
$this->example2 = 'Hi again';
echo '$example: '.$example."<br/>";
echo '$example2: '.$example2."<br/>";
echo '$this->example: '.$this->example."<br/>";
echo '$this->example2: '.$this->example2."<br/>";
}
function say_again()
{
echo '$example: '.$example."<br/>";
echo '$example2: '.$example2."<br/>";
echo '$this->example: '.$this->example."<br/>";
echo '$this->example2: '.$this->example2."<br/>";
}
}
$convo = new myClass();
$convo->say_what();
$convo->say_again();
// this is $convo->say_what();
$example: Hi
$example2: //blank
$this->example: //blank
$this->example2: Hi again
// this is $convo->say_again();
$example: //blank
$example2: //blank
$this->example: //blank
$this->example2: Hi again // only this one assigned to class shows.
It would be very helpful it you could add the database layouts.
Also, you only reference one database but you state we need to pull information from two.
In your class you state:
var $cat_id;
var $depth;
var $cat_title;
var $cat_parent_id;
var $cat_long_title;
It is hard to know which tables these belong to.
Also, in your $db->fetchrow(), is this a mysql_fetch_row, or mysql_fetch_object, assoc? Assuming you said row, im guessing it would be a fetch row, but clarification would be nice. Also, maybe a working script.
Hi Hawkee! This code is very usefull, but i\'m getting an error while running it:
Warning: Invalid argument supplied for foreach() in c:\web\anuncios\admin\dump.php on line 35
Dump.php is what I named the script, the line with the error is:
foreach($cat_array as $category)
I tried to do something similar to this script myself, but I was not sucessfull. If you can see this and help figuring this error out, I would appreciate very much.
Best Regards;
(Marcio)