NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky
Tags for Laravel

Správa štítkov

Tags::type($type) je katalóg jedného typu. Každý zápis ide cez neho — model Tag slúži len na čítanie — takže slugy, cesty, počty použití aj udalosti zostanú správne aj pri súbežných zápisoch.

Vytváranie a seedovanie

use RoundlyConsulting\Tags\DataTransferObjects\TagData;

$genres = Tags::type('genre');

// The builder…
$music = $genres->make(['en' => 'Music', 'sk' => 'Hudba'])->color('#f24e29')->create();
$jazz = $genres->make('Jazz')->under($music)->position(0)->create();

// …or the DTO — the same code path
$rock = $genres->create(new TagData(name: 'Rock', parent: $music, icon: 'guitar'));

// Idempotent seeding: an existing tag is returned unchanged (never moved, recoloured or renamed),
// a missing one is created with every attribute — so the seeder may run again
$bebop = $genres->make('Bebop')->under($jazz)->color('#a7c4d6')->findOrCreate();
$live = Tags::type('label')->findOrCreate('Live');            // a name, a locale map or a TagData

create() odmietne názov, ktorý v niektorom jazyku drží živý štítok toho istého typu a rozsahu (DuplicateTagException), a obnoví zmazaný štítok, ktorý ho drží, s novými atribútmi a na pôvodnom mieste, pokiaľ nezadáte rodiča (namiesto TagCreated sa spustí TagRestored). findOrCreate() hľadá názov v rozsahu, inak globálne, a nájdený štítok vráti bez zmeny — zmazaný sa vráti taký, aký bol, a presunie ho len zadaný rodič (pozrite Názvy, slugy a preklady); mapa jazykov sa porovnáva podľa záznamu aktuálneho jazyka (inak prvého) a ostatné záznamy len doplnia novovytvorený štítok. Je povolené aj pre kurátorované typy — ide o výslovné volanie katalógu — a dve súbežné volania skončia jedným štítkom.

Hľadanie

$genres = Tags::type('genre');

$genres->find('jazz');              // a live tag by slug or name (along the locale chain), a key or a model
$genres->find(12);                  // by primary key (int)
$genres->findOrFail('jazz');        // TagNotFoundException when missing
$genres->findMany($ids);            // by keys, in the order given — malformed, foreign or missing keys skipped
$genres->findTrashed('jazz');       // a deleted tag of exactly this handle's scope, to restore it

$genres->all();                     // every live tag of the type, by position
$genres->roots();                   // the roots (every tag of a flat type)
$genres->query()->where('usage_count', '>', 10)->get();   // Builder<Tag> of the readable scopes

Tags::find($key);                   // a live tag of any type by primary key
Tags::findOrFail($key);

Úpravy

use RoundlyConsulting\Tags\DataTransferObjects\UpdateTagData;

// Fluently — only what you call changes
Tags::type('genre')->edit($jazz)->name('Jazz music')->color(null)->save();

// A rename of the current locale, or of several locales at once
Tags::type('genre')->rename($jazz, 'Jazz music');
Tags::type('genre')->rename($jazz, ['en' => 'Jazz music', 'sk' => 'Jazzová hudba']);

// The DTO — fields left out stay; null clears a description, colour or icon
Tags::type('genre')->update($jazz, new UpdateTagData(description: null, icon: 'sax'));

// A null (or blank) description entry clears that locale only
Tags::type('genre')->edit($jazz)->description(['sk' => null])->save();

Mapa názvu či popisu sa zlúči s uloženou po jazykoch; prázdna alebo null položka popisu vymaže len daný jazyk. Premenovanie na slug, ktorý drží iný štítok, sa odmietne — a ak ho drží zmazaný štítok, odkáže na restore(). TagUpdated sa spustí so zmenenými atribútmi (name, description, slug, color, icon); volanie, ktoré nič nezmení, nespustí nič.

Mazanie a obnova

use RoundlyConsulting\Tags\Enums\TagChildren;

$genres = Tags::type('genre');

$genres->delete($rock);                                   // soft-deletes it and detaches it everywhere
$genres->delete($music);                                  // TagHasChildrenException while it has live children
$genres->delete($music, TagChildren::Reparent);           // children move up to its parent
$genres->delete($music, TagChildren::Delete);             // the whole subtree goes

