Skip to content

Instantly share code, notes, and snippets.

@tnorthcutt
Created April 11, 2019 22:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tnorthcutt/d76dbb7581b0f2a878d3f8042542e08e to your computer and use it in GitHub Desktop.
Save tnorthcutt/d76dbb7581b0f2a878d3f8042542e08e to your computer and use it in GitHub Desktop.
Extending spatie/laravel-tags to limit to the current team in a Spark application
<?php
// Relevant parts of my Member.php model, which is the model that I'm applying tags to
/**
* Using our own Tag model
* @see https://docs.spatie.be/laravel-tags/v2/advanced-usage/using-your-own-tag-model
*
* @return string
*/
public static function getTagClassName(): string
{
return Tag::class;
}
/**
* @return MorphToMany
*/
public function tags(): MorphToMany
{
return $this
->morphToMany(self::getTagClassName(), 'taggable', 'taggables', null, 'tag_id')
->orderBy('order_column');
}
/**
* @param array|\ArrayAccess|\Spatie\Tags\Tag $tags
*
* @return $this
*/
public function attachTags($tags)
{
$className = static::getTagClassName();
$tags = collect($className::findOrCreate($tags, null, null, $this->team));
$this->tags()->syncWithoutDetaching($tags->pluck('id')->toArray());
return $this;
}
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AlterTagsTableAddTeamIdColumn extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('tags', function (Blueprint $table) {
$table->unsignedInteger('team_id')->after('id')->nullable();
});
Schema::table('tags', function (Blueprint $table) {
$table->foreign('team_id')
->references('id')
->on('teams');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('tags', function (Blueprint $table) {
$table->dropColumn('team_id');
$table->dropForeign(['team_id']);
});
}
}
<?php
namespace App\Models;
use Spatie\Tags\Tag as SpatieTag;
use App\Traits\UsedByTeams;
class Tag extends SpatieTag
{
use UsedByTeams;
/**
* @param array|\ArrayAccess $values
* @param string|null $type
* @param string|null $locale
*
* @return \Spatie\Tags\Tag|static
*/
public static function findOrCreate($values, string $type = null, string $locale = null, Team $team = null)
{
$tags = collect($values)->map(function ($value) use ($type, $locale, $team) {
if ($value instanceof Tag) {
return $value;
}
return static::findOrCreateFromString($value, $type, $locale, $team);
});
return is_string($values) ? $tags->first() : $tags;
}
protected static function findOrCreateFromString(string $name, string $type = null, string $locale = null, Team $team = null): SpatieTag
{
$locale = $locale ?? app()->getLocale();
$tag = static::findFromString($name, $type, $locale);
if (! $tag) {
$tag = static::create([
'name' => [$locale => $name],
'type' => $type,
'team_id' => $team->id,
]);
}
return $tag;
}
}
@ptrin
Copy link

ptrin commented Apr 13, 2019

This is awesome, thanks!

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