'Hieratic Data of Unknown Depth' or 'How to Use Recursion'

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
lightnb
Forum Newbie
Posts: 13
Joined: Mon Jul 28, 2008 11:13 pm

'Hieratic Data of Unknown Depth' or 'How to Use Recursion'

Post by lightnb »

I'm trying to use PHP to dynamically generate hieratic form elements, for an e-commerce website:

eg. When you choose "Large" in the 'size' radio group of a T-shirt order form, Javascript makes a second option appear for 'color', listing only the colors that are available for "Large" shirts.

This, in and of itself, is simple and straightforward. The challenge is, the depth of the options hierarchy is unknown at the time of programming. So there could be two options (Color, dependent on Size), or 30 options (color dependent on size, dependent on design, dependent on fabric type, dependent on fabric thickness, etc...)

There's a built in PHP class called "RecursiveIteratorIterator" that may be what I need, but there's no documentation in the PHP.net manual.

The cart already has a products table. So my idea is to create a "Dummy Product" (eg. "T-Shirt") with a flag that lets the cart know it's a dummy.

Then, once the user chooses the options, based on their choices, a real product is added to the cart (eg. "T-shirt-Large-Red-Logo 1"). Because product attributes are really just for display/usability purposes.

Here are my specific questions:
1.) Should I use the "LeftID" "RightID" method (I think this is called Nested Sets?), or the "ParentID" method, in the database for the attributes/options table?

2.) What is the appropriate way to build an array of this data, when it's depth in unknown? (recursive functions?)

Thanks,

Nick
lightnb
Forum Newbie
Posts: 13
Joined: Mon Jul 28, 2008 11:13 pm

Re: 'Hieratic Data of Unknown Depth' or 'How to Use Recursion'

Post by lightnb »

This is what I've got so far:

Code: Select all

 
// STEP ONE: Get all Attributes For the Product. So we know how many levels we're dealing with
    
    $AttribuesQuery = 'SELECT PA.H_Order, AN.Name AS FieldName, AN.ID AS AttributeID
                FROM `SA_ProductAttributes` PA
                LEFT JOIN `SA_AttributeNames` AN 
                ON PA.AttributeNameID = AN.ID 
                WHERE DummyProductID = "'.$DummyProductID.'"
                ORDER BY H_Order';
        
 
    $AttributesResult = mysql_query($AttribuesQuery) or die(mysql_error()); // Run the query 
        
    while($row = mysql_fetch_array($AttributesResult))
    {
        $AttributeNamesArray[$row['H_Order']]['Name'] = $row['FieldName'];
        $AttributeNamesArray[$row['H_Order']]['ID'] = $row['AttributeID'];
    }
            
    $NumberOfAttributes = count($AttributeNamesArray);
 
At this point I know how many levels I have, so I need the program to create x nested foreach loops, where x = $NumberOfAttributes. But I'm not sure how to create a variable number of loops?
WebbieDave
Forum Contributor
Posts: 213
Joined: Sun Jul 15, 2007 7:07 am

Re: 'Hieratic Data of Unknown Depth' or 'How to Use Recursion'

Post by WebbieDave »

lightnb wrote:1.) Should I use the "LeftID" "RightID" method (I think this is called Nested Sets?), or the "ParentID" method, in the database for the attributes/options table?
I'm wondering if it may be inappropriate to lock into either a nested set model or a parental relationship. I don't know enough specifics about your project but what if in the future you must allow customers to choose fabric first, then color, then size? What if attributes/options are added or taken away? Shouldn't the data be stored in a way that one could travel to the desired product through any of its attributes in any order?

Only if you are confident in the permanency of the hierarchy should you store it that way. If are confident in it, nested sets are generally superior, especially in limiting the amount of querying necessary to retrieve a full hierarchy.
lightnb
Forum Newbie
Posts: 13
Joined: Mon Jul 28, 2008 11:13 pm

Re: 'Hieratic Data of Unknown Depth' or 'How to Use Recursion'

Post by lightnb »

WebbieDave wrote:what if in the future you must allow customers to choose fabric first, then color, then size? What if attributes/options are added or taken away? Shouldn't the data be stored in a way that one could travel to the desired product through any of its attributes in any order?
For now, the only products I know of are (for this store):
Based on things the user can't control (like their shoe size, weight and t-shirt size) followed by the preferential options available (like color). Of course, it wouldn't make sense to allow the user to choose "yellow" first, and then only allow them to buy large or extra large, because those are the only sizes that come in yellow.

But you are right. The attributes structure has to be flexible. I was planing on the attributes themselves, and their options being dynamic, on a product by product basis.

So product A could be Size -> Color -> Print, Where product B could be Style -> Shoe Size.

So I guess we're dealing with more than one hierarchy? One for the attribute relationship, and then another for the options?

Maybe some sample data would help:

The `Products` table is already built into the cart, and is the 'given' in the equation. (although fields can be added if needed).

PRODUCTS TABLE:

Code: Select all

 
UID               Model                       QuantityInStock
1           Tshirt-Large-Yellow                      4
2           Tshirt-Large-Blue                        3
3           Tshirt-Small-Green                       22
4           Tshirt-Small-Blue                        8
5           Tshirt-Small-Pink                        0
6           T-Shirt                                  0
 
Even though all of the above are T-shirts, they are all separate products based on their attributes. A "large blue T-shirt" is not the same as a "small blue T-shirt". They could have different prices, and they will have different inventory counts.

So:
1. Each attribute configuration of a base product is a separate product in the products table
2. The quantity needs to be different, but I think this can use existing quantities field for that.
3. The prices need to be able to change based on attribute as well, but I think we can use the existing price field.

It was my intention to add a column to the products table that identifies it as "regular", "dummy" or "attribute". Dummy products show up in the product list, but can't be added to the cart (or bought). "attribute" products DO NOT show up in the product listing, but CAN be added
to the cart through the dummy products page.

So the table for attributes linking table might look like this (using the products table above):

Code: Select all

 
ID           DummyProductID              Attributes               RealProductID
 
1                  6                      Large-Yellow                  1
2                  6                      Large-Blue                    2
3                  6                      Small-Green                   3
4                  6                      Small-Blue                    4
5                  6                      Small-Pink                    5
 
Product ID 6 is the dummy, and when the certain attributes are chosen, it 'becomes' a real product. Of course strings in a database field are messy/impractical, but I'm not sure how to do this, since the number of fields is variable.
WebbieDave
Forum Contributor
Posts: 213
Joined: Sun Jul 15, 2007 7:07 am

Re: 'Hieratic Data of Unknown Depth' or 'How to Use Recursion'

Post by WebbieDave »

lightnb wrote:Based on things the user can't control (like their shoe size, weight and t-shirt size) followed by the preferential options available (like color)
So products have attributes that are to be displayed to the visitor in a particular order.
lightnb wrote:Of course strings in a database field are messy/impractical
Right. So you should spread them out into tables and see what you're working with. The increased integrity afforded by the resulting normalization will make it well worth it. This is no simple task you've got ahead of you no matter which approach you take but data integrity should be a priority IMO. Either way, I'm interested to know what you come up with.
lightnb
Forum Newbie
Posts: 13
Joined: Mon Jul 28, 2008 11:13 pm

Re: 'Hieratic Data of Unknown Depth' or 'How to Use Recursion'

Post by lightnb »

How about:

TABLE `AttributeNames`

Code: Select all

 
ID           Name          
 
1            Size                     
2            Color
3            Print
 
TABLE `AttributeOptions`

Code: Select all

 
ID   ChildOfRowID         BaseProductID          AttributeNameID           RealProductID          OptionName
 
1        0                    25                        1                       1                   Large
2        0                    25                        1                       2                   Small
3        2                    25                        2                       3                   Green
4        2                    25                        2                       4                   Blue
5        1                    25                        2                       5                   Blue
6        1                    25                        2                       5                   Yellow
7        2                    25                        2                       5                   Pink
 
The field names (in the AttributeNames table) are reusable across all products. Then a hierarchy of options is built in the second table. So to build the tree, you would query for records whose `BaseProductID` was equal to whatever product page you were on.
Post Reply