Skip to content

Instantly share code, notes, and snippets.

@Harti
Last active March 13, 2020 21:24
Show Gist options
  • Save Harti/ec1fcd28b162bbb2e7fe06ce2df22275 to your computer and use it in GitHub Desktop.
Save Harti/ec1fcd28b162bbb2e7fe06ce2df22275 to your computer and use it in GitHub Desktop.
Overriding trait for laravel/scout's Searchable trait, to hide unpublished instances from the search
<?php
namespace App\Models\Traits;
use Illuminate\Support\Collection;
trait Searchable
{
use \Laravel\Scout\Searchable;
private static $visibilityFieldName = 'visible';
private static $valueIndicatingVisibility = true;
/**
* Make all instances of the model searchable, except for the ones that are hidden by a database condition.
*
* @return void
*/
public static function makeAllSearchable()
{
$self = new static();
$self->newQuery()
->where($self::$visibilityFieldName, $self::$valueIndicatingVisibility)
->orderBy($self->getKeyName())
->searchable();
}
/**
* Make the given model instance searchable, provided it wasn't hidden by a database condition.
*
* @return void
*/
public function searchable()
{
$self = new static();
if($this->getAttribute($self::$visibilityFieldName) == $self::$valueIndicatingVisibility)
{
Collection::make([$this])->searchable();
}
else
{
$this->unsearchable();
}
}
}
@sandervanhooft
Copy link

sandervanhooft commented Mar 1, 2017

@Harti,
I really like this approach. How would you set/override the $visibilityFieldName at the model (instead of in the trait)? I may use different values for different models (i.e. 'active', 'published', 'visible', ...).

@Harti
Copy link
Author

Harti commented May 30, 2017

Sorry for getting back to you this late, I must have missed the notification.
Since Traits technically "copy" code into your class you should be able to override the variables using the same private variables within your Model class.

If this doesn't work (it has been too long to remember haha), different field names could be quite problematic. I don't see a super clean solution for this as you cannot "extend" PHP Traits (otherwise I would have provided an overrideable method "shouldBeSearchable" but unfortunately that won't work).

Advanced programmers could try to look for existing fields in the class via reflection and use these instead of the trait's values. I have to admit though that my experience on this is too little.
For the time being, I think the best way to go would be to create multiple instances of the trait and call them Publishable, Activatable and so forth.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment