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 TagDatacreate() 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 firstdelete() š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 a nespustí nič. 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 --orphansModel 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út | Význam |
|---|---|
type | Ná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_key | Interný 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, depth | Strom: path je zhmotnená reťaz kľúčov predkov (/ pre koreň), depth 1 pre koreň. |
position | Poradie medzi súrodencami (0 je prvé). |
name, description, slug | Prelož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_count | Počet priradení štítku, upravený v tej istej transakcii ako každý zápis — všetky triedy modelov, vrátane soft-deleted modelov. |
wasRecentlyRestored | Obyč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 kryptomienOdoslaní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.