Skip to content

Instantly share code, notes, and snippets.

@timacdonald
Last active April 19, 2019 23:09
Show Gist options
  • Save timacdonald/c770552a0faaa2ce72209c6ee2c7a4a1 to your computer and use it in GitHub Desktop.
Save timacdonald/c770552a0faaa2ce72209c6ee2c7a4a1 to your computer and use it in GitHub Desktop.
Basic Search
<?php
/**
* Single attribute...
*/
User::search('tim mac', 'email');
// same as...
User::where('email', 'LIKE', '%tim%')->where('email', 'LIKE', '%mac%');
/**
* Multi attribute...
*/
User::search('tim mac', ['name', 'email']);
// same as...
User::where(function ($query) {
$query->where('name', 'LIKE', '%tim%')->where('name', 'LIKE', '%mac%');
})->orWhere(function () {
$query->where('email', 'LIKE', '%tim%')->where('email', 'LIKE', '%mac%');
});
/**
* Quoted segments
*/
User::search('"tim mac" .com', 'email');
// same as...
User::where('email', 'LIKE', '%tim mac%')->where('email', 'LIKE', '%.com%');
<?php
namespace App\Builders;
use Illuminate\Database\Eloquent\Builder as BaseBuilder;
class Builder extends BaseBuilder
{
public function search($term, $attributes)
{
$attributes = collect($attributes);
// find any quoted terms "like this one"
if (preg_match_all('/"[^"]*"/', $term, $terms) === false) {
$terms = [[]];
}
// unwrap the found terms
$terms = $terms[0];
// remove the extracted quoted terms from the original input
$term = str_replace($terms, '', $term);
// strip out the surrounding quotes so '"like this"' becomes 'like this'
$terms = collect($terms)->map(function ($term) {
return str_replace('"', '', $term);
});
// add all other terms
$terms = $terms->merge(explode(' ', $term))->filter();
// make the magic happen
$this->where(function ($query) use ($terms, $attributes) {
$query->searchMultipleAttributes($terms, $attributes);
});
return $this;
}
protected function searchMultipleAttributes($terms, $attributes)
{
$attributes->each(function ($attribute) use ($terms) {
$this->orWhere(function ($query) use ($terms, $attribute) {
$query->searchSingleAttribute($terms, $attribute);
});
});
}
protected function searchSingleAttribute($terms, $attribute)
{
$terms->each(function ($term) use ($attribute) {
$this->where($attribute, 'LIKE', "%{$term}%");
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment