I've got a links database that I'm playing around with, each link category identified with a unique (auto_increment) id, and a field containing the id of it's parent (or NULL if it's at the bottom of the tree) category.
I pulled a three function 'menu' builder from http://www.evolt.org/article/BBS_style_ ... To/17/3962, and have been using that as my base.
So far, I've been successful in making it display in both definition lists, and select lists (forms) by passing variables. I select a category, and click edit, that reloads the page with the link category editor loaded up. However, on the link editor page, I can't make it select the parent of the link category that is being edited... sort of.
The following link categories exist in my database (test data - there are also descriptions, but that shouldn't apply as I'm not using them yet):
Code: Select all
cat_ID p_cat_ID category
1 NULL 'Zeitgeist'
2 1 'Earthquakes'
3 NULL 'Tiddly bits o info'
4 1 'Tsunamis'
5 1 'Meteor Strikes'
6 3 'Randomness'
7 1 'Moon Disappearances'
8 3 'Miscellany'
9 6 'Now it is getting silly.'Code: Select all
SELECT cat_ID, category, p_cat_ID FROM b2_linkcategories ORDER BY p_cat_ID, categoryCode: Select all
cat_ID menu entry
3 Tiddly bits o info
8 Miscellany
6 Randomness
9 Now it is getting silly.
1 Zeitgeist
2 Earthquakes
5 Meteor Strikes
7 Moon Disappearances
4 TsunamisThis is frustrating, so if anyone could peruse the following code, and possibly tell me where my error is, I'd appreciate it.
Snippet from the form:
Code: Select all
<select name="link_cat_parent_ID">
<option value="">
<?php
echo "\t<option value="" . $result_arrayї0]ї0] . """;
if ($result_arrayї0]ї0] == $link_cat_p_ID) echo " selected";
echo ">";
echo stripslashes($result_arrayї0]ї1]) . "</option>\n";
$selectedOnce = false;
find_child($parentID, $startSeed, $depth, false, $link_cat_p_ID, "\t<option value="", "">", "", "</option>\n");
?>
</select><br />Code: Select all
<?php
$q_tree = "SELECT cat_ID, category, p_cat_ID, description FROM $tablelinkcategories ORDER BY p_cat_ID, category";
$r_tree = mysql_query($q_tree) or die("Couldn't query '" . $tablelinkcategories . "' for link category list.");
$i = 0;
while ($row_tree = mysql_fetch_row($r_tree)) {
$result_arrayї$i] = $row_tree;
$i++;
}
$parentID = $result_arrayї0]ї0];
$arr_size = count($result_array);
$depth = 1;
$startSeed = 1;
$selectedOnce = false;
function depth($depth) {
for ($i=1; $i<= $depth; ++$i) {
echo " ";
}
}
/*
Here's where the real meat of the program starts.
It's actually the second of two functions that format
our results. Because functions are defined before
they are called in PHP it comes first in the script.
You might want to read the description of find_child first!
Okay, step-up is called by the find_child function
when it cannot find any more children in a
particular branch of categories.
*/
function step_up ($parentID, $startSeed, $depth, $showdescr, $link_cat_p_ID, $befID, $aftID, $befCat, $aftCat, $befDescr, $aftDescr) {
global $result_array;
global $arr_size;
// The first thing we'll check is that $start_seed
// hasn't gone off the end of our result_array.
// If it has, we'll stop execution of this function.
if ($startSeed > $arr_size) {
return;
} else {
// if the CatParent of the last category is
// equal to the CatParent of the next category
// then they are on the same level. We'll move
// along to it and check to see if it has children
// This was why we chose to order our results by
// CatParent first in our SELECT statement.
if ($result_arrayї$startSeed-1]ї2] == $result_arrayї$startSeed]ї2]) {
$depth--;
return find_child($result_arrayї$startSeed-1]ї2], $startSeed, $depth, $showdescr, $link_cat_p_ID, $befID, $aftID, $befCat, $aftCat, $befDescr, $aftDescr);
// Otherwise, if the last CatParent was NULL and
// the current is 1, we stop processing
// as we have covered all the top level
// (again, we know this thanks to our SELECT
// statement ordering)
} else {
if ($result_arrayї$startSeed-1]ї2] == "" &&
$result_arrayї$startSeed]ї2] == 1) {
return;
}
// If they were unequal, and we haven't reached
// the end of the list, we need to
// climb back to this category's parent and
// restart this checking process. More recursion!
for ($j = 0; $j <= $arr_size; ++$j) {
if ($result_arrayї$j]ї0] == $result_arrayї$startSeed-1]ї2]) {
$depth--;
// end this definition list if this is the end of a branch
if ($showdescr) echo "</dl>\n";
return
step_up($result_arrayї$j+1]ї0], $j+1, $depth, $showdescr, $link_cat_p_ID, $befID, $aftID, $befCat, $aftCat, $befDescr, $aftDescr);
}
}
// I've forgotten what this return does, but it's
// probably something important!
// Best leave it there :-)
return;
}
}
}
/*
The find_child function is the part of our recursive
process that steps down the category list.
It is fed the CatID of the last category we got
from our results. This is the potential "parent"
of other categories, so I have called it $parentID. It is
also fed a $startSeed, which is the position of the current
result we are looking at in $result_array. There's also a
$depth variable which is used for formatting purposes.
*/
function find_child ($parentID, $startSeed, $depth, $showdescr = true, $link_cat_p_ID = "0", $befID = "<dt>ї ", $aftID = " ] ", $befCat = "<b>", $aftCat = "</b></dt>\n", $befDescr = "<dd>", $aftDescr = "</dd>\n") {
global $result_array;
global $arr_size;
global $selectedOnce;
// This for loop starts us where we left off in
// $result_array and steps through the results.
for ($k = $startSeed; $k <= $arr_size; ++$k) {
// If we find a result where the catParent is
// equal to the CatID of our current result
// then we've found a child.
if ($result_arrayї$k]ї2] == $parentID) {
// make a new definition list if this is the start of a new branch
if (($showdescr) && ($result_arrayї$k-1]ї2] != $result_arrayї$k]ї2])) echo "<dl>\n";
// We can then do whatever we need to do
// with our category.
// In this case we'll print it out with some
// depth formatting.
if ((!$selectedOnce) && ($result_arrayї$k]ї0] == $link_cat_p_ID)) {
$aftID = substr($aftID, 0, -1) . " selected" . ">" . $selectedOnce;
$selectedOnce = true;
}
echo $befID . $result_arrayї$k]ї0] . $aftID;
if (!$showdescr) depth($depth);
echo $befCat . stripslashes($result_arrayї$k]ї1]) . $aftCat;
if ($showdescr) echo $befDescr . stripslashes($result_arrayї$k]ї3]) . $aftDescr;
// then we need to reset our startup variables - our
// current result could now be a parent itself.
$parentID = $result_arrayї$k]ї0];
$startSeed = ++$k;
$depth++;
// Finally we recall find_child with our new values
// to see if this category contains sub-categories.
// This is recursion at work!
return find_child($parentID, $startSeed, $depth, $showdescr, $link_cat_p_ID, $befID, $aftID, $befCat, $aftCat, $befDescr, $aftDescr);
} elseif ($result_arrayї$k]ї2] > $parentID) {
// Simply a little code to save some processing time.
// We'll break out of the loop if we've gone
// past the parent value
break;
}
}
/*
If we didn't find a child, then we've gone as far down
this particular branch of categories as we can.
We need to keep our startup variables the same and
use our second function - step_up to either find
further results on the same level, or to take us
back up the category tree.
*/
step_up ($parentID, $startSeed, $depth, $showdescr, $link_cat_p_ID, $befID, $aftID, $befCat, $aftCat, $befDescr, $aftDescr);
}
?>Regards,