Skip to content
This repository has been archived by the owner on Jul 1, 2020. It is now read-only.

Reuse laravel validate rules request & messages #59

Closed
cdsuperstar opened this issue Aug 19, 2015 · 7 comments
Closed

Reuse laravel validate rules request & messages #59

cdsuperstar opened this issue Aug 19, 2015 · 7 comments

Comments

@cdsuperstar
Copy link

If we can reuse our Laravel Validation Rules, Messages via json response, so we can validate both server side & client side!
laravel's message face to the rules, angular-validation's messages seems to the input name.
when I us between:4,8 , angular-validation cann't validate , as I set min_len:4 , laravel cann't validate, why not use same rules or more rules compatible with laravel, reuse laravel's messages is expect !
good job ! :)

@ghiscoding
Copy link
Owner

Thanks for your interest, you probably saw that I had my inspiration from Laravel when I created this library, but I stopped using Laravel and there is a few variances with my library and Laravel. I can maybe make some similar but I cannot do them all, you can't do everything the same when dealing with Javascript (AngularJS) and PHP (Laravel), it's just impossible, for example I can't do anything about the Date validator, JS and PHP are completely different.

The between that you took from Laravel seems like an auto-detect of the input value type (numeric or string). It would need some code change, but I could maybe do an auto-detect as well and depending if it's a number I would redirect to between_num or if a string redirect to between_len.

So I think it's doable for some Validators:

  • between => auto-detect, it will use between_len or between_num
  • max => auto-detect, it would use max_len or max_num
  • min => auto-detect, it would use min_len or min_num
  • size => auto-detect, it will use exact_len or exact_num (I would need to create the exact_num)
  • accepted => I could create it, it's just a True boolean
  • ip => I could make an alias to my ipv4

Some Validators that I am not sure:

  • digits:n => I believe it's the same as my exact_len:n is it? If so, I can make an alias
  • digits_between => I believe it's the same as between_len is it? If so, I can also make an alias.

These Validators will be different

  • date and date_format => I cannot do that in JS
  • integer and numeric => in Laravel this can probably be negative/positive numbers, but in my library it's only positive number, if you want negative too you need to use integer_signed or numeric_signed
  • same => in Laravel you probably just pass the field name but in mine (called match) you need to pass an ngModel so it's quite different

And for your question, can we reuse the same Laravel error messages, the answer is...NO
My library already support 7 languages and I can't rewrite them, there is a lot of people using my library now (75+), so I cannot change all these languages without affecting people's code, and I only speak 2 of these 7 languages.

Please give some feedback on what I wrote... Thanks

@cdsuperstar
Copy link
Author

  1. Nice! alias may be a good way,for rules translate.
    2.About message, see: http://laravel.com/docs/5.1/localization#overriding-vendor-language-files ,
/resources
    /lang
        /en
            messages.php
        /es
            messages.php

I not mean to change language package, we can do this

$translateProvider.useStaticFilesLoader({
        prefix: '/js/bower_components/angular-validation-ghiscoding/locales/validation/',
        suffix: '.json'
    });

change to

$translateProvider.useStaticFilesLoader({
        prefix: '/myroute/to/method/myValidateMessage',
        suffix: ''
    });

