Skip to content

Instantly share code, notes, and snippets.

@tnorthcutt
Created April 11, 2019 22:13
Show Gist options
  • Select an option

  • Save tnorthcutt/d76dbb7581b0f2a878d3f8042542e08e to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown

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