Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Validating multiple variables with variable rules effectively #129

Closed
chrissound opened this Issue · 12 comments

6 participants

@chrissound

How can I possibly get an array of all the failed validation rules?

Example:

135     try {
136
137         $validationRules = [
138             'comment' => Validator::string()->notEmpty()->alnum()->length(1,1000)->setName('comment')->assert($post['comment']),
139             'captcha' => Validator::string()->notEmpty()->alnum()->assert($post['captcha']),
140         ];  
141     } catch(\InvalidArgumentException $e) {                                                                                                      
142         $errors = ($e->findMessages(array('notEmpty', 'alnum', 'length')));
143     }

When $post['comment'] and $post['captcha'] are both empty, $errors gets set to the following:

array (size=3)
  'notEmpty' => string '"" must not be empty' (length=20)
  'alnum' => string '' (length=0)
  'length' => string '"" must have a length between 1 and 1000' (length=40)
  1. Do I need to specify all the rules to 'check' in the findMessages method? This involves unnecessary work for me to check what rules I used, and having to retype them...
  2. This does not seem to work with 'multiple' variables.
  3. Am I using setName() incorrectly? Why are the error messages referencing a '' field?
@wesleyvicthor

a simple way is using the v::arr()->key();

try {
    v::arr()
        ->key('captcha', v::notEmpty()->alnum())
        ->key('comment', v::notEmpty()->alnum()->length(1, 1000))
        ->assert($_POST);
} catch(\InvalidArgumentException $e) {
    $messages = $e->findMessages([
        'comment' => 'Invalid Comment.',
        'captcha' => 'Invalid Captcha.'
    ]);
    $messages = array_filter($messages);
}

You can check some references of similar use in the docs.

@chrissound

I think we're on the right track here however is it possible to get further details on which rules failed?

I'm trying to get an array like such:
['Comment must be alphanumeric', 'Comment must be between 1 and 1000 chars'].

@chrissound

Still having issues. Heres something I tried:

213         var_dump($example);
214         try {
215             Validator::
216                 key('comment',    Validator::string()->notEmpty()->setName('comment text'))
217                 ->key('score',      Validator::int()->notEmpty()->between(0,100))
218                 ->key('gender',     Validator::string()->oneOf(
219                    Validator::string()->equals(''),
220                    Validator::string()->equals('male'),
221                    Validator::string()->equals('female')
222                ))
223                 ->assert($example);
224         } catch(\InvalidArgumentException $e) {
225             $messages = $e->findMessages(array('notEmpty', 'between', 'oneOf', 'equals'));
226             var_dump(array_filter($messages));                                                                                                    
227         }

Output:

array (size=5)
  'score' => string '123' (length=3)
  'title' => string 'too short title' (length=15)
  'titleColor' => string 'blue' (length=4)
  'comment' => string '' (length=0)
  'gender' => string 'dinosaur' (length=8)

array (size=4)
  'notEmpty' => string '"" must not be empty' (length=20)
  'between' => string '"123" must be lower than 100' (length=28)
  'oneOf' => string 'At least one of these rules must pass for "dinosaur"' (length=52)
  'equals' => string '"dinosaur" must be identical as ' (length=32)

@wesleyvicthor

@chrissound please read again my example above and see that I'm using the keys of the array to find the
error messages and not the validation method names.

@chrissound

Your example does not return which individual rules failed.

@jimbocoder

@chrissound did you ever have any progress on this issue? I'm in the same boat now. Thanks.

@chrissound

@jimbocoder No I didn't... Judging from the response it seems it isn't supported.

Here is an alternative library you could use: https://github.com/vlucas/valitron

@CMCDragonkai

Try setName?

@nickl-
Owner

@chrissound @jimbocoder have you tried the suggestion from @CMCDragonkai?

@marcosdimitrio

@chrissound, I'm late to this, but I think you want something like the code below, which is based on @wesleyvicthor's example:

use Respect\Validation\Validator as v;
try {
    v::arr()
        ->key('captcha', v::allOf(
            v::string()->notEmpty()->setName('captchaNotEmpty'),
            v::string()->alnum()->setName('captchaAlnum')
        ))
        ->key('comment', v::allOf(
            v::string()->notEmpty()->setName('commentNotEmpty'),
            v::string()->alnum()->setName('commentAlnum'),
            v::string()->length(1, 1000)->setName('commentLength')
        ))
        ->assert($_POST);
} catch(\InvalidArgumentException $e) {
    $messages = $e->findMessages([
        'captchaNotEmpty' => 'Captcha must not be empty.',
        'captchaAlnum'    => 'Captcha must be alphanumeric.',
        'commentNotEmpty' => 'Comment must not be empty.',
        'commentAlnum'    => 'Comment must be alphanumeric.',
        'commentLength'   => 'Comment must have a length between 1 and 1000.'
    ]);
    $messages = array_filter($messages);
    print_r($messages);
}

You could just repeat the keys if you want:

    v::arr()
        ->key('captcha', v::string()->notEmpty()->setName('captchaNotEmpty'))
        ->key('captcha', v::string()->alnum()->setName('captchaAlnum'))
        ->key('comment', v::string()->notEmpty()->setName('commentNotEmpty'))
        ->key('comment', v::string()->alnum()->setName('commentAlnum'))
        ->key('comment', v::string()->length(1, 1000)->setName('commentLength'))
        ->assert($post);

In both cases, you will get:

Array
(
    [captchaNotEmpty] => Captcha must not be empty.
    [commentNotEmpty] => Comment must not be empty.
)
@wesleyvicthor

@chrissound considering you might be using other lib and the answers for your question sounds plausible, is it ok to close this issue ?
one day left.

@chrissound

With all due respect this is such a small issue I don't have the time to invest to look into this again. It's been more then a year!

So I honestly don't mind if you close this or leave it open.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.