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

Vlastné polia

Správcovia definujú polia v databáze (ticket_fields) — globálne, pre projekt alebo pre kategóriu; hodnoty žijú v attributes-for-laravel, jedna na (tiket, kľúč). define(FieldData) je DTO podoba buildera; obe spúšťajú DefineFieldAction a settery buildera validujú hneď:

use RoundlyConsulting\Tickets\DataTransferObjects\UpdateFieldData;
use RoundlyConsulting\Tickets\Enums\FieldType;

Tickets::fields()->make('asset_tag', FieldType::Text)
    ->label(['en' => 'Asset tag', 'sk' => 'Inventárne číslo'])
    ->help(['en' => 'On the sticker'])
    ->category($hardware)          // or ->project($helpdesk); neither = global
    ->required()
    ->requesterEditable()          // the requester may fill it (implies requester-visible)
    ->rules(['max:32'])
    ->define();

Tickets::fields()->make('root_cause', FieldType::Select)
    ->options(['hardware' => ['en' => 'Hardware'], 'user' => ['en' => 'User error']])
    ->agentOnly()                  // requester_visible = false, requester_editable = false
    ->define();

Tickets::fields()->update($field, new UpdateFieldData(required: false, position: 5));
Tickets::fields()->delete($field);    // soft: values stay hidden until a restore or a prune
Tickets::fields()->restore($field);   // refused when the key was taken meanwhile
AtribútVýznam
key^[a-z][a-z0-9_]{0,63}$; nemenný. Unikátny medzi živými poliami projektu vrátane globálnych polí a všetkých kategórií — podkategória nemôže znova definovať kľúč predka ani globálny kľúč. Odmietne sa aj kľúč, pod ktorým zmazané pole daného rozsahu stále drží hodnoty (field.kept_values): pole obnovte alebo najprv jeho hodnoty vyčistite. Vynucuje sa pod poradným zámkom lock:fields.
label, helpPreložiteľné mapy jazykov (reťazec = aktuálny jazyk).
typeFieldType (nižšie).
optionsselect / multiselect: hodnota => popis (mapa jazykov alebo reťazec).
rulesĎalšie pravidlá z tickets.fields.allowed_rules.
required, default, encryptedPredvolená hodnota musí byť hodnota, ktorú pole samo prijme (typ, možnosti, pravidlá) — kontroluje sa pri define() aj pri každej úprave; inak ValidationException s kľúčom default (HTTP 422).
requester_visible, requester_editableČo strana žiadateľa vidí a smie nastaviť.
position, is_activePoradie; neaktívne pole sa neponúka, jeho hodnoty zostávajú.
project, category_idNemenný rozsah.

Typy polí

FieldTypeUkladá sa akoZákladné pravidlá
textstringstring, max:255
textareastringstring, max:65535
emailstringstring, email:rfc
urlstringstring, url
numberintegerinteger
decimalfloatnumeric
booleanbooleanboolean
date, datetimedatetimedate
selectstringstring, in:<options>
multiselectarrayarray, každá in:<options>

Pravidlá sú len z povoleného zoznamu (tickets.fields.allowed_rules): exists a unique sa odmietnu vždy (žiadne skúmanie databázy), rovnako closures a objekty, a vzor regex: má najviac 255 znakov a musí sa dať skompilovať. Keď existujú hodnoty, typ aj príznak šifrovania sa uzamknú (FieldTypeLockedException); možnosti select potom môžu len pribúdať a multiselect si ponechá každú používanú možnosť.

Platná sada polí

Polia tiketu sú aktívne polia, ktorých projekt je projekt tiketu (alebo globálny) a ktorých kategória je null alebo leží v reťazi predkov kategórie tiketu, zoradené podľa position. Fields\FieldSetResolver (scoped na požiadavku či job, bezpečný pre Octane) si sadu zapamätá pre (projekt, kategória):

Tickets::fields()->for($ticket);              // array<string, FieldDefinition>, keyed by field key
Tickets::fields()->for($category, $project);  // for a ticket that would be filed there
Tickets::for($ticket)->fields()->definitions();

Tickets::fields()->find('asset_tag', $project); // ?TicketField by key or id: the project's, else the global one

Hodnoty

Tickets::for($ticket)->by($agent)->fields()->set('asset_tag', 'PRN-0042')->setMany(['root_cause' => 'hardware']);
Tickets::for($ticket)->fields()->get('asset_tag');   // the default when unset; null for an unknown key
Tickets::for($ticket)->fields()->all();              // ['asset_tag' => 'PRN-0042', …], field order
Tickets::for($ticket)->by($agent)->fields()->forget(['root_cause']);

Tickets::make()->subject('…')->requester($user)->category($hardware)->fields(['asset_tag' => 'PRN-0042'])->create();
  • set($key, null) hodnotu zruší; zrušenie či zabudnutie povinného poľa sa odmietne (ValidationException).
  • Kľúč, ktorý nie je poľom tiketu, vyhodí FieldNotEditableException (unknown_field); aktér, ktorý nie je agent, smie nastaviť len polia requester_editable (field_not_editable).
  • Každá hodnota sa zvaliduje podľa svojho poľa (ValidationException s kľúčom fields.<key>) a hlásenie pomenuje pole jeho popisom v aktuálnom jazyku.
  • Povinné polia sa vynucujú pri založení, keď zmena kategórie prinesie novo povinné pole, a keď hodnoty polí zapisuje agent alebo systém — vždy len to, čo smie aktér zapisovať, takže povinné pole len pre agentov nezablokuje samoobsluhu.
  • Interný záznam aktivity fields_changed a TicketFieldsChanged nesú zmenené kľúče — nikdy hodnoty, takže šifrované hodnoty sa nedostanú do histórie, udalostí ani logov.
  • Hodnoty zmazaného poľa alebo poľa, ktoré po zmene kategórie už neplatí, zostanú uložené, no pri čítaní skryté; pod iným poľom sa nikdy neobjavia.

Viditeľnosť

Resources pre žiadateľov a hostí ukazujú len polia requester_visible. Šifrované hodnoty sa agentom dešifrujú; žiadateľ šifrovanú hodnotu uvidí, len ak je pole requester_visible.

Filtrovanie

Ticket::query()->whereField('asset_tag', 'PRN-0042')->get();
Ticket::query()->whereFieldBetween('estimate_hours', 2, null)->get();   // one-sided: the open end is padded
  • Hodnota sa najprv prevedie na typ poľa (reťazec „42“ z požiadavky nájde celočíselný riadok); hodnota, ktorú previesť nemožno, nenájde nič.
  • Obe hranice sú inkluzívne. Horná hranica poľa datetime zadaná ako dátum (2026-10-17) platí do konca dňa.
  • Neznámy, šifrovaný alebo multiselect kľúč vyhodí UnknownTicketFieldException.
  • V API: filter[fields.<key>]=a,b a pre polia number, decimal, date a datetime filter[fields.<key>.from] / filter[fields.<key>.to] — zostavené pri každej požiadavke z aktívnych, nešifrovaných polí, ktoré nie sú multiselect a ktoré divák smie vidieť.

Čistenie osirotených hodnôt

$count = Tickets::fields()->prune(dryRun: true);      // count only
$count = Tickets::fields()->prune(chunk: 500);        // forget them, 500 tickets at a time
php artisan tickets:prune-fields --dry-run
php artisan tickets:prune-fields --chunk=500

Čistenie natrvalo zmaže hodnoty, ktoré už nezodpovedajú žiadnemu poľu ich tiketu — zmazanému poľu alebo kategórii, ktorú tiket opustil. Hodnoty neaktívneho poľa zostanú. Je to jediný krok, ktorý sa nedá vrátiť; dovtedy ich obnovenie poľa vráti a definícia nového poľa s kľúčom zmazaného poľa sa odmieta, kým také hodnoty existujú.

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.