php - Laravel 4 - Eloquent. Infinite children into usable array? -


i've got categories table. each category can have optional parent (defaults 0 if no parent).

what want build simple html list tree levels of categories.

example date:

foods -- fruit ---- apple ---- banana ---- orange -- veg ---- cucumber ---- lettuce drinks -- alcoholic ---- beer ---- vodka misc -- household objects ---- kitchen ------ electrical -------- cooking ---------- stove ---------- toaster ---------- microwave 

note needs work around 10 'levels'. i'd love infinite dont want going down route of using nested set model it'll cause huge delays on project.

the docs on laravel terrible, no real reference start. i've been playing days trying work out , seem getting without huge messy block of each loops within each other 10 times.

i've got tree of data using following in model:

<?php class item extends eloquent {     public function parent()     {         return $this->hasone('item', 'id', 'parent_id');     }      public function children()     {         return $this->hasmany('item', 'parent_id', 'id');     }      public function tree()     {         return static::with(implode('.', array_fill(0,10, 'children')))->where('parent_id', '=', '0')->get();     } } 

this gets parent , children level of 10. works fine, cant child data without manually having 10 foreach loops within each other.

what doing wrong here? surely shouldn't hard/poorly executed? want do simple html list items in tree structure.

i've put quick sqlfiddle example of dummy data used above: http://sqlfiddle.com/#!2/e6d18/1

this more fun usual morning crossword puzzle. :)

here itemshelper class looking for, , better yet recurse far down want.

app/models/itemshelper.php:

<?php    class itemshelper {      private $items;      public function __construct($items) {       $this->items = $items;     }      public function htmllist() {       return $this->htmlfromarray($this->itemarray());     }      private function itemarray() {       $result = array();       foreach($this->items $item) {         if ($item->parent_id == 0) {           $result[$item->name] = $this->itemwithchildren($item);         }       }       return $result;     }      private function childrenof($item) {       $result = array();       foreach($this->items $i) {         if ($i->parent_id == $item->id) {           $result[] = $i;         }       }       return $result;     }      private function itemwithchildren($item) {       $result = array();       $children = $this->childrenof($item);       foreach ($children $child) {         $result[$child->name] = $this->itemwithchildren($child);       }       return $result;     }      private function htmlfromarray($array) {       $html = '';       foreach($array $k=>$v) {         $html .= "<ul>";         $html .= "<li>".$k."</li>";         if(count($v) > 0) {           $html .= $this->htmlfromarray($v);         }         $html .= "</ul>";       }       return $html;     }   } 

i used new installation of laravel 4 , basic hello.php view.

here route in app/routes.php:

route::get('/', function() {   $items = item::all();   $itemshelper = new itemshelper($items);   return view::make('hello',compact('items','itemshelper')); }); 

although view doesn't use items variable, i'm passing here because want else them too.

and finally, app/views/hello.php has 1 line:

<?= $itemshelper->htmllist(); ?>

the output looks this:

  • foods
    • fruit
      • apple
      • banana
      • orange
    • veg
      • cucumber
      • lettuce
  • drinks
    • alcoholic
      • beer
      • vodka
  • misc
    • household objects
      • kitchen
        • electrical
          • cooking
            • stove
            • toaster
            • microwave

note: sql fiddle had 5 ("orange") parent_id cucumber , lettuce, had change 6 ("veg").


Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -