I have product catalog with 4 subcategory levels
routes/web.php
Route::get('/products/{level2?}/{level3?}/{level4?}', 'ProductController@showIndex');
Route::get('/products/{level2?}/{level2prod?}/{level3?}/{level3prod?}/{level4?}/{level4prod?}', 'ProductController@showProduct');
First route is showing categories with corresponding products, which are children to current category. Between Product and Category models there is ManytoMany relationship $this->belongsToMany. And I have category_product pivot table.
showProduct function in ProductController receives $request and I extract last 2 segments out of $request->path(). Last path segment is equal to current product sef - this is the most important info to load product page. Previous path segment is equal to parent category sef. This is needed to know under which category we are located now. Because one product could belong to many categories and we don't know how current product page was loaded. In this case I use $category to load breadcrumbs like that
Home > Products > Category level 2 > Category level3 > Category level4
public function showProduct(Request $request) {
$parent = '';
$categorysef = '';
// we need only last part of uri after last slash
if ( strrpos($request->path(), '/') !== false ) {
$sef = substr($request->path(), strrpos($request->path(), '/') + 1);
$parent = substr($request->path(), 0, strrpos($request->path(), '/') );
if ( strrpos($parent, '/') !== false ) {
$categorysef = substr($parent, strrpos($parent, '/') + 1);
}
else {$categorysef = $parent;}
} else {
$sef = $request->path();
}
$item = Product::whereSef($sef)->firstorfail();
$previous = Product::where('id', '<', $item->id)->orderBy('id', 'desc')->first();
$next = Product::where('id', '>', $item->id)->orderBy('id', 'asc')->first();
$category = Category::whereSef($categorysef)->firstorfail();
return view('product.item')
->withItem($item)
->withPrevious($previous)
->withNext($next)
->withCategory($category);
}
One thing I cannot understand is how to filter $previous and $next to contain only values belongsTo current category.
{level2?}/{level2prod?}/{level3?}/{level3prod?}/{level4?}/{level4prod?}
. You'd physically have to putnull
in the URL to achieve this, like/null/null/example/level3
, otherwise/example/level3
would, to you, map to level3, but the the program would map to level2. – Tim Lewislevel2
, and has 2 params, one for level3 and level4, you'll navigate to a route that is handled by level2 and level3. – Tim Lewis