TalkPHP
 
 
Account Login
Latest Articles
» The basic usage of PHPTAL, a XML/XHTML template library for PHP
» Vulnerable methods and the areas they are commonly trusted in.
» Simple way to protect a form from bot
» The Basics On: How Session Stealing Works
» How to keep your forms from double posting data
IRC Channel
IRC Speech Bubble Join the friendly bunch on IRC...
(#TalkPHP on Freenode)

...Also available via a web interface.

See this thread for information on the TalkPHP Free Hugs Initiative™. Subject to availability.
Associates
Associates
CSS Tutorials
Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old 12-07-2007, 08:26 AM   #1 (permalink)
The Wanderer
 
victorius's Avatar
 
Join Date: Nov 2007
Location: Denmark
Posts: 21
Thanks: 4
victorius is on a distinguished road
Default 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.
Send a message via MSN to victorius
victorius is offline  
Reply With Quote
Old 12-07-2007, 08:49 AM   #2 (permalink)
The Prestige
Upcoming Programmer Inquisitive 
 
Tanax's Avatar
 
Join Date: Sep 2007
Location: Sweden, Stockholm
Posts: 1,080
Thanks: 115
Tanax is on a distinguished road
Default

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
Tanax is offline  
Reply With Quote
Old 12-07-2007, 11:17 AM   #3 (permalink)
The Frequenter
Prolific Welcomer Upcoming Programmer 
 
Join Date: Sep 2007
Posts: 360
Thanks: 24
Haris is on a distinguished road
Default

Do you mean in the following format?

PHP Code:
Backup
    
Tape
        
LTO
        
RDX
        
Cleaner

Motherboard
    
Intel
    
AMD 
Haris is offline  
Reply With Quote
Old 12-07-2007, 11:33 AM   #4 (permalink)
The Wanderer
 
victorius's Avatar
 
Join Date: Nov 2007
Location: Denmark
Posts: 21
Thanks: 4
victorius is on a distinguished road
Default

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.
Send a message via MSN to victorius
victorius is offline  
Reply With Quote
Old 12-07-2007, 12:35 PM   #5 (permalink)
The Wanderer
 
victorius's Avatar
 
Join Date: Nov 2007
Location: Denmark
Posts: 21
Thanks: 4
victorius is on a distinguished road
Default

@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.
Send a message via MSN to victorius
victorius is offline  
Reply With Quote
Old 12-07-2007, 02:19 PM   #6 (permalink)
La Vida es Sueño
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Oldham
Posts: 2,280
Thanks: 90
Wildhoney is on a distinguished road
Default

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.
__________________
The man who comes back through the Door in the Wall will never be quite the same as the man who went out.
Send a message via AIM to Wildhoney Send a message via MSN to Wildhoney Send a message via Yahoo to Wildhoney
Wildhoney is offline  
Reply With Quote
Old 12-07-2007, 04:32 PM   #7 (permalink)
The Reckoner
Advanced Programmer Top Contributor 
 
Karl's Avatar
 
Join Date: Sep 2007
Posts: 437
Thanks: 22
Karl is on a distinguished road
Default

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.
__________________
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

Last edited by Karl : 12-07-2007 at 08:50 PM. Reason: Cleaned up code comments
Karl is offline  
Reply With Quote
The Following 4 Users Say Thank You to Karl For This Useful Post:
Haris (12-08-2007), Matt83 (12-07-2007), thegrayman (12-09-2007), victorius (12-08-2007)
Old 12-07-2007, 06:01 PM   #8 (permalink)
The Contributor
Upcoming Programmer 
 
Matt83's Avatar
 
Join Date: Oct 2007
Location: Argentina
Posts: 72
Thanks: 18
Matt83 is on a distinguished road
Default

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
__________________
http://www.mattvarone.com
Matt83 is offline  
Reply With Quote
Old 12-07-2007, 08:57 PM   #9 (permalink)
The Reckoner
Advanced Programmer Top Contributor 
 
Karl's Avatar
 
Join Date: Sep 2007
Posts: 437
Thanks: 22
Karl is on a distinguished road
Default

Quote:
Originally Posted by Matt83 View Post
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).
__________________
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
Karl is offline  
Reply With Quote
The Following 2 Users Say Thank You to Karl For This Useful Post:
Matt83 (12-08-2007), victorius (12-08-2007)
Old 12-07-2007, 09:03 PM   #10 (permalink)
La Vida es Sueño
Advanced Programmer Top Contributor 
 
Wildhoney's Avatar
 
Join Date: Sep 2007
Location: Oldham
Posts: 2,280
Thanks: 90
Wildhoney is on a distinguished road
Default

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.
__________________
The man who comes back through the Door in the Wall will never be quite the same as the man who went out.
Send a message via AIM to Wildhoney Send a message via MSN to Wildhoney Send a message via Yahoo to Wildhoney
Wildhoney is offline  
Reply With Quote
The Following 5 Users Say Thank You to Wildhoney For This Useful Post:
Gurnk (12-08-2007), Haris (12-08-2007), Matt83 (12-08-2007), Morishani (12-08-2007), victorius (12-08-2007)
Old 12-08-2007, 12:27 AM   #11 (permalink)
The Contributor
Upcoming Programmer 
 
Matt83's Avatar
 
Join Date: Oct 2007
Location: Argentina
Posts: 72
Thanks: 18
Matt83 is on a distinguished road
Default

Perfect, got it. Thanks guys
__________________
http://www.mattvarone.com
Matt83 is offline  
Reply With Quote
Old 12-08-2007, 01:13 AM   #12 (permalink)
The Frequenter
Prolific Welcomer Upcoming Programmer 
 
Join Date: Sep 2007
Posts: 360
Thanks: 24
Haris is on a distinguished road
Default

Quote:
Originally Posted by Wildhoney View Post
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.
Haris is offline  
Reply With Quote
Old 12-08-2007, 03:04 AM   #13 (permalink)
The Contributor
Upcoming Programmer 
 
Gurnk's Avatar
 
Join Date: Oct 2007
Location: US
Posts: 66
Thanks: 19
Gurnk is on a distinguished road
Default

Thats very cool Wildhoney, you are full of useful knowledge.
Send a message via MSN to Gurnk
Gurnk is offline  
Reply With Quote
Old 12-08-2007, 05:01 PM   #14 (permalink)
The Wanderer
 
victorius's Avatar
 
Join Date: Nov 2007
Location: Denmark
Posts: 21
Thanks: 4
victorius is on a distinguished road
Default 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!
Send a message via MSN to victorius
victorius is offline  
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


All times are GMT. The time now is 05:19 AM.

 
     

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2013, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0
Inactive Reminders By Icora Web Design