Short of seeing the exact output you want if it's a report style see http://dsmithweb.com/itemized.png and http://laravel.io/forum/04-04-2015-looping-through-collection
Laravel 5.x Pagination and recursive child categories.
Hey everyone, So I managed to finish my infinite nested categories. It was kind of simple and difficult at same time. I’m not really good with recursions. The reason of this post, if there is some way to optimize this code a little bit more.
So my controller looks like this:
public function index()
{
$categories = Category::all();
$categoriesPaged = $this->buildArray($categories->toArray());
$categoriesPaged = $this->paginate($categoriesPaged, 15, 1);
return view('admin.categories.index', ['pagedCategories' => $categoriesPaged, 'categories' => $categories]);
}
After getting all the categories, I transform the object toArray. The reason is pretty simple to reorder them in this genre. -Parent(Depth 0) --Children (Depth 1) ---Children (Depth 2) --Children (Depth 1) --Children (Depth 1) -Parent(Depth 0) So buildArray function looks like this:
function buildArray(array $objects, array &$result=array(), $parent=0, $depth=0)
{
foreach ($objects as $key => $object) {
if ($object['parent_id'] == $parent) {
$object['depth'] = $depth;
array_push($result, $object);
unset($objects[$key]);
CategoriesController::buildArray($objects, $result, $object['id'], $depth + 1);
}
}
return $result;
}
The result is next and you can see all the camps they have:
array:6 [▼
0 => array:9 [▼
"id" => 1
"parent_id" => 0
"user_id" => 1
"slug" => "categoria-1"
"name" => "Categoria 1"
"description" => "Descrição da categoria 1"
"created_at" => "2016-01-10 01:15:43"
"updated_at" => "2016-01-10 01:15:43"
"depth" => 0
]
1 => array:9 [▼
"id" => 2
"parent_id" => 1
"user_id" => 1
"slug" => "igors-sigalovs-11"
"name" => "Igors Sigalovs"
"description" => "Descrição da categoria 1"
"created_at" => "2016-01-10 10:35:18"
"updated_at" => "2016-01-10 10:35:18"
"depth" => 1
]
2 => array:9 [▼
"id" => 9
"parent_id" => 2
"user_id" => 1
"slug" => "igors-sigalovs-1"
"name" => "Igors Sigalovs"
"description" => "Descrição da categoria 1"
"created_at" => "2016-01-10 12:58:06"
"updated_at" => "2016-01-10 12:58:06"
"depth" => 2
]
3 => array:9 [▼
"id" => 8
"parent_id" => 1
"user_id" => 1
"slug" => "igors-sigalovs"
"name" => "Igors Sigalovs"
"description" => "Descrição da categoria 1"
"created_at" => "2016-01-10 01:32:35"
"updated_at" => "2016-01-10 01:32:35"
"depth" => 1
]
4 => array:9 [▼
"id" => 6
"parent_id" => 0
"user_id" => 1
"slug" => "test"
"name" => "Test"
"description" => "test"
"created_at" => "2016-01-10 01:31:43"
"updated_at" => "2016-01-10 01:31:43"
"depth" => 0
]
5 => array:9 [▶]
]
After rearranging them, I create custom paginator with laravel help:
public function paginate($items,$perPage,$pageStart=1)
{
$page = Input::get('page', $pageStart);
$offset = ($page * $perPage) - $perPage;
return new LengthAwarePaginator(array_slice($items, $offset, $perPage, true), count($items), $perPage, $page, ['path' => Request::url(), 'query' => Request::query()]);;
}
And here is where my doubt about optimal solution is. Imagine that I set my $perPage variable to 2. The query would just bring 2 elements and on page 2 in order to get Parent name instead of ID, I have to pass all the categories in order to it can search though the array. So passing full data and partial data twice, seems a bit fishy. Example: https://i.gyazo.com/7215db2893c4e5034d422aa945d2edba.png In order to search though the array in view I used this solution.
@foreach($pagedCategories as $category)
<tr>
<td>{{$category['name']}}</td>
<td>{{$category['description']}}</td>
<td>{{$category['slug']}}</td>
<td>@if($category['depth'] == 0) --- @else {{$categories[array_search($category['parent_id'], array_column($categories->toArray(), 'id'))]['name']}} @endif</td>
…
It works like a charm, still it feels like there is a better solution. Also I don’t want to use nor ajax, nor jquery to get a solution. So any tips on improving this?
Please or to participate in this conversation.