so I can use response()->toJson($myMessageArray) some how.
let's look at the laravel validation.php messages,

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Validation Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines contain the default error messages used by
    | the validator class. Some of these rules have multiple versions such
    | as the size rules. Feel free to tweak each of these messages here.
    |
    */

    'accepted'             => 'The :attribute must be accepted.',
    'active_url'           => 'The :attribute is not a valid URL.',
    'after'                => 'The :attribute must be a date after :date.',
    'alpha'                => 'The :attribute may only contain letters.',
    'alpha_dash'           => 'The :attribute may only contain letters, numbers, and dashes.',
    'alpha_num'            => 'The :attribute may only contain letters and numbers.',
    'array'                => 'The :attribute must be an array.',
    'before'               => 'The :attribute must be a date before :date.',
    'between'              => [
        'numeric' => 'The :attribute must be between :min and :max.',
        'file'    => 'The :attribute must be between :min and :max kilobytes.',
        'string'  => 'The :attribute must be between :min and :max characters.',
        'array'   => 'The :attribute must have between :min and :max items.',
    ],
    'boolean'              => 'The :attribute field must be true or false.',
    'confirmed'            => 'The :attribute confirmation does not match.',
    'date'                 => 'The :attribute is not a valid date.',
    'date_format'          => 'The :attribute does not match the format :format.',
    'different'            => 'The :attribute and :other must be different.',
    'digits'               => 'The :attribute must be :digits digits.',
    'digits_between'       => 'The :attribute must be between :min and :max digits.',
    'email'                => 'The :attribute must be a valid email address.',
    'filled'               => 'The :attribute field is required.',
    'exists'               => 'The selected :attribute is invalid.',
    'image'                => 'The :attribute must be an image.',
    'in'                   => 'The selected :attribute is invalid.',
    'integer'              => 'The :attribute must be an integer.',
    'ip'                   => 'The :attribute must be a valid IP address.',
    'max'                  => [
        'numeric' => 'The :attribute may not be greater than :max.',
        'file'    => 'The :attribute may not be greater than :max kilobytes.',
        'string'  => 'The :attribute may not be greater than :max characters.',
        'array'   => 'The :attribute may not have more than :max items.',
    ],
    'mimes'                => 'The :attribute must be a file of type: :values.',
    'min'                  => [
        'numeric' => 'The :attribute must be at least :min.',
        'file'    => 'The :attribute must be at least :min kilobytes.',
        'string'  => 'The :attribute must be at least :min characters.',
        'array'   => 'The :attribute must have at least :min items.',
    ],
    'not_in'               => 'The selected :attribute is invalid.',
    'numeric'              => 'The :attribute must be a number.',
    'regex'                => 'The :attribute format is invalid.',
    'required'             => 'The :attribute field is required.',
    'required_if'          => 'The :attribute field is required when :other is :value.',
    'required_with'        => 'The :attribute field is required when :values is present.',
    'required_with_all'    => 'The :attribute field is required when :values is present.',
    'required_without'     => 'The :attribute field is required when :values is not present.',
    'required_without_all' => 'The :attribute field is required when none of :values are present.',
    'same'                 => 'The :attribute and :other must match.',
    'size'                 => [
        'numeric' => 'The :attribute must be :size.',
        'file'    => 'The :attribute must be :size kilobytes.',
        'string'  => 'The :attribute must be :size characters.',
        'array'   => 'The :attribute must contain :size items.',
    ],
    'string'               => 'The :attribute must be a string.',
    'timezone'             => 'The :attribute must be a valid zone.',
    'unique'               => 'The :attribute has already been taken.',
    'url'                  => 'The :attribute format is invalid.',

    /*
    |--------------------------------------------------------------------------
    | Custom Validation Language Lines
    |--------------------------------------------------------------------------
    |
    | Here you may specify custom validation messages for attributes using the
    | convention "attribute.rule" to name the lines. This makes it quick to
    | specify a specific custom language line for a given attribute rule.
    |
    */

    'custom' => [
        'attribute-name' => [
            'rule-name' => 'custom-message',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Custom Validation Attributes
    |--------------------------------------------------------------------------
    |
    | The following language lines are used to swap attribute place-holders
    | with something more reader friendly such as E-Mail Address instead
    | of "email". This simply helps us make messages a little cleaner.
    |
    */

    'attributes' => [],

];

it can be custom by coders, if we can do some alias about messages?
in our angular-validation like this

    "INVALID_ALPHA_NUM":                "May only contain letters and numbers. ",

in laravel

    'alpha_num'            => 'The :attribute may only contain letters and numbers.',

we can see, laravel message key alpha_num link to the rule alpha_num,
our INVALID_ALPHA_NUM link to the rule alpha_num
when I get locale json from server, it's useless for our angular-validation,key mismatch! every laravel coder must do some translate to reuse the messages for the baserules, do alias or something ? :)

@ghiscoding
Copy link
Owner

I know you really want it to be the same as Laravel but it can't be, like I said many people already use my library so I don't and won't change the handling of error messages.
I guess you could as you said provide your own error message, but you will need some effort of building, I won't do that myself but you could, a mapping table (INVALID_ALPHA_NUM = alpha_num, etc...) and you'll have to deal with the arguments too (I use {0}, {1}.... they use :attribute, :value). Even looking deeper at it, Laravel even sometime have array of messages like the between is an array, that also won't work on my side because everything is 1 to 1 (1 error = 1 message).

But seriously, I don't see the need of having exact same error messages!?! If most messages are caught on the client side (Angular-Validation) then what's the point of having exact same messages if user will never, or rarely, see the Laravel error message? What is that going to give you to have exact same messages?

So as I said, I could possibly do some changes for some of the Validators (the ones I mentioned in previous message, between, min, max, etc...) but I can't make everything the same as Laravel. I don't really want to spend time on error messages, I don't think it's worthed, the error messages are very similar and mean the same things anyway... but if you want to spend time on doing mapping table and some ways to accept outside JSON files, then go ahead I would accept Pull Request if it make sense.

@cdsuperstar
Copy link
Author

got it, many thank for your notes.you are right about `what's the point of having exact same messages if user will never, or rarely, see the Laravel error message?', I will reconsider my idea. thanks a lot.

@ghiscoding
Copy link
Owner

Leave it open, even if I didn't see an advantage to error message being the sames, I do see a big advantage of having similar Validator names, that would be a big benefit of being able to reuse the same names. A developer should always think about having Client Side and Server Side validations (client side is not enough), so I really like the idea of having similar Validators as Laravel.

I should have this list of new Validators (some are new, some are just alias)

  • between (new auto-detect)
  • min (new auto-detect)
  • max (new auto-detect)
  • size (new auto-detect)
  • accepted (new)
  • ip (alias)
  • digits (new)
  • digits_between (new)
  • same (alias but uses ngModel)
  • different (new but uses ngModel)
  • in (new)
  • not_in (new)

Most of them are already done, I just need to add Protractor tests and make sure they work correctly, I'm currently working on the last two: in and not_in, I think these are also doable.

So even though I didn't see advantages on error messages, I do see a big advantage on the list of new Validators being similar to Laravel, there is even a few that I was missing and are nice to have. So I hope you didn't get offended from my last reply and will still use my validation library ;)

A side note, having 2 layers of validation security (client/server side) is mostly because of hackers/pirates/manInTheMiddle who try to manipulate the form and bypass them completely (disabling JS or whatever else) and in that case those are the bad people that might end up seeing the different error messages, do we care about them seeing something different? Most probably not... that was my conclusion, does it make sense?

@ghiscoding ghiscoding reopened this Aug 20, 2015
@cdsuperstar
Copy link
Author

great work! store messages in database or something at server side, provide a unite messages service,can custom by users not coders,it's cool.! go on,these many things to be done :)

ghiscoding added a commit that referenced this issue Aug 22, 2015
Added few Validators that are like Laravel for reusability. The `in` and
`not_in` Validators are the most interesting. The list includes:
- accepted: useful on "Terms of service"
- between: auto-detect type then use between_len or between_num
- max: auto-detect type then use max_len or max_num
- min: auto-detect type then use min_len or min_num
- size: auto-detect type then use exact_len or exact_num
- ip: new alias
- digits: similar to exact_len but only for digits
- digits_between: similar to between_len but only for digits
- in / in_list: useful for accepting a word from a given list of values
- not_in / not_in_list: useful for accepting a word outside a given list
of values
- different: make sure current input is different from another input
- same: new alias to match
@ghiscoding
Copy link
Owner

Pushed into v1.4.4, so go ahead and use it...

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

2 participants