Viewing file: RequestCriteria.php (12.63 KB) -rw-rw-rw- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
<?php namespace Prettus\Repository\Criteria;
use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Http\Request; use Illuminate\Support\Str; use Prettus\Repository\Contracts\CriteriaInterface; use Prettus\Repository\Contracts\RepositoryInterface;
/** * Class RequestCriteria * @package Prettus\Repository\Criteria * @author Anderson Andrade <contato@andersonandra.de> */ class RequestCriteria implements CriteriaInterface { /** * @var \Illuminate\Http\Request */ protected $request;
public function __construct(Request $request) { $this->request = $request; }
/** * Apply criteria in query repository * * @param Builder|Model $model * @param RepositoryInterface $repository * * @return mixed * @throws \Exception */ public function apply($model, RepositoryInterface $repository) { $fieldsSearchable = $repository->getFieldsSearchable(); $search = $this->request->get(config('repository.criteria.params.search', 'search'), null); $searchFields = $this->request->get(config('repository.criteria.params.searchFields', 'searchFields'), null); $filter = $this->request->get(config('repository.criteria.params.filter', 'filter'), null); $orderBy = $this->request->get(config('repository.criteria.params.orderBy', 'orderBy'), null); $sortedBy = $this->request->get(config('repository.criteria.params.sortedBy', 'sortedBy'), 'asc'); $with = $this->request->get(config('repository.criteria.params.with', 'with'), null); $withCount = $this->request->get(config('repository.criteria.params.withCount', 'withCount'), null); $searchJoin = $this->request->get(config('repository.criteria.params.searchJoin', 'searchJoin'), null); $sortedBy = !empty($sortedBy) ? $sortedBy : 'asc';
if ($search && is_array($fieldsSearchable) && count($fieldsSearchable)) {
$searchFields = is_array($searchFields) || is_null($searchFields) ? $searchFields : explode(';', $searchFields); $isFirstField = true; $searchData = $this->parserSearchData($search); $fields = $this->parserFieldsSearch($fieldsSearchable, $searchFields, array_keys($searchData)); $search = $this->parserSearchValue($search); $modelForceAndWhere = strtolower($searchJoin) === 'and';
$model = $model->where(function ($query) use ($fields, $search, $searchData, $isFirstField, $modelForceAndWhere) { /** @var Builder $query */
foreach ($fields as $field => $condition) {
if (is_numeric($field)) { $field = $condition; $condition = "="; }
$value = null;
$condition = trim(strtolower($condition));
if (isset($searchData[$field])) { $value = ($condition == "like" || $condition == "ilike") ? "%{$searchData[$field]}%" : $searchData[$field]; } else { if (!is_null($search) && !in_array($condition,['in','between'])) { $value = ($condition == "like" || $condition == "ilike") ? "%{$search}%" : $search; } }
$relation = null; if(stripos($field, '.')) { $explode = explode('.', $field); $field = array_pop($explode); $relation = implode('.', $explode); } if($condition === 'in'){ $value = explode(',',$value); if( trim($value[0]) === "" || $field == $value[0]){ $value = null; } } if($condition === 'between'){ $value = explode(',',$value); if(count($value) < 2){ $value = null; } } $modelTableName = $query->getModel()->getTable(); if ( $isFirstField || $modelForceAndWhere ) { if (!is_null($value)) { if(!is_null($relation)) { $query->whereHas($relation, function($query) use($field,$condition,$value) { if($condition === 'in'){ $query->whereIn($field,$value); }elseif($condition === 'between'){ $query->whereBetween($field,$value); }else{ $query->where($field,$condition,$value); } }); } else { if($condition === 'in'){ $query->whereIn($modelTableName.'.'.$field,$value); }elseif($condition === 'between'){ $query->whereBetween($modelTableName.'.'.$field,$value); }else{ $query->where($modelTableName.'.'.$field,$condition,$value); } } $isFirstField = false; } } else { if (!is_null($value)) { if(!is_null($relation)) { $query->orWhereHas($relation, function($query) use($field,$condition,$value) { if($condition === 'in'){ $query->whereIn($field,$value); }elseif($condition === 'between'){ $query->whereBetween($field, $value); }else{ $query->where($field,$condition,$value); } }); } else { if($condition === 'in'){ $query->orWhereIn($modelTableName.'.'.$field, $value); }elseif($condition === 'between'){ $query->whereBetween($modelTableName.'.'.$field,$value); }else{ $query->orWhere($modelTableName.'.'.$field, $condition, $value); } } } } } }); }
if (isset($orderBy) && !empty($orderBy)) { $orderBySplit = explode(';', $orderBy); if(count($orderBySplit) > 1) { $sortedBySplit = explode(';', $sortedBy); foreach ($orderBySplit as $orderBySplitItemKey => $orderBySplitItem) { $sortedBy = isset($sortedBySplit[$orderBySplitItemKey]) ? $sortedBySplit[$orderBySplitItemKey] : $sortedBySplit[0]; $model = $this->parserFieldsOrderBy($model, $orderBySplitItem, $sortedBy); } } else { $model = $this->parserFieldsOrderBy($model, $orderBySplit[0], $sortedBy); } }
if (isset($filter) && !empty($filter)) { if (is_string($filter)) { $filter = explode(';', $filter); }
$model = $model->select($filter); }
if ($with) { $with = explode(';', $with); $model = $model->with($with); }
if ($withCount) { $withCount = explode(';', $withCount); $model = $model->withCount($withCount); }
return $model; }
/** * @param $model * @param $orderBy * @param $sortedBy * @return mixed */ protected function parserFieldsOrderBy($model, $orderBy, $sortedBy) { $split = explode('|', $orderBy); if(count($split) > 1) { /* * ex. * products|description -> join products on current_table.product_id = products.id order by description * * products:custom_id|products.description -> join products on current_table.custom_id = products.id order * by products.description (in case both tables have same column name) */ $table = $model->getModel()->getTable(); $sortTable = $split[0]; $sortColumn = $split[1];
$split = explode(':', $sortTable); $localKey = '.id'; if (count($split) > 1) { $sortTable = $split[0];
$commaExp = explode(',', $split[1]); $keyName = $table.'.'.$split[1]; if (count($commaExp) > 1) { $keyName = $table.'.'.$commaExp[0]; $localKey = '.'.$commaExp[1]; } } else { /* * If you do not define which column to use as a joining column on current table, it will * use a singular of a join table appended with _id * * ex. * products -> product_id */ $prefix = Str::singular($sortTable); $keyName = $table.'.'.$prefix.'_id'; }
$model = $model ->leftJoin($sortTable, $keyName, '=', $sortTable.$localKey) ->orderBy($sortColumn, $sortedBy) ->addSelect($table.'.*'); } else { $model = $model->orderBy($orderBy, $sortedBy); } return $model; }
/** * @param $search * * @return array */ protected function parserSearchData($search) { $searchData = [];
if (stripos($search, ':')) { $fields = explode(';', $search);
foreach ($fields as $row) { try { list($field, $value) = explode(':', $row); $searchData[$field] = $value; } catch (\Exception $e) { //Surround offset error } } }
return $searchData; }
/** * @param $search * * @return null */ protected function parserSearchValue($search) {
if (stripos($search, ';') || stripos($search, ':')) { $values = explode(';', $search); foreach ($values as $value) { $s = explode(':', $value); if (count($s) == 1) { return $s[0]; } }
return null; }
return $search; }
protected function parserFieldsSearch(array $fields = [], array $searchFields = null, array $dataKeys = null) { if (!is_null($searchFields) && count($searchFields)) { $acceptedConditions = config('repository.criteria.acceptedConditions', [ '=', 'like' ]); $originalFields = $fields; $fields = [];
foreach ($searchFields as $index => $field) { $field_parts = explode(':', $field); $temporaryIndex = array_search($field_parts[0], $originalFields);
if (count($field_parts) == 2) { if (in_array($field_parts[1], $acceptedConditions)) { unset($originalFields[$temporaryIndex]); $field = $field_parts[0]; $condition = $field_parts[1]; $originalFields[$field] = $condition; $searchFields[$index] = $field; } } }
if (!is_null($dataKeys) && count($dataKeys)) { $searchFields = array_unique(array_merge($dataKeys, $searchFields)); }
foreach ($originalFields as $field => $condition) { if (is_numeric($field)) { $field = $condition; $condition = "="; } if (in_array($field, $searchFields)) { $fields[$field] = $condition; } }
if (count($fields) == 0) { throw new \Exception(trans('repository::criteria.fields_not_accepted', ['field' => implode(',', $searchFields)])); }
}
return $fields; } }
|