Laravel repository search concat first name and last name using criterias
Table of contents
Hi everyone today i want to show you how to make filter search name by combine first name and last name in database field using laravel repository with implement request criteria refer to this l5-repository.
Database Scheme
first we have a database with user table and have some field like this.
field | type |
varchar | |
first_name | varchar |
last_name | varchar |
Repository file
lets assume you have a repository to get all user data lets say its called UserRepository and we want to give search condition like this https://app.test/v1/users?search=name:John
which is John can be first name or last name in database above we never know, so take a look this code
namespace App;
use Prettus\Repository\Eloquent\BaseRepository;
use App\Criterias\UserFullNameCriteria;
class UserRepository extends BaseRepository
{
protected $fieldSearchable = [
'name',
'email',
];
public function boot()
{
if (request()->has('search')){
$searchFields = explodeSearch(request('search'));
if (isset($searchFields['name']))
{
$this->pushCriteria(new UserFullNameCriteria($searchFields['name']));
}
}
}
public function explodeSearch(array $searchFields)
{
$search = array_map(function($val) {
return explode(':', $val);
}, explode(';', $searchFields));
$fieldNames = array();
foreach ($search as $s)
{
$fieldNames[$s[0]] = $s[1];
}
return $fieldNames;
}
}
explaination
look at boot() function the first step we determine if request has search request()->has('search')
then create a function to explode search content with explodeSearch()
function, that will make our search can be determinate if we want to search by name
like this /v1/users?search=name:John;email:@gmail
.
Pay attention on this function $this->pushCriteria()
we are gonna include criteria in this function, so you must create Criteria like this
use Prettus\Repository\Contracts\RepositoryInterface;
use Prettus\Repository\Contracts\CriteriaInterface;
class UserFullNameCriteria implements CriteriaInterface {
private $name;
public function __construct($name)
{
$this->name = $name;
}
public function apply($model, RepositoryInterface $repository)
{
$search = $this->name;
return $model->where(function ($query) use ($search){
$query->orWhere('first_name', 'like', '%'.$search.'%')
->orWhere('last_name', 'like', '%'.$search.'%');
});
}
}
after all above we can implement the repository in our controller or task if you are using laravel apiato
namespace App\Http\Controllers;
use App\UserRepository;
class UserController extends BaseController {
/**
* @var UserRepository
*/
protected $repository;
public function __construct(UserRepository $repository){
$this->repository = $repository;
}
....
}
if you are using Laravel-apiato implement this repository in Task
<?php
namespace App\Containers\AppSection\User\Tasks;
use Apiato\Core\Exceptions\CoreInternalErrorException;
use App\Containers\AppSection\User\Data\Repositories\CustomerRepository;
use App\Ship\Parents\Tasks\Task as ParentTask;
use Prettus\Repository\Exceptions\RepositoryException;
class GetAllCustomersTask extends ParentTask
{
public function __construct(
protected UserRepository $repository
) {
}
/**
* @throws CoreInternalErrorException
* @throws RepositoryException
*/
public function run(): mixed
{
return $this->addRequestCriteria()->repository->latest()->paginate();
}
}
Remember our criteria automaticaly implement when UserRepository initiate, because we include $this->pushCriteria()
in boot()
method inside UserRepository class.
Test with your tools
you can use POSTMAN or INSOMNIA to test our API.
access your endpoint /v1/users?search=name:John
, this will return a result including first_name or last_name