Hello there,
i want to set up a big data structure that goes like this:
[products]
.[cat_1]
.[cat_1.1]
.[item-A] //type 1
.[item-B] //type 1
. ...
.[cat_1.2]
.[item-X] //type 2
.[cat_2]
.[item-Y] //type 3
So far so good.
Since the site shall be kind of a catalog the URL would be for example:
www.example.com/products/cat_1/.../cat_Y/
.
The behavior on that URL should be: present all children (either only items or only subgroups) with it's previewImage and a hyperlink to example.com/products/cat_1/.../cat_Y/item-X
. The Itemtypes are of course different.
I implemented the structure based on the Composite Pattern, so the nodes and the the leafs have a common base class, which - in my example - holds the name of the object. Nodes contain an array of either leafs or nodes, which is filled by a method called addChild()
.
The implementation is similar to this:
<?php
abstract class Base
{
public $name;
public $previewImage; //path to preview image
public function __construct($name,$preview){
$this->name=$name;
$this->previewImage=$preview;
}
}
class SubGroup extends Base{
public $children= array();
public function getChildrenByPath(Array $subGroupPath){
//example: array("cat_1","cat_1-1",...);
$subChildren=$this->children;
foreach($subGroupPath as $currentPathStep){//follow subGroupPath
foreach($subChildren as $currentChildr){// step through children and compare to path
if($currentChild->uriPattern == $currentPathStep){
$subChildren=$currentChild->getChildren();
break; //end foreach
}
}
}
return $subChildren;
}
public function addChild(Base $new_child){
$this->children[]=$new_child;
}
public function getChildren(){
return $this->children;
}
}
class ProductType01 extends Base{
public property1,property2,property3;
}
?>
I set up a few items in a separate php-file to create a dummy structure and try to play around (can later be in a database):
$cat01 = new SubGroup("category 01","preview_cat_01.png");
$cat01->addChild( new ProductType01("Item-01","preview_01.png"));
$cat01->addChild( new ProductType01("Item-02","preview_02.png"));
...
$products = new subGroup("","","products"); //very first node
$products->addChild($cat01);
So the addChild() method adds items to the first category's array.
<main>
<?php
$children=$products->getChildrenByPath($uri);
foreach($children as $value){
echo "<div class='previewImage_element'>";
echo "<img src='".$value->previewImage."' style='width:calc(120px *4/3);height:calc(120px*3/4);'>";
echo "<br /><a href='".."'>".$value->name."</a></div>
";
}
?>
</main>
This is how i list up the previewImages in a table structure, no problem there of course. This could also be automated as a method as well.
I have no clue if composite (and the way i built it) is the right design pattern and the best approach to reach the desired flexibility and easy to implement structure. At a first glance the Composite Pattern seems to match my hierarchical data but there are is a lot to be made to accomplish an easy implementation.
For example: how to build the hyperlink of the item, since i can't move up the tree structure to collect all levels above?
I am not looking for an "easy" way to set up the classes but to use them easily.
Is the inner array the way to do it or are there more sophisticated ways to point to children / subnodes?
With that kind of structure, how would you guys implement a multi language feature?
And in what way could i keep data and html separated (as much as possible)?
Is this a good way to start? Any hints? any help? Criticism is very welcome!!
You could add a parent variable in your Base class and set it in the addChild. Checking for null will be necessary but it will allow you to move both ways in the tree hierarchy.