Vstup a validácia
Kľúče jazykov sa overujú pri zápise
Každá cesta zápisu do modelu — $model->name = …, setTranslation(), setTranslations(), hromadné priradenie vrátane kľúčov s JSON cestou, napríklad update(['name->de' => …]) — overuje kľúče jazykov. Kľúč musí vyzerať ako kód BCP-47 (en, en_US, pt-BR); čokoľvek s úvodzovkami, medzerami, markupom či SQL, napríklad hromadne priradené name[<script>]=…, sa odmietne výnimkou InvalidLocaleException. Hodnoty musia byť skalárne: reťazce sa uložia bez zmeny, int a float sa prevedú na reťazec a vnorené pole, objekt či boolean namiesto uloženia vyhodí InvalidTranslationValueException:
$topic->name = ['en' => 'Investing']; // ok
$topic->name = ['en' => 42]; // ok — stored as "42"
$topic->setTranslation('name', 'pt-BR', 'Investir'); // ok — well-formed key
$topic->update(['name->sk' => 'Sporenie']); // ok — JSON-path key, same guards
$topic->setTranslation('name', '<script>', 'x'); // InvalidLocaleException
$topic->name = ['en' => ['nested' => 'value']]; // InvalidTranslationValueException
$topic->name = true; // InvalidTranslationValueException
// With strict_locales = true and locales ['en', 'sk']:
$topic->setTranslation('name', 'de', 'Investieren'); // InvalidLocaleException (not supported)Zapnite strict_locales, ak chcete odmietať aj správne tvarované kľúče, ktoré nie sú v zozname podporovaných jazykov. Update cez query builder, napríklad Topic::query()->update([...]), nikdy nevytvorí model, preto tieto kontroly obíde rovnako ako akúkoľvek inú logiku atribútov Eloquentu.
Normalizácia vstupu cez fromInput()
Surové mapy z requestu posielajte cez Translatable::fromInput(): nepodporované a prázdne jazyky zahodí ešte pred modelom, takže nedôveryhodný $request->input('name') nikdy nevyvolá výnimku pri zápise. Samotný reťazec sa stane hodnotou pre aktuálny jazyk — a ak tento jazyk nie je podporovaný, zahodí sa tiež:
use RoundlyConsulting\Translatable\Facades\Translatable;
// Supported locales: en, sk — app locale: sk
Translatable::fromInput('Investovanie'); // ['sk' => 'Investovanie']
Translatable::fromInput(['en' => 'Investing', 'sk' => '', 'de' => 'Investieren']); // ['en' => 'Investing']
Translatable::fromInput(null); // []
// App locale de (not supported): a bare string is dropped too
Translatable::fromInput('Investieren'); // []
$topic->setTranslations('name', Translatable::fromInput($request->input('name')));
// or validate first with Translatable::rules('name', required: true)Overenie jedného jazyka
Jeden kľúč — query parameter ?locale= či segment route — overíte cez ensureLocale(), ktorá kľúč vráti alebo vyhodí InvalidLocaleException; isSupported() namiesto toho vráti boolean:
use RoundlyConsulting\Translatable\Facades\Translatable;
Translatable::isSupported('sk'); // true — exact, case-sensitive
Translatable::ensureLocale($locale); // returns it, or throws InvalidLocaleException (malformed)
Translatable::ensureLocale($locale, strict: true); // … also throws when it is not supportedValidačné pravidlá
Translatable::rules() zostaví pravidlá pre pole s mapou jazykov: pole musí byť array, každý podporovaný jazyk je nullable|string a ak je pole povinné, aspoň jeden jazyk musí byť vyplnený. Ďalšie pravidlá pre hodnotu každého jazyka pridáte parametrom each:
use RoundlyConsulting\Translatable\Facades\Translatable;
$request->validate(Translatable::rules('name', required: true, each: ['max:120']));
// Translatable::rules('name', required: true, each: ['max:120']) returns:
// [
// 'name' => ['required', 'array', <at-least-one-locale closure>],
// 'name.en' => ['nullable', 'string', 'max:120'],
// 'name.sk' => ['nullable', 'string', 'max:120'],
// ]
// Optional field — no "filled" check:
Translatable::rules('description', required: false);
// ['description' => ['sometimes', 'array'], 'description.en' => ['nullable', 'string'], …]
// Building your own rule list? Take only the "at least one locale is filled" rule:
'name' => ['required', 'array', ...Translatable::filledRule('name')],Kontrola „aspoň jeden jazyk“ je dostupná aj samostatne ako Translatable::filledRule('name') — pozrite koniec príkladu vyššie. Jej hláška je jazykový riadok translatable::validation.filled („At least one locale must be provided.“) — ak ju chcete zmeniť, publikujte translatable-translations.
Form request s unikátnym slugom
Pravidlá skombinujte s pravidlom UniqueSlug zo sluggable. Pravidlá slugu rozšírte, nedeklarujte slug znova — druhý kľúč 'slug' by potichu nahradil sometimes|array a prepustil hodnotu, ktorá nie je mapou:
use RoundlyConsulting\Sluggable\Rules\UniqueSlug;
use RoundlyConsulting\Translatable\Facades\Translatable;
public function rules(): array
{
// Extend the slug rules rather than re-declaring `slug`: a second `'slug' => […]` key would
// silently replace `sometimes|array` and let a non-map value through.
$slug = Translatable::rules('slug', required: false);
$slug['slug'][] = UniqueSlug::for(Topic::class)->ignore($this->route('topic')); // sluggable's rule
return [...Translatable::rules('name', required: true), ...$slug];
}Aktualizácie v štýle PATCH
Translatable::apply() zlúči sadu TranslationChanges do modelu a zmení len dodané jazyky — ideálne pre čiastočné aktualizácie z API. Nič neukladá, preto potom zavolajte save():
use RoundlyConsulting\Translatable\DataTransferObjects\TranslationChanges;
use RoundlyConsulting\Translatable\Facades\Translatable;
$topic->getTranslations('name'); // ['en' => 'Investing', 'sk' => 'Investovanie']
Translatable::apply($topic, TranslationChanges::make(['name' => ['sk' => 'Sporenie']]));
$topic->getTranslations('name'); // ['en' => 'Investing', 'sk' => 'Sporenie']
$topic->save();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.