<?php
|
|
namespace App\Traits;
|
|
use Carbon\Carbon;
|
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Support\Arr;
|
|
trait SearchableExtended
|
{
|
/**
|
* The attributes that are searchable.
|
*
|
* @var array
|
*/
|
protected $searchable = [];
|
|
/**
|
* Apply filters in your QueryBuilder based in $fields
|
*
|
* @param \Illuminate\Database\Eloquent\Builder $queryBuilder
|
* @param array $fields
|
*
|
* @return Builder
|
*/
|
public function scopeSearchWithParams(Builder $queryBuilder, array $fields = []){
|
if (isset($this->searchable)) {
|
foreach ($fields as $field => $config) {
|
$operator = (is_array($config)) ? Arr::get($config, 'operator', config('searchable.logical_operators.and')) : config('searchable.logical_operators.and');
|
$value = (is_array($config) && Arr::has($config, "value")) ? Arr::get($config, 'value') : $config;
|
|
if (!is_null($value) && $this->_isSearchable($field)) {
|
$searchType = $this->_getSearchType($field, (is_array($config) ? $config : []));
|
|
if(!is_null($searchType)) {
|
$args = [
|
"field" => $field,
|
"value" => $value,
|
"operator" => $operator,
|
"where" => (strcasecmp($operator, config("searchable.logical_operators.or")) == 0) ? "orWhere" : "where",
|
"searchType" => $searchType,
|
];
|
|
if ($this->_callable($searchType)) {
|
$functionName = "_applySearch" . $searchType;
|
$this->$functionName($queryBuilder, $args);
|
} else {
|
$this->_callLocalScope($queryBuilder, $args);
|
}
|
}
|
}
|
}
|
}
|
|
return $queryBuilder;
|
}
|
|
/**
|
* @param $type
|
* @return bool
|
*/
|
protected function _callable($type)
|
{
|
return Arr::has(array_flip(config("searchable.filter_types")), $type);
|
}
|
|
/**
|
* Check if it is possible to perform a search on the indicated field
|
*
|
* @param string $field
|
* @return bool
|
*/
|
protected function _isSearchable(string $field)
|
{
|
return Arr::has($this->searchable, 'columns.' . $field);
|
}
|
|
/**
|
* Returns the type of search associated with the field
|
*
|
* @param string $field
|
* @param array|null $config
|
* @return mixed
|
*/
|
protected function _getSearchType(string $field, array $config = [])
|
{
|
$searchType = Arr::get($this->searchable, 'columns.' . $field, null);
|
|
if(!empty($config)) {
|
$searchType = Arr::get($config, "searchType", $searchType);
|
}
|
|
return $searchType;
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchBetween(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", []);
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if (is_array($value) && count($value) == 2 && !is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
if(isset($value[0]) && !empty($value[0])) {
|
$queryBuilder->$where($field, ">=", $value[0]);
|
}
|
if(isset($value[1]) && !empty($value[1])) {
|
$queryBuilder->$where($field, "<=", $value[1]);
|
}
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchLike(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", []);
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
array_map(function ($value) use ($queryBuilder, $field, $where) {
|
$queryBuilder->$where($field, "LIKE", "%" . $value . "%");
|
}, explode(" ", $value));
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchMatch(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", []);
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->$where($field, $value);
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchGreaterThan(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", []);
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->$where($field, ">", $value);
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchGreaterOrEqual(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", []);
|
$field = Arr::get($args, "field", null);
|
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->$where($field, ">=", $value);
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchLessThan(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", []);
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->$where($field, "<", $value);
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchLessOrEqual(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", []);
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->$where($field, "<=", $value);
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchDateGreaterThan(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", "");
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->$where($field, ">", Carbon::createFromFormat('d/m/Y', $value)->format("Y-m-d"));
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchDateGreaterOrEqual(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", "");
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->$where($field, ">=", Carbon::createFromFormat('d/m/Y', $value)->format("Y-m-d"));
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchDateLessThan(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", "");
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->$where($field, "<", Carbon::createFromFormat('d/m/Y', $value)->format("Y-m-d"));
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchDateLessOrEqual(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", "");
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->$where($field, "<=", Carbon::createFromFormat('d/m/Y', $value)->format("Y-m-d"));
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchDateGreaterThanNullable(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", "");
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->where(function ($query) use ($value, $field, $where) {
|
$query->$where($field, ">=", Carbon::createFromFormat('d/m/Y', $value)->format("Y-m-d"))
|
->orWhereNull($field);
|
});
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchDateGreaterOrEqualNullable(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", "");
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->where(function ($query) use ($value, $field, $where) {
|
$query->$where($field, ">=", Carbon::createFromFormat('d/m/Y', $value)->format("Y-m-d"))
|
->orWhereNull($field);
|
});
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchDateLessThanNullable(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", "");
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->where(function ($query) use ($value, $field, $where) {
|
$query->$where($field, "<", Carbon::createFromFormat('d/m/Y', $value)->format("Y-m-d"))
|
->orWhereNull($field);
|
});
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchDateLessOrEqualNullable(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", "");
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->where(function ($query) use ($value, $field, $where) {
|
$query->$where($field, "<=", Carbon::createFromFormat('d/m/Y', $value)->format("Y-m-d"))
|
->orWhereNull($field);
|
});
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchDifferent(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", []);
|
$field = Arr::get($args, "field", null);
|
$where = Arr::get($args, "where", config("searchable.logical_operators.and"));
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->$where($field, "<>", $value);
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _applySearchIn(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", []);
|
$field = Arr::get($args, "field", null);
|
|
if(!is_null($field)) {
|
$field = $this->getTable() . "." . $field;
|
$queryBuilder->whereIn($field, $value);
|
}
|
}
|
|
/**
|
* @param Builder $queryBuilder
|
* @param array $args
|
*/
|
protected function _callLocalScope(Builder &$queryBuilder, array $args)
|
{
|
$value = Arr::get($args, "value", []);
|
$scopeName = Arr::get($args, "searchType", null);
|
|
if(!is_null($scopeName)) {
|
$queryBuilder->{$scopeName}($value);
|
}
|
}
|
}
|