laravel에서 trait를 이용한 트리구조 메뉴 만들기
예를 들어 아래와 같은 데이터를 DB에서 가져왔다고 가정을 한다.
$rows = [ ['id' => 1, 'pid' => 0, 'name' => '메뉴A'], ['id' => 2, 'pid' => 0, 'name' => '메뉴B'], ['id' => 3, 'pid' => 1, 'name' => '메뉴A-1'], ['id' => 4, 'pid' => 1, 'name' => '메뉴A-2'], ['id' => 5, 'pid' => 2, 'name' => '메뉴B-1'], ];
위의 데이터는 아래의 과정을 거쳐서 트리구조의 배열(객체)로 변한다.
namespace App\Traits;
use Illuminate\Support\Arr;
trait TraitMenu
{
protected $menus = []; // 메뉴가 없을 시 forelse에서 문제가 없도록 처리함.
protected $byId;
public function getMenus($rows)
{
foreach ($rows as $row) {
$id = $row['id'];
$parentId = $row['pid'];
$entry = $row;
$entry['submenus'] = empty($this->byId[$id]['submenus']) ? [] : $this->byId[$id]['submenus'];
if ($parentId === 0) {
$this->menus[] = $entry;
} else {
// $rows가 객체로 DB에서 받아온 객체(콜렉션 형태)라서 직접 수정은 불가능함.
// 방법 1(스스로 만든 방법)
$collet = collect($this->byId[$parentId]['submenus']);
$collet->push($entry);
$this->byId[$parentId]['submenus'] = $collet;
// 방법 2
// $sub = $this->byId[$parentId]['submenus'];
// $sub[] = $entry;
// $this->byId[$parentId]['submenus'] = $sub;
}
$this->byId[$id] = $entry;
}
return $this->menus;
}
}