TalkPHP

TalkPHP (http://www.talkphp.com/forums.php)
-   Advanced PHP Programming (http://www.talkphp.com/advanced-php-programming/)
-   -   Making a navigation list from database (http://www.talkphp.com/advanced-php-programming/1650-making-navigation-list-database.html)

victorius 12-07-2007 08:26 AM

Making a navigation list from database
 
Hi peeps, I hope someone can help me out or point me to a tutorial or code which could help.

The challenge
I want to make an unordered list (and sublists) from product groups in a database.

I think I would need to use some kind of recursive function/looping through this. But I just can't wrap my mind around it. I've searched the Internet quite a bit and found a few directory->list scripts but nothing that I've been able to apply to my needs.

I fetch product groups from database which are returned each in a string like so:

Backup/Tape/LTO
Backup/Tape/RDX
Backup/Tape/Cleaner
Motherboard/Intel
Motherboard/AMD

General solution:
I need to split the string by / and check if the group exists already in an array, and if so, then if the subgroup does not exist, then create it. If the subgroup exists, then check the next element etc. But for me, this gets complex fast.

In the meantime...
I'm going to read some articles I found on recursion and traversing arrays etc. :-)

Thank you everybody.

Tanax 12-07-2007 08:49 AM

Check out this tutorial: http://www.talkphp.com/showthread.php?p=5123

Hope that helps! :-)


And welcome to the site! Why don't you take a minute and introduce yourself over here: http://www.talkphp.com/forumdisplay.php?f=14

Haris 12-07-2007 11:17 AM

Do you mean in the following format?

PHP Code:

Backup
    
Tape
        
LTO
        
RDX
        
Cleaner

Motherboard
    
Intel
    
AMD 


victorius 12-07-2007 11:33 AM

Yes, in a nested list like so...

Code:

<ul>
  <li>Backup
    <ul>
      <li>Tape
        <ul>
          <li>LTO</li>
          <li>RTO</li>
          ...
        </ul>
      </li>
    </ul>
  </li>
  <li>Motherboard
    <ul>
      ...
    </ul>
  </li>
</ul>

I think I need to somehow split/explode the strings into an multidimensional array. From there I would output the list.

This is actually very close to working for me: Convert anything to Tree Structures in PHP

But I'm battling the plotTree function to output it for me.

victorius 12-07-2007 12:35 PM

@Tanax: I've taken a look and I don't think that's what I need. But thanks for your help.

I'll probably introduce myself today or tomorrow. :-D

Wildhoney 12-07-2007 02:19 PM

A warm welcome, Victorius! I did have a stab at this, but it would appear I'm not in such a frame a mind to be able to successfully do it yet! I'll have another go later if you're still having troubles.

Karl 12-07-2007 04:32 PM

That was a tough little problem. Here's a solution I came up with:

php Code:
<?php

class ProductList
{
    private $m_aList;
   
    public function __construct($aProducts)
    {
        $this->m_aList = array();
       
        foreach ($aProducts as $szProductTree)
        {
            $this->parseProductTree($szProductTree);
        }           
    }
   
    public function parseProductTree($szProduct)
    {
        // First of all split the string into an array
        $aParts = split('/', $szProduct);
       
        // Get a reference to root array
        $aList = &$this->m_aList;
       
        $iLastIndex = count($aParts) - 1;

        foreach ($aParts as $iIndex => $szLabel)
        {
            // This is the last node in the list, we need to handle this
            // differently because it will not contain any child nodes
            if ($iIndex == $iLastIndex)
            {
                if (key_exists($szLabel, $aList))
                {
                    break;
                }
               
                $aList[] = $szLabel;
                break;
            }

            // Check if node exists in the current array (specified by $aList),
            // if it doesn't exist, we add it to the array
            if (!key_exists($szLabel, $aList))
            {
                $aList[$szLabel] = array();
            }
           
            // Update the array reference to point to the array we just added
            // The next node in the foreach loop will be added to this array
            $aList = &$aList[$szLabel];
        }     
    }
   
    public function getList()
    {
        return $this->m_aList;
    }
}

class ProductList_RenderHtml
{
    public function render($aList)
    {
        $szHtml .= "<ul>\n";
       
        foreach ($aList as $mNodeName => $mNodeValue)
        {
            $szHtml .= $this->renderList($mNodeName, $mNodeValue);
        }
       
        $szHtml .= "</ul>\n";
        return $szHtml;
    }
   
    public function renderList($szListLabel, $aList)
    {
        $szHtml .= "<li>" . $szListLabel . "\n";
        $szHtml .= "<ul>\n";
       
        foreach ($aList as $mNodeName => $mNodeValue)
        {
            // If the node value is an array we render it as a new list
            if (is_array($mNodeValue))
            {
                $szHtml .= $this->renderList($mNodeName, $mNodeValue);
            }
            // If its not an array we know it's list item
            else
            {
                $szHtml .= "<li>$mNodeValue</li>\n";
            }
        }
       
        $szHtml .= "</ul>\n";
        $szHtml .= "</li>\n";
        return $szHtml;
    }
}

$aProducts = array(
    'Backup/Tape/LTO',
    'Backup/Tape/RDX',
    'Backup/Tape/Cleaner',
    'Motherboard/Intel',
    'Motherboard/AMD'
);

$pProductList = new ProductList($aProducts);
$pRender = new ProductList_RenderHtml();

echo $pRender->render($pProductList->getList());

?>

Hope it helps.

Matt83 12-07-2007 06:01 PM

amazing stuff Karl, very simple solution. i gave this problem a try and all i ended up with was a headache and a code double in length than yours :-$ :-)

If you dont mind, i would like to ask you about this bit of the code:

PHP Code:

// Get a reference to root node
        
$aList = &$this->m_aList

I never saw this before. Whats supposed to be/do?,
thank you

Karl 12-07-2007 08:57 PM

Quote:

Originally Posted by Matt83 (Post 5792)
I never saw this before. Whats supposed to be/do?

It just provides a reference (pointer) to the array. You can then add elements to the array via the reference.

I could have just added the elements to the $this->m_aList array, but because we were recursively traversing the array, and we wanted to add nodes to the last parent from the current level, it was easier to use the array reference to keep track of the parent array (node).

Wildhoney 12-07-2007 09:03 PM

In extension to Karl's, consider this:

php Code:
$a = 1;
$b =& $a;
$b = 2;

In the above example, both $a and $b now equal 2 because $b has been set as a reference to $a and so whatever $b becomes, $a becomes as well.

In a more complicated example:

php Code:
$aArray = array('Apple', 'Orange', 'Kiwi', 'Pear');
$pItem =& $aArray[2];
$pItem = 'Pitaya';

As $pItem is now a reference to the third item in our array, changing its value will also change the value in the array, so Kiwi now becomes Pitaya.

Matt83 12-08-2007 12:27 AM

Perfect, got it. Thanks guys ^^

Haris 12-08-2007 01:13 AM

Quote:

Originally Posted by Wildhoney (Post 5822)
In extension to Karl's, consider this:

php Code:
$a = 1;
$b =& $a;
$b = 2;

In the above example, both $a and $b now equal 2 because $b has been set as a reference to $a and so whatever $b becomes, $a becomes as well.

In a more complicated example:

php Code:
$aArray = array('Apple', 'Orange', 'Kiwi', 'Pear');
$pItem =& $aArray[2];
$pItem = 'Pitaya';

As $pItem is now a reference to the third item in our array, changing its value will also change the value in the array, so Kiwi now becomes Pitaya.

Thanks, got that. ^^

Gurnk 12-08-2007 03:04 AM

Thats very cool Wildhoney, you are full of useful knowledge. :-D

victorius 12-08-2007 05:01 PM

Wow
 
Wow, thank you all for your input. This is fantastic. I too just got a headache when trying to figure this out.

Thank you Karl, I'm going to see if I can put this to good use.

Love this community. Thanks again everybody! ^^


All times are GMT. The time now is 08:13 AM.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0