initial commit
This commit is contained in:
commit
ae93c7e1a6
233 changed files with 20282 additions and 0 deletions
100
backend/app/Http/Controllers/ProductController.php
Normal file
100
backend/app/Http/Controllers/ProductController.php
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Requests\ProductIndexRequest;
|
||||
use App\Http\Resources\ProductResource;
|
||||
use App\Models\Category;
|
||||
use App\Models\Product;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
|
||||
class ProductController extends Controller
|
||||
{
|
||||
public function index(ProductIndexRequest $request): AnonymousResourceCollection
|
||||
{
|
||||
$query = Product::query()
|
||||
->with(['category:id,name,slug', 'brand:id,name,slug'])
|
||||
->active()
|
||||
->whereNotNull('published_at')
|
||||
->orderByDesc('published_at')
|
||||
->orderByDesc('id');
|
||||
|
||||
$this->applySearchFilter($query, (string) ($request->validated('q') ?? ''));
|
||||
$this->applyCategoryFilter($query, $request->validated('category'));
|
||||
|
||||
$paginator = $query->paginate(24)->appends($request->query());
|
||||
|
||||
return ProductResource::collection($paginator);
|
||||
}
|
||||
|
||||
private function applySearchFilter(Builder $query, string $search): void
|
||||
{
|
||||
$search = trim($search);
|
||||
|
||||
if ($search !== '') {
|
||||
$query->where(function (Builder $builder) use ($search): void {
|
||||
$builder
|
||||
->where('name', 'like', "%{$search}%")
|
||||
->orWhere('description', 'like', "%{$search}%")
|
||||
->orWhere('sku', 'like', "%{$search}%");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private function applyCategoryFilter(Builder $query, mixed $categorySlug): void
|
||||
{
|
||||
if (is_string($categorySlug) && $categorySlug !== '') {
|
||||
$category = Category::query()
|
||||
->where('slug', $categorySlug)
|
||||
->first();
|
||||
|
||||
if (! $category instanceof Category) {
|
||||
return;
|
||||
}
|
||||
|
||||
$query->whereIn('category_id', $this->collectDescendantCategoryIds($category->id));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<int>
|
||||
*/
|
||||
private function collectDescendantCategoryIds(int $rootCategoryId): array
|
||||
{
|
||||
/** @var Collection<int, Category> $categories */
|
||||
$categories = Category::query()
|
||||
->select(['id', 'parent_id'])
|
||||
->get();
|
||||
|
||||
$byParent = [];
|
||||
|
||||
foreach ($categories as $category) {
|
||||
if ($category->parent_id === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$byParent[$category->parent_id][] = (int) $category->id;
|
||||
}
|
||||
|
||||
$stack = [$rootCategoryId];
|
||||
$seen = [];
|
||||
|
||||
while ($stack !== []) {
|
||||
$categoryId = array_pop($stack);
|
||||
|
||||
if ($categoryId === null || isset($seen[$categoryId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$seen[$categoryId] = true;
|
||||
|
||||
foreach ($byParent[$categoryId] ?? [] as $childId) {
|
||||
$stack[] = $childId;
|
||||
}
|
||||
}
|
||||
|
||||
return array_map('intval', array_keys($seen));
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue