Potreboval som v Laraveli vytvoriť validačné pravidlo, ktoré by akceptovalo práve jeden z dvoch vstupov – nie oba naraz a aspoň jeden musel byť zadaný. Inými slovami, potreboval som na ne aplikovať logickú operáciu XOR:
| A | B | XOR |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
Výsledky vyhľadávania ponúkali veľa riešení, ale žiadne z nich sa mi zvlášť
nepáčilo, väčšinou kvôli ich zložitosti alebo nedostatočnej
znovupoužiteľnosti. Najbližšie k minimálnej zložitosti som sa dostal
použitím validačného pravidla required_without z Laravelu:
<?php
public function rules(): array
{
return [
input1 => [
'required_without:input2',
],
input2 => [
'required_without:input1',
],
];
}
Toto však stále nestačilo, pretože to nie je operácia XOR, ale obyčajná OR:
| A | B | OR |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
Keď by boli zadané oba vstupy, validátor by ich ochotne prijal. Po chvíli
premýšľania som zistil, že v Laraveli existuje aj operátor prohibits, tak
som ho použil:
<?php
public function rules(): array
{
return [
input1 => [
'required_without:input2',
'prohibits:input2',
],
input2 => [
'required_without:input1',
'prohibits:input1',
],
];
}
Toto funguje podľa očakávania. Operácia XOR sa aplikuje na oba vstupy
input1 aj input2.
Validačné správy #
Jediným nedostatkom bola vrátená validačná správa:
{
"message": "The given data was invalid.",
"errors": {
"qrcode": ["validation.prohibits"],
"code": ["validation.prohibits"]
}
}
To znamená, že správa jednoducho nie je zadaná a vrátila sa jej „cesta”.
Vyplnením cesty validation.prohibits reťazcom by sa vrátila chybová
správa. Ide o základnú súčasť Laravel validátora, dokumentáciu nájdeš na
odkazoch nižšie. Na zníženie opakovania kódu by výsledok mohol vyzerať
takto:
<?php
public function messages(): array
{
return [
...$this->customMessage('input1', 'input2'),
...$this->customMessage('input2', 'input1'),
];
}
private function customMessage(string $input, string $otherInput): array
{
return [
"$input.prohibits" => "The $input field is prohibited when $otherInput is present."
];
}
Dúfam, že to pomôže. Enjoy!