Skip to content

Instantly share code, notes, and snippets.

@ManojKiranA
Last active September 11, 2019 05:32
Show Gist options
  • Save ManojKiranA/bd2cce69c4dfc60b7602227b1828a9c1 to your computer and use it in GitHub Desktop.
Save ManojKiranA/bd2cce69c4dfc60b7602227b1828a9c1 to your computer and use it in GitHub Desktop.

using the Macro on Builder

will work work on both the Eloquent Builder and also the Query Builder

    use Illuminate\Database\Eloquent\Builder;

    Builder::macro('search', function ( $tableFields, $searchValues, $splitOn = null, $addOwnWildCard = true) {

        $tableFields = (array) $tableFields;
        $searchValues = (array) $searchValues;

        if ($splitOn !== null && array_filter($splitOn) !== []) {
            foreach ($searchValues as  $searchTerm) {
                $splitOnSpaceArray[] = explode(chr(1), str_replace($splitOn, chr(1), $searchTerm));
            }
            $searchValues = \Illuminate\Support\Arr::collapse($splitOnSpaceArray);
        }
        if ($addOwnWildCard) {
            foreach ($searchValues as  $searchTerm) {
                $addWildOnEach[] = "%{$searchTerm}%";
            }
            $searchValues = $addWildOnEach;
        }
        $this->orWhere(function ($query) use ($tableFields, $searchValues) {
            foreach ($tableFields as $attribute) {
                $query->orWhere(function ($query) use ($attribute, $searchValues) {
                    foreach ($searchValues as $searchTerm) {
                        $query->orWhere($attribute, 'LIKE', $searchTerm);
                    }
                });
            }
        });

        return $this;
    });


 /**
 * Scope a query for Wild Card Search
 *
 * @author Manojkiran.A <manojkiran10031998@gmail.com>
 * @param  \Illuminate\Database\Eloquent\Builder $builderQuery
 * @param string|array $tableFields
 * @param string|array $searchValues
 * @param array|null $splitOn
 * @see https://freek.dev/1182-searching-models-using-a-where-like-query-in-laravel
 * @return \Illuminate\Database\Eloquent\Builder
 */
public function scopeSearch($builderQuery, $tableFields, $searchValues, $splitOn = null, $addOwnWildCard = true)
{
    $tableFields = (array) $tableFields;
    $searchValues = (array) $searchValues;

    if ($splitOn !== null && array_filter($splitOn) !== []) {
        foreach ($searchValues as  $searchTerm) {
            $splitOnSpaceArray[] = explode(chr(1), str_replace($splitOn, chr(1), $searchTerm));
        }
        $searchValues = \Illuminate\Support\Arr::collapse($splitOnSpaceArray);
    }
    if ($addOwnWildCard) {
        foreach ($searchValues as  $searchTerm) {
            $addWildOnEach[] = "%{$searchTerm}%";
        }
        $searchValues = $addWildOnEach;
    }
    $builderQuery-> orWhere(function ($query) use ($tableFields, $searchValues) {            
        foreach ($tableFields as $attribute) {
            $query->orWhere(function ($query) use ($attribute, $searchValues) {
                foreach ($searchValues as $searchTerm) {
                    $query->orWhere($attribute, 'LIKE', $searchTerm);
                }
            });
        }
    });

    return $builderQuery;
}

Finally How To use it

   //variables
   
   $fileds = ['email','name'];

  $values = ['example.net','Taylor Otwell'];
   
   //first Argument will be array of fileds that need to be searched in the Query
   
   //second Argument will be array of values that to be searched
   
   //third Argument will be array of patterns for exploding the each string
   
   //if its set to true the values will be exploded as  ['example.net','Taylor','Otwell'];
   
   //fourth Argument will be boolean for the adding own wild card
   //if its set to true the values in the sql will be processed as follows
   //%eachValues%
  
  $query = User:: search($fileds, $values,['.',' ','@'],true)->select('name','email')->get();
     
     //So query result will be
     
     select
      `name`,
      `email`
    from
      `users`
    where
      (
        (
          `email` LIKE "%example%"
          or `email` LIKE "%net%"
          or `email` LIKE "%Taylor%"
          or `email` LIKE "%Otwell%"
        )
        or (
          `name` LIKE "%example%"
          or `name` LIKE "%net%"
          or `name` LIKE "%Taylor%"
          or `name` LIKE "%Otwell%"
        )
      )
      and `users`.`deleted_at` is null
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment