pedi2/app/Filtros/Filtro.php

75 lines
2.3 KiB
PHP
Raw Normal View History

2022-01-05 18:14:21 -03:00
<?php
namespace App\Filtros;
2022-01-05 18:14:21 -03:00
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Builder;
class Filtro extends Model
{
protected $request;
protected $builder;
protected $MENSAJES_ERROR = [
'ARGUMENTO' => 'Argumento inválido para el parámetro %s. Revise la documentación.'
];
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Apply all existing filters, if available.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @return \Illuminate\Database\Eloquent\Builder
*/
public function aplicar(Builder $builder)
{
$this->builder = $builder;
//Aplicar filtros que aparecen en los parámetros, si los hay
$filtros = $this->request->all();
//el filtro nombre debe tomar precedencia sobre otros como (alfabetico)
if ($filtros["nombre"]) {
$nombre = $filtros["nombre"];
unset($filtros["nombre"]);
$filtros = array_merge(["nombre" => $nombre],$filtros);
}
foreach($filtros as $filtro => $valor) {
2022-01-05 18:14:21 -03:00
//Obtener nombre del método (snake_case a camelCase)
$metodo = str_replace('_', '', lcfirst(ucwords($filtro, '_')));
if(!method_exists($this, $metodo)) { continue; }
//Llamar métodos sin argumentos
if ($valor === null|| (is_a($valor,'String') && trim($valor)=='')){ $this->$metodo(); continue; }
//Llamar métodos con argumentos
try {
$this->$metodo($valor);
} catch (\Throwable $th) {
if (is_a($th,'TypeError') ) { throw new HttpException(400, sprintf($this->MENSAJES_ERROR['ARGUMENTO'],$filtro)); }
throw $th;
}
}
return $this->builder;
}
//Buscar un término en el nombre
public function nombre(String $valor)
{
$this->builder->where('nombre', "LIKE", "%" . $valor . "%")->orderByRaw("IF(nombre = '{$valor}',2,IF(nombre LIKE '{$valor}%',1,0)) DESC");
}
public function alfabetico(String $order = 'asc')
2022-01-05 18:14:21 -03:00
{
if(!in_array($order,['asc','desc'])) { throw new TypeError(); }
$this->builder->orderBy('nombre', $order);
2022-01-05 18:14:21 -03:00
}
}