【发布时间】:2021-05-17 02:15:10
【问题描述】:
我正在创建一个房地产项目,该项目将为具有不同搜索过滤器的不同页面提供搜索选项。
这是搜索视图的一个示例
<form class="form-row basic-select-wrapper" method="POST" action="{{route('filter')}}">
@csrf
{{-- <div class="form-group">
<input type="text" name="prop_name">
</div> --}}
<div class="form-group col-lg col-md-6">
<label>Property type</label>
<select name="type_id" class="form-control basic-select">
<option>Select Type</option>
@foreach ($types as $type)
@if ($type->status == 1)
<option value="{{ $type->id }}">{{ $type->name }}</option>
@endif
@endforeach
</select>
</div>
<div class="form-group col-lg col-md-6">
<label>Property Category</label>
<select name="cat_id" class="form-control basic-select">
<option>Select Category</option>
@foreach ($categories as $category)
<option value="{{ $category->id }}">{{ $category->name }}</option>
@endforeach
</select>
</div>
<div class="form-group col-lg col-md-6">
<label>Location</label>
<select name="loc_id" class="form-control basic-select">
<option>Select Location</option>
@foreach ($locations as $location)
<option value="{{ $location->id }}">{{ $location->loc_name }}</option>
@endforeach
</select>
</div>
<div class="form-group col-lg col-md-6">
<label>Budget</label>
<select name="start_price" class="form-control basic-select">
<option>Select Budget</option>
@foreach($price['price'] as $key => $val)
<option value="{{$key}}">{{$val}}</option>
@endforeach
</select>
</div>
<div class="form-group col-lg col-md-6">
<label>Bedroom(s)</label>
<select name="min_bed" class="form-control basic-select">
<option>Select Bedroom</option>
<option value="0">studio</option>
<option value="1">one bedroom</option>
<option value="2">two bedroom</option>
<option value="3">three bedroom</option>
<option value="4">four bedroom</option>
<option value="5">five bedroom</option>
<option value="6">six bedroom</option>
<option value="7">seven bedroom</option>
</select>
</div>
<div class="advanced-search" id="advanced-search">
<div class="card card-body">
<div class="form-group col-md-12">
<div class="mt-0">
<button class="btn btn-primary align-items-center" type="submit"><i
class="fas fa-search mr-1"></i><span>Search</span></button>
</div>
</div>
</div>
</div>
</form>
这是我的搜索控制器
<?php
namespace App\Http\Controllers\User;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
//use App\Models\Listing;
use App\ListingSearch\ListingSearch;
class SearchController extends Controller
{
public function filter(Request $request)
{
return ListingSearch::apply($request);
}
}
现在,要实现这一点,因为有多个搜索过滤器,我想简化它。这是文件夹结构 folder structure
这是Listitng搜索类
<?php
namespace App\ListingSearch;
use Illuminate\Database\Eloquent\Builder;
use App\Models\Listing;
use Illuminate\Http\Request;
class ListingSearch
{
public static function apply(Request $filters)
{
$query = static::applyDecoratorsFromRequest(
$filters, (new Listing)->newQuery()
);
// Get the results and return them.
return static::getResults($query);
}
private static function applyDecoratorsFromRequest(Request $request, Builder $query)
{
foreach ($request->all() as $filterName => $value) {
$decorator = static::createFilterDecorator($filterName);
if (static::isValidDecorator($decorator)) {
$query = $decorator::apply($query, $value);
}
}
return $query;
}
private static function createFilterDecorator($name)
{
return __NAMESPACE__ . '\\Filters\\' .
str_replace(' ', '',
ucwords(str_replace('_', ' ', $name)));
}
private static function isValidDecorator($decorator)
{
return class_exists($decorator);
}
private static function getResults(Builder $query)
{
return $query->get();
}
}
这是类别过滤器 CATID 之一的示例
<?php
namespace App\ListingSearch\Filters;
use Illuminate\Database\Eloquent\Builder;
class CatId implements Filter
{
public static function apply($builder, $value)
{
return $builder->where('cat_id', $value);
}
}
这样做的问题是我必须输入所有必需的过滤器才能获得结果,否则如果我只填写一个过滤器我会得到空结果,例如我只想要公寓,而不输入位置或类别。我怎样才能做到这一点?
【问题讨论】: