77 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
	
		
			2.3 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| namespace App\Filtros;
 | |
| 
 | |
| use Illuminate\Database\Eloquent\Model;
 | |
| use Illuminate\Http\Request;
 | |
| use Illuminate\Database\Eloquent\Builder;
 | |
| use Symfony\Component\HttpKernel\Exception\HttpException;
 | |
| use Throwable;
 | |
| use TypeError;
 | |
| 
 | |
| class Filtro extends Model
 | |
| {
 | |
|     protected Request $request;
 | |
|     protected $builder;
 | |
|     protected array $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 Builder $builder
 | |
|      * @return Builder
 | |
|      */
 | |
|     public function aplicar(Builder $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);
 | |
|     }
 | |
| }
 |