mercredi 16 septembre 2015

php, oop; Choose the right design pattern for categorized items of variable depth and display links to items

Intro

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.

Goal

Since the site shall be kind of a catalog the URL would be for example:

http://ift.tt/1FgnQiQ.

The behavior on that URL should be: present all children (either only items or only subgroups) with it's previewImage and a hyperlink to http://ift.tt/1Kgh4sm. The Itemtypes are of course different.

What i did

Classes

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;
}
?>

Objects / data structure

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.

Presentation

<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>\n";
    }
?>
</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.

Question

I have no clue which design pattern would be 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.

With that kind of structure, how would you guys implement a multi language feature?

Is this a good way to start? Any hints? any help? Criticism is very welcome!!

Aucun commentaire:

Enregistrer un commentaire