Laravel repository search concat first name and last name using criterias

Laravel repository search concat first name and last name using criterias

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.

fieldtype
emailvarchar
first_namevarchar
last_namevarchar

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

Did you find this article valuable?

Support Belajar Backend by becoming a sponsor. Any amount is appreciated!