HomePHP Page 7 - Building an Extensible Menu Class
Saving My Bookmarks - PHP
So you know the theory behind OOP, but don't really understandits applications? Well, it's time to take objects out of the classroom andinto the real world - this article demonstrates how OOP can save you timeand effort by building a PHP-based Menu object to describe therelationships in a hierarchical menu tree. And since the proof of thepudding is in the eating, it then combines the newly-minted Menu objectwith some of the most popular JavaScript menu systems available online toshow you how cool objects really are.
At this stage, I think I have enough building blocks to actually begin using this class to build menu trees. Keep in mind, though, that I've been wrong before, and so my initial feeling of satisfaction may soon disappear.
The only way to find out for sure is to try building a tree to see if the methods exposed by the class are simple and generic enough to be used in a variety of situations - so let's do that. I will attempt to use this Menu class to build a simple Web portal, which has links classified into hierarchical categories (a lot like the Open Directory Project at http://www.dmoz.org/)
This is a good time to download the accompanying source code, which contains complete versions of the SQL records displayed below, together with a copy of the final Menu class.
My user interface should clearly reflect this menu tree, by
making a distinction between "categories" and "links". A click on a category reveals the sub-categories and links under it, while a click on a link directs the browser to the appropriate content module or URL.
Here's the script to accomplish this:
<?
// set default id to 0
if (!$id) { $id = 0; }
// include class
include("menu.class.php");
// create Menu
$obj = new Menu;
// get next level
$children = $obj->get_children($id);
// check to see if items are "leaves" or "branches" on the tree
for ($x=0; $x<sizeof($children); $x++)
{
if($obj->get_type($children[$x]["id"]) == 1)
{
$branches[] = $children[$x];
}
else
{
$leaves[] = $children[$x];
}
}
// get lineage from tree root (used to create navigation path)
$ancestors = $obj->get_ancestors($id)
?>
<html>
<head>
<basefont face="Arial">
</head>
<body bgcolor="White" link="Black" vlink="Black">
<img src="logo.gif" height=50 width=206 border=0 alt="">
<table width="100%" border="0" cellspacing="0" cellpadding="3"
bgcolor="#9898D0">
<tr>
<td height=20>
<font color="Black"><b>
<?
// use $ancestors[] to set up path
for ($x=0; $x<sizeof($ancestors); $x++)
{
$path .= "<a href=" . $PHP_SELF . "?id=" . $ancestors[$x]["id"] . ">" .
$ancestors[$x]["label"] . "</a>" . " > ";
}
// add current level to path and print
$path .= $obj->get_label($id);
echo $path;
?>
</b></font>
</td>
<td align=right><? if ($id > 0) { ?><font color="Black"><b><a href="<? echo
$PHP_SELF; ?>">Top</a></b></font> <? } ?></td>
</tr>
</table>
<p>
<?
if ($branches)
{
?>
<b><font color="#9898D0" size="+1">Categories</font></b>
<ul>
<?
// print branches here
for ($x=0; $x<sizeof($branches); $x++)
{
echo "<li><a href=" . $PHP_SELF . "?id=" . $branches[$x]["id"] . ">" .
$branches[$x]["label"] . "</a><br>";
}
?>
</ul>
<?
}
?>
<p>
<?
if ($leaves)
{
?>
<b><font color="#9898D0" size="+1">Links</font></b>
<ul>
<?
// print leaves here
for ($x=0; $x<sizeof($leaves); $x++)
{
echo "<li><a href=" . $leaves[$x]["link"] . ">" . $leaves[$x]["label"] .
"</a><br>";
}
?>
</ul>
<?
}
?>
</body>
</html>
In this case, I'm first using the get_children() method to
obtain a list of all items under the current tree branch. I'm then using the get_type() method to split the list of child nodes into two separate arrays, $branches and $nodes, and formatting and displaying each appropriately. Finally, with the help of the get_ancestors() method, I'm building a hierarchical, clickable trail leading to the current node - just like any good portal would.