Merge pull request #3113 from CachetHQ/searchable-tags-2920

Searchable tags
This commit is contained in:
James Brooks
2018-06-18 21:30:13 +01:00
committed by GitHub
5 changed files with 95 additions and 36 deletions

View File

@@ -37,6 +37,10 @@ class ComponentController extends AbstractApiController
$components = Component::enabled();
}
if ($tags = Binput::get('tags')) {
$components->withAnyTags($tags);
}
$components->search(Binput::except(['sort', 'order', 'per_page']));
if ($sortBy = Binput::get('sort')) {

View File

@@ -12,9 +12,9 @@
namespace CachetHQ\Cachet\Models;
use AltThree\Validator\ValidatingTrait;
use CachetHQ\Cachet\Models\Traits\HasTags;
use CachetHQ\Cachet\Models\Traits\SearchableTrait;
use CachetHQ\Cachet\Models\Traits\SortableTrait;
use CachetHQ\Cachet\Models\Traits\Taggable;
use CachetHQ\Cachet\Presenters\ComponentPresenter;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
@@ -23,7 +23,7 @@ use McCool\LaravelAutoPresenter\HasPresenter;
class Component extends Model implements HasPresenter
{
use SearchableTrait, SoftDeletes, SortableTrait, Taggable, ValidatingTrait;
use HasTags, SearchableTrait, SoftDeletes, SortableTrait, ValidatingTrait;
/**
* List of attributes that have default values.

View File

@@ -12,9 +12,9 @@
namespace CachetHQ\Cachet\Models;
use AltThree\Validator\ValidatingTrait;
use CachetHQ\Cachet\Models\Traits\HasTags;
use CachetHQ\Cachet\Models\Traits\SearchableTrait;
use CachetHQ\Cachet\Models\Traits\SortableTrait;
use CachetHQ\Cachet\Models\Traits\Taggable;
use CachetHQ\Cachet\Presenters\IncidentPresenter;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
@@ -30,7 +30,7 @@ use McCool\LaravelAutoPresenter\HasPresenter;
*/
class Incident extends Model implements HasPresenter
{
use SearchableTrait, SoftDeletes, SortableTrait, Taggable, ValidatingTrait;
use HasTags, SearchableTrait, SoftDeletes, SortableTrait, ValidatingTrait;
/**
* Status for incident being investigated.

View File

@@ -0,0 +1,87 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Models\Traits;
use CachetHQ\Cachet\Models\Tag;
use Illuminate\Database\Eloquent\Builder;
/**
* This is the has tags trait.
*
* @author James Brooks <james@alt-three.com>
*/
trait HasTags
{
/**
* Get the tags relation.
*
* @return \Illuminate\Database\Eloquent\Relations\MorphToMany
*/
public function tags()
{
return $this->morphToMany(Tag::class, 'taggable');
}
/**
* @param \Illuminate\Database\Eloquent\Builder $query
* @param array|\ArrayAccess $tags
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeWithAllTags(Builder $query, $tags)
{
$tags = static::convertToTags($tags);
$tags->each(function ($tag) use ($query) {
$query->whereHas('tags', function (Builder $query) use ($tag) {
return $query->where('id', $tag ? $tag->id : 0);
});
});
return $query;
}
/**
* @param \Illuminate\Database\Eloquent\Builder $query
* @param array|\ArrayAccess $tags
*
* @return \Illuminate\Database\Eloquent\Builder
*/
public function scopeWithAnyTags(Builder $query, $tags)
{
$tags = static::convertToTags($tags);
return $query->whereHas('tags', function (Builder $query) use ($tags) {
$tagIds = $tags->pluck('id')->toArray();
$query->whereIn('taggables.tag_id', $tagIds);
});
}
/**
* Convert a list of tags into a collection of \CachetHQ\Cachet\Models\Tag.
*
* @param array|\ArrayAccess $values
*
* @return \Illuminate\Support\Collection
*/
protected static function convertToTags($values)
{
return collect($values)->map(function ($value) {
if ($value instanceof Tag) {
return $value;
}
return Tag::where('slug', '=', $value)->first();
});
}
}

View File

@@ -1,32 +0,0 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Models\Traits;
use CachetHQ\Cachet\Models\Taggable as TaggableModel;
/**
* This is the taggable trait.
*
* @author James Brooks <james@alt-three.com>
*/
trait Taggable
{
/**
* Get the tags relation.
*
* @return \Illuminate\Database\Eloquent\Relations\MorphMany
*/
public function tags()
{
return $this->morphMany(TaggableModel::class, 'taggable');
}
}