Laravel Rule Object

0

Witam, ostatnio przeczytałem, że od Laravela 5.5 można dodawać własne reguły walidacji za pomocą klas, a nie tylko przez Validator::extend() Problem w tym, że trzeba w metodzie message() określić, co konkretnie ma zostać zwrócone w przypadku niepowodzenia. Chciałbym, aby w w razie błędu była zwracana customowa wiadomość dla danego pola. Mam taką klasę:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;

class HasDigit implements Rule
{
    private $fieldName;

    /**
     * Create a new rule instance.
     */
    public function __construct($fieldName)
    {
        $this->fieldName = $fieldName;
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        return preg_match('/[\d]+/', $value);
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return trans("validation.custom.{$this->fieldName}.has_digit");
    }
}

Właściwie działa, ale czy tak to należało zrobić?

0

A to czasem nie tutaj ustalasz?

resources/lang/pl/validation.php

0

No tak, ale jeśli w message() napiszę np. return 'Coś poszło nie tak';, to właśnie ten napis pojawi się w przypadku błędu, a nie to co jest w plikach językowych.

0
protected function getMessage($attribute, $rule)
    {
        $lowerRule = Str::snake($rule);

        $inlineMessage = $this->getInlineMessage($attribute, $lowerRule);

        // First we will retrieve the custom message for the validation rule if one
        // exists. If a custom validation message is being used we'll return the
        // custom message, otherwise we'll keep searching for a valid message.
        if (! is_null($inlineMessage)) {
            return $inlineMessage;
        }

        $customKey = "validation.custom.{$attribute}.{$lowerRule}";

        $customMessage = $this->getCustomMessageFromTranslator($customKey);

        // First we check for a custom defined validation message for the attribute
        // and rule. This allows the developer to specify specific messages for
        // only some attributes and rules that need to get specially formed.
        if ($customMessage !== $customKey) {
            return $customMessage;
        }

        // If the rule being validated is a "size" rule, we will need to gather the
        // specific error message for the type of attribute being validated such
        // as a number, file or string which all have different message types.
        elseif (in_array($rule, $this->sizeRules)) {
            return $this->getSizeMessage($attribute, $rule);
        }

        // Finally, if no developer specified messages have been set, and no other
        // special messages apply for this rule, we will just pull the default
        // messages out of the translator service for this validation rule.
        $key = "validation.{$lowerRule}";

        if ($key != ($value = $this->translator->trans($key))) {
            return $value;
        }

        return $this->getInlineMessage(
            $attribute, $lowerRule, $this->fallbackMessages
        ) ?: $key;
    }

Chyba nie ma innej opcji, bo metody musisz użyć. Możesz spróbować zrobić za pomocą klasy abstrakcyjnej :)

0

jeżeli sami twórcy tak polecają w punkcie Customizing The Error Messages to raczej musi to być prawilne

0

Wygląda na to, że przy Validator::extend() system wiadomości działa poprawnie, a przy własnych klasach reguł już trzeba go robić ręcznie. Więc napisałem sobie takiego traita:

<?php

namespace App\Http\Traits;

trait RuleMessage
{
    private $fieldName;

    public function __construct($fieldName)
    {
        $this->fieldName = $fieldName;
    }

    private function getMessage()
    {
        $rule = snake_case(class_basename(self::class));
        return trans("validation.custom.{$this->fieldName}.{$rule}");
    }
}

Mam teraz problem z wywołaniem tego konstruktora. Z tego co czytałem, można to zrobić tak:

<?php

namespace App\Rules;

use Illuminate\Contracts\Validation\Rule;
use App\Http\Traits\RuleMessage;


class HasDigit implements Rule
{
    use RuleMessage{
        RuleMessage::__construct as private __rmConstruct;
    }

    /**
     * Create a new rule instance.
     */
    public function __construct($fieldName)
    {
        $this->__rmConstruct($fieldName);
    }

    /**
     * Determine if the validation rule passes.
     *
     * @param  string  $attribute
     * @param  mixed  $value
     * @return bool
     */
    public function passes($attribute, $value)
    {
        return preg_match('/[\d]+/', $value);
    }

    /**
     * Get the validation error message.
     *
     * @return string
     */
    public function message()
    {
        return $this->getMessage();
    }
}

Jak patrzę na ten kod, to widzę, że dołączanie tego traita nie ma sensu, ale tak sobie myślę: czy ten konstruktor z traita nie powinien być jakoś domyślnie dostępny i gotowy do użycia? W PHP 7 jest już chyba przeciążanie metod.

1 użytkowników online, w tym zalogowanych: 0, gości: 1