pedi2/app/Filtros/Filtro.php

75 lines
2.3 KiB
PHP

<?php
namespace App\Filtros;
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 (isset($filtros["nombre"])) {
$nombre = $filtros["nombre"];
unset($filtros["nombre"]);
$filtros = array_merge(["nombre" => $nombre],$filtros);
}
foreach($filtros as $filtro => $valor) {
//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')
{
if(!in_array($order,['asc','desc'])) { throw new TypeError(); }
$this->builder->orderBy('nombre', $order);
}
}