1st: I am NOT a PHP expert. I struggle. I read a lot of help and tutorials. I understand some of them!
2nd: I found a PHP driven menu system called
EasyNav - that was the easy bit.. things go downhill from this point!
I like the way that PHP is used to rewrite the site navigation, specifically removing nested menu items, and applying ID and CLASS tags to the menu to facilitate easy styling.
BUT the original script is written for PHP4 and my host uses PHP5. No problem, I thought, I'll rewrite the bits of the script that I need, and learn a lot about PHP along the way.
Generally I have got things working, but there is a bug in the code somewhere...
In one section I loop through all the UL elements in the DOM, checking to see whether their parent nodes are LI elements. If they are then the UL is a nested list, and so, unless it is the one containing the current page, should be removed from the menu.
$HTMLDOM = new DOMDocument(); //Create a new DOMDocument.
$HTMLDOM->loadHTML($NavHTML); //Convert $NavHTML to a tree of DOM objects.
$ULs = $HTMLDOM->getElementsByTagname("ul"); //Get a NodeList of the <ul> elements in the document.
foreach($ULs as $CurrentUL) //For each <ul>...
{
$ULParent=$CurrentUL->parentNode; //Get its parent.
if ($ULParent->nodeName=='li') //If parent is an <li>, then this is a nested list...
{
if($ULParent->getElementsByTagName('strong')->item(0)==NULL) //If the nested list does NOT contain current page.
{
$ULParent->removeChild($CurrentUL); //Remove the child node. (ie the nested list).
}
}
}
To test it I run the loop on the following navigation structure...
<li><a href="index.php">A no_kids
</a></li> <li><a href="B.php">B 2_kids
</a> <li><a href="B1.php">B.1
</a></li> <li><a href="B2.php">B.2
</a></li> <li><a href="C.php">C 2_kids
</a> <li><a href="C1.php">C.1
</a></li> <li><a href="C2.php">C.2
</a></li> <li><a href="D.php">D 2_kids
</a> <li><a href="D1.php">D.1
</a></li> <li><a href="D2.php">D.2
</a></li> <li><a href="E.php">E no_kids
</a></li>
The current page is index.php, so ALL the sub-menus should be removed; but the actual output is...
A no_kids
B 2_kids
C 2_kids
C.1
C.2
D 2_kids
E no_kids
ie. sub-menus B and D are removed but C is not!
If I watch what is happening in the code, the foreach loop skips the iteration for C. If I comment out the removeNode() command, then the loop works correctly.
Does anyone have any idea why the removeNode() command is causing my loop to jump?