wip
This commit is contained in:
98
app/Helpers/Ecommerce/Product/Filter/ProductFilterer.php
Normal file
98
app/Helpers/Ecommerce/Product/Filter/ProductFilterer.php
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace App\Helpers\Ecommerce\Product\Filter;
|
||||
|
||||
use App\Rules\CommaSeparatedIntegers;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class ProductFilterer
|
||||
{
|
||||
/*
|
||||
* Query builder
|
||||
*/
|
||||
protected $queryBuilder;
|
||||
|
||||
/**
|
||||
* Request
|
||||
*/
|
||||
protected Request $request;
|
||||
|
||||
/**
|
||||
* Product filterer
|
||||
*/
|
||||
public function __construct($queryBuilder, $request)
|
||||
{
|
||||
$this->queryBuilder = $queryBuilder;
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create "new" class via static method
|
||||
*/
|
||||
public static function make($queryBuilder, $request): self
|
||||
{
|
||||
return new self($queryBuilder, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the request
|
||||
*/
|
||||
public function validateRequest(): \Illuminate\Contracts\Validation\Validator
|
||||
{
|
||||
return Validator::make($this->request->all(), [
|
||||
'ids' => ['nullable', 'string', new CommaSeparatedIntegers()],
|
||||
'brands' => ['nullable', 'string', new CommaSeparatedIntegers()],
|
||||
'categories' => ['nullable', 'string', new CommaSeparatedIntegers()],
|
||||
'name' => ['nullable', 'string', 'max:255'],
|
||||
'min_price' => ['nullable', 'numeric'],
|
||||
'max_price' => ['nullable', 'numeric'],
|
||||
'backorder' => ['nullable', 'in:0,1'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort
|
||||
*/
|
||||
public function filter()
|
||||
{
|
||||
if ($this->validateRequest()->fails()) {
|
||||
return $this->queryBuilder;
|
||||
}
|
||||
|
||||
if ($this->request->filled('brands')) {
|
||||
$this->queryBuilder->whereIntegerInRaw('products.brand_id', explode(',', $this->request->brands));
|
||||
}
|
||||
|
||||
if ($this->request->filled('categories')) {
|
||||
$this->queryBuilder->whereIn(
|
||||
column: 'id',
|
||||
values: (
|
||||
fn ($query) => $query->from('product_has_relations')
|
||||
->select('product_id')
|
||||
->distinct('product_id')
|
||||
->where('productable_type', '=', 'category')
|
||||
->whereIn('productable_id', explode(',', $this->request->categories))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->request->filled('name')) {
|
||||
$this->queryBuilder->where('products.name', 'ilike', $this->request->name.'%');
|
||||
}
|
||||
|
||||
if ($this->request->filled('min_price')) {
|
||||
$this->queryBuilder->whereRaw('products.price_amount::NUMERIC >= ?', [$this->request->float('min_price')]);
|
||||
}
|
||||
|
||||
if ($this->request->filled('max_price')) {
|
||||
$this->queryBuilder->whereRaw('products.price_amount::NUMERIC <= ?', [$this->request->float('max_price')]);
|
||||
}
|
||||
|
||||
if ($this->request->filled('backorder')) {
|
||||
$this->queryBuilder->where('products.backorder', $this->request->backorder);
|
||||
}
|
||||
|
||||
return $this->queryBuilder;
|
||||
}
|
||||
}
|
||||
96
app/Helpers/Ecommerce/Product/Sort/ProductSorter.php
Normal file
96
app/Helpers/Ecommerce/Product/Sort/ProductSorter.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
namespace App\Helpers\Ecommerce\Product\Sort;
|
||||
|
||||
use App\Rules\SortableColumnRule;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
|
||||
class ProductSorter
|
||||
{
|
||||
/*
|
||||
* Query builder
|
||||
*/
|
||||
protected mixed $queryBuilder;
|
||||
|
||||
/**
|
||||
* Request
|
||||
*/
|
||||
protected Request $request;
|
||||
|
||||
/**
|
||||
* Allowed columns for sorting
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
protected array $allowedColumns = [
|
||||
'price_amount',
|
||||
'created_at',
|
||||
'name',
|
||||
];
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct($queryBuilder, $request)
|
||||
{
|
||||
$this->queryBuilder = $queryBuilder;
|
||||
$this->request = $request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct statically
|
||||
*/
|
||||
public static function make($queryBuilder, $request): self
|
||||
{
|
||||
return new self($queryBuilder, $request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the request
|
||||
*/
|
||||
public function validateRequest(): \Illuminate\Contracts\Validation\Validator
|
||||
{
|
||||
return Validator::make($this->request->all(), [
|
||||
'sorting' => ['nullable', 'string', new SortableColumnRule($this->allowedColumns)],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort from request
|
||||
*/
|
||||
public function sort()
|
||||
{
|
||||
if ($this->request->isNotFilled('sorting') || $this->validateRequest()->fails()) {
|
||||
return $this->orderByLatest();
|
||||
}
|
||||
|
||||
return $this->queryBuilder->orderBy($this->getColumn(), $this->getSortType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sort column
|
||||
*/
|
||||
public function getColumn(): string
|
||||
{
|
||||
return explode('-', $this->request->sorting)[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sort type
|
||||
*/
|
||||
public function getSortType(): string
|
||||
{
|
||||
$sortType = explode('-', $this->request->sorting)[1];
|
||||
|
||||
return $sortType === 'descending' ? 'DESC' : 'ASC';
|
||||
}
|
||||
|
||||
/**
|
||||
* Order by latest (created_at)
|
||||
*/
|
||||
public function orderByLatest(): mixed
|
||||
{
|
||||
return $this->queryBuilder->latest();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user