Custom Rules

Custom Rule Objects and Closure Rules

php artisan make:rule Isbn13 writes a class implementing ValidationRule. Its validate() gets the attribute, the value and a $fail closure, and the object joins a rule list like any string: 'isbn' => ['nullable', new Isbn13, 'unique:products,isbn'].

The validate() method of app/Rules/Isbn13.phpPHP
public function validate(string $attribute, mixed $value, Closure $fail): void
{
    $d = preg_replace('/[\s-]/', '', (string) $value);
    if (! preg_match('/^97[89]\d{10}$/', $d)) {
        $fail('The :attribute must be a 13-digit ISBN starting with 978 or 979.');
    } elseif (array_sum(array_map(fn ($i) => $d[$i] * ($i % 2 ? 3 : 1), range(0, 12))) % 10) {
        $fail('The :attribute :input has a wrong check digit.');
    }
}

A one-off check can be a closure with the same parameters: the review body's rules gained one that calls $fail('Reviews may not contain links.') when preg_match('~https?://|www\.~i', $value) hits.

Output of 73
$ P='name=Refactoring&sku=BK-1005&category_id=1&price=47.5&authors[0][name]=Fowler'
$ P="$P&format=ebook&authors[0][role]=author&download_url=https://example.com/dl/refactoring"
$ for i in 978-0-13-475759-8 0134757599; do \
    curl -s $A -H "$H" -H "$J" -d "$P&isbn=$i" $B/products | errs; done
isbn: The isbn 978-0-13-475759-8 has a wrong check digit.
isbn: The isbn must be a 13-digit ISBN starting with 978 or 979.
$ curl -s -H "$H" -H "$J" -d 'author=Eve&rating=5' \
    --data-urlencode 'body=Cheap copies at www.example.com today!' $R | errs
body: Reviews may not contain links.

9780134757599 passed. Rules skip absent or empty fields unless implicit (make:rule --implicit adds public $implicit = true;), and DataAwareRule hands a rule the other fields.