$genres->restore($rock);                                  // back, with no old taggings
$genres->restore($genres->findTrashed('rock'));           // find it by name first

delete() štítok soft-deletne a v tej istej transakcii ho odpojí od každého modelu, takže znovu vytvorený štítok s rovnakým názvom nikdy neoznačí staré záznamy. Untagged pre jednotlivé modely sa nespustí — TagDeleted nesie počet odstránených priradení. Zmazanie už zmazaného štítku či obnova živého ho vráti bez zmeny. restore() odmietne dieťa, ktorého rodič je stále zmazaný, prepočíta jeho cestu podľa aktuálneho miesta rodiča — kde sa spolu so živým podstromom musí zmestiť do limitu hĺbky typu — a pod nezmeneným rodičom mu ponechá pozíciu; obnova rodiča obnoví len tento štítok.

Obyčajné $tag->delete()

// An admin panel calling Eloquent directly — safe, but it detaches nothing
$tag->delete();

// Reads ignore the leftover taggings at once; a restore through the package starts clean,
// and tags:doctor reports them as an error until you run:
// php artisan tags:repair --orphans

Model Tag

RoundlyConsulting\Tags\Models\Tag sa dá vymeniť cez tags.models.tag (podtriedou). Používa HasSlug zo sluggable, HasTranslations z translatable, SoftDeletes a HasFactory:

$jazz->type;                   // 'genre'
$jazz->name;                   // in the current locale
$jazz->slug;                   // in the current locale
$jazz->slugFor('sk');          // one locale's slug, or null
$jazz->description;
$jazz->color;                  // '#f24e29' or null
$jazz->icon;
$jazz->parent_id;
$jazz->depth;                  // 1 for a root
$jazz->position;               // among its siblings
$jazz->usage_count;            // taggings, kept in the same transaction as each write
$jazz->definition();           // its TagType

Tag::query()->ofType('genre')->within($team)->roots()->ordered()->get();
AtribútVýznam
typeNázov typu; nikdy sa nemení.
scope_type, scope_id, scope()Vlastník štítku s rozsahom (pri globálnom null); nikdy sa nemení. scope_type je pri serializácii skrytý.
scope_keyInterný a skrytý: '' pre globálny štítok, inak morph trieda a kľúč vlastníka, aby unikátny index slugov viazal aj globálne štítky. Odvodí sa pri každom uložení.
parent_id, path, depthStrom: path je zhmotnená reťaz kľúčov predkov (/ pre koreň), depth 1 pre koreň.
positionPoradie medzi súrodencami (0 je prvé).
name, description, slugPreložiteľné: čítajú sa v aktuálnom jazyku; getTranslations('name') vráti mapu jazykov, slugFor($locale) slug jedného jazyka.
color, icon#rrggbb alebo null; identifikátor či emoji, alebo null.
usage_countPočet priradení štítku, upravený v tej istej transakcii ako každý zápis — všetky triedy modelov, vrátane soft-deleted modelov.
wasRecentlyRestoredObyčajná vlastnosť, obdoba wasRecentlyCreated: inštancia bola práve obnovená zo zmazaných.
MetódaČo robí
definition()Vyhodnotený TagType štítku.
parent() / children()BelongsTo a HasMany; deti podľa pozície.
ancestors()Od koreňa, jedným dotazom — alebo bez dotazu, ak ich načítal loadAncestors(). Vždy nová kolekcia.
descendants() / siblings()Buildery živých štítkov pod ním a živých štítkov s rovnakým rodičom, typom a rozsahom.
isRoot()Bez rodiča.
taggings()HasMany riadkov spojovacej tabuľky (Models\Tagging).
taggedModels($class)Modely jednej triedy, ktoré štítok nesú — len na čítanie, ako tags().
ofType(), within($scope, $includeGlobal = true), global(), roots(), descendantsOf($tag, self: false), ordered()Query scopes na Tag::query().

Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

Ďalšie spôsoby podpory vrátane kryptomien

Odoslaním daru súhlasíte s našimi podmienkami prijímania darov.

Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.