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. 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.