Git Product home page Git Product logo

validator's Introduction

Yii

Yii Validator


Latest Stable Version Total Downloads Build status Code Coverage Mutation testing badge type-coverage static analysis psalm-level

This package provides data validation capabilities.

Features

  • Validates any data: arrays, objects, scalar values, etc.
  • Supports custom data sets.
  • Handles nested data structures (one-to-one and one-to-many).
  • Can read validation rules from PHP 8 attributes.
  • Error message formatting and translation.
  • Attribute names translation.
  • Conditional validation:
    • Skip validation of "empty" value with possibility to configure "empty" condition.
    • Skip further validation if an error occurred for the same property.
    • Skip validation depending on a condition.
  • Possibility to use context in rule handler.
  • Common rules bundled.
  • Supports DI container for creating custom rule handlers with extra dependencies.
  • Exporting rules options for using in the frontend.

Requirements

  • PHP 8.0 or higher.
  • mbstring PHP extension.

Installation

The package could be installed with Composer:

composer require yiisoft/validator

General usage

Validator allows to check data in any format. For example, when data is an object:

use Yiisoft\Validator\Rule\FilledAtLeast;
use Yiisoft\Validator\Rule\Email;
use Yiisoft\Validator\Rule\Length;
use Yiisoft\Validator\Rule\Number;
use Yiisoft\Validator\Rule\Required;
use Yiisoft\Validator\Validator;

#[FilledAtLeast(['email', 'phone'])]
final class Person
{
    public function __construct(
        #[Required]
        #[Length(min: 2)]
        public ?string $name = null,

        #[Number(min: 21)]
        public ?int $age = null,

        #[Email]
        public ?string $email = null,

        public ?string $phone = null,
    ) {
    }
}

$person = new Person(
    name: 'John', 
    age: 17, 
    email: '[email protected]',
    phone: null
);

$result = (new Validator())->validate($person);

The validation result is an object that allows to check whether validation was successful:

$result->isValid();

It also contains errors occurred during validation:

$result->getErrorMessages();

Documentation

If you need help or have a question, the Yii Forum is a good place for that. You may also check out other Yii Community Resources.

License

The Yii Validator is free software. It is released under the terms of the BSD License. Please see LICENSE for more information.

Maintained by Yii Software.

Support the project

Open Collective

Follow updates

Official website Twitter Telegram Facebook Slack

validator's People

Contributors

arduanovdanil avatar arhell avatar armpogart avatar arogachev avatar cebe avatar dehbka avatar dependabot[bot] avatar devanych avatar dood- avatar fantom409 avatar githubjeka avatar kamarton avatar kartavik avatar kriptogenic avatar luizcmarin avatar mapeveri avatar pamparam83 avatar romkatsu avatar roxblnfk avatar rustamwin avatar samdark avatar shoman4eg avatar stylecibot avatar terabytesoftw avatar thenotsoft avatar tomaszkane avatar viktorprogger avatar vjik avatar wiperawa avatar xepozz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

validator's Issues

How to validate an optional field?

What steps will reproduce the problem?

Validate field recipient, but it's optional (No new Required()).

public function rules(): array
{
    return [
        'recipient' => [(new Email())->checkDNS(true)->enableIDN(true)],
    ];
}

Filling the form and it submits. Filling the form except recipient fails with error.

What is the expected result?

Form submits without error.

What do you get instead?

This value is not a valid email address.

Additional info

Q A
Version current dev
PHP version 7.4.8
Operating system Debian 10

IP validator with custom network aliases

What steps will reproduce the problem?

Checking the custom network domains are currently difficult at code level. The validator supports predefined networks that would be useful for this purpose, only needing to be able to add additional aliases.

private $networks = [
'*' => ['any'],
'any' => ['0.0.0.0/0', '::/0'],
'private' => ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', 'fd00::/8'],
'multicast' => ['224.0.0.0/4', 'ff00::/8'],
'linklocal' => ['169.254.0.0/16', 'fe80::/10'],
'localhost' => ['127.0.0.0/8', '::1'],
'documentation' => ['192.0.2.0/24', '198.51.100.0/24', '203.0.113.0/24', '2001:db8::/32'],
'system' => ['multicast', 'linklocal', 'localhost', 'documentation'],
];

What is the expected result?

$v = (new Ip())
  ->withAlias('myNetworkdEu', ['6.6.6.6', '4.4.4.4', '2.2.2.2/10', '!2.2.2.3']);

// example directly at class level
class MyIp extends Ip {
  __construct() {
    $this->withAlias('myNetworkEu', ['6.6.6.6', '4.4.4.4', '2.2.2.2/10', '!2.2.2.3']);
    $this->withAlias('myNetworkLosAngeles', ['99.99.99.99', '1.1.1.1']);
  }
}
// usage
(new MyIp())->withRanges('myNetworkEu')->validateValue($ip)->isValid();

What do you get instead?

$v = (new Ip())
  ->withRanges(array_merge(
    ['6.6.6.6', '4.4.4.4', '2.2.2.2/10', '!2.2.2.3']   // myNetwork EU
    ['99.99.99.99', '1.1.1.1']                         // myNetwork Los Angeles
  ));

// example directly at class level
class MyIp extends Ip {
  withMyAliasRanges($aliases) {
    $ranges = [];
    foreach((array) $aliases as $alias) {
      switch($alias)
        case ...
          $ranges = array_merge($ranges, ['99.99.99.99', '1.1.1.1']);
        case ...
    }
    return $this->withRanges($ranges);
  }
}

// usage
$v->validateValure($ip)->withMyAliasRanges('myNetworkEu')->isValid();

Additional info

For security reasons, I recommend that do not overwrite something that is already being setted.

$ip=(new Ip())
  ->withNetworkAlias('apple', [1.1.1.1])    // OK
  ->wtihNetworkAlias('any', ['2.2.2.2'])    // throw
  ->withNetowkrAlias('apple', [2.2.2.2])    // throw

It can also be a useful function for NetworkResolver. yiisoft/yii-web#119

(new TrustesdHostsNetworkResolver($factory))
  ->withAddedTrustedHosts(['myNetworkEu'])
  ->withIpValidator(new MyIp());
Q A
Version 3.0.x-dev
PHP version -
Operating system -

What About Data transformers?

In yii2 we have 'trim' and 'filter' validators... that really was not validators, but useful.

What about ability to add Transformers. Not sure - should it be in this repo, or as separated...

$transforms = new Transforms([
    'a'=>['trim', new TitleCaseTransformer()],
    'b'=>[function($v){ return rtrim($v, '/').'/';}, 'strtolower']
]);
$transforms->apply($dataSet);

or

$validator = new Validator([    
    'amount' => [
       (new Number())->integer()->max(100),
       (new Transform())->apply([function($value, DataSetInterface $data){
           return $data->getValue('mode') === 'X' ? $value*100: $value*$data->getValue('mul');
       }]),
        function ($value): Result {
            $result = new Result();
            if ($value === 13) {
                $result->addError('Value should not be 13!');
            }
            return $result;
        }
    ],
]);

The `Email` rule also checks the DNS A record, but this is incorrect for email sending

What steps will reproduce the problem?

If the validation of the MX record was unsuccessful, it will attempt to verify the A record, but the verification of the A record will give false results and is incorrect.

$valid = checkdnsrr($matches['domain'] . '.', 'MX') || checkdnsrr($matches['domain'] . '.', 'A');

If the MX entry fails, the mail sending will not work, regardless of the A record pointing somewhere. An MX record is an entry that points to an A record, but this A record itself is mostly completely independent of the A record in the domain of the email.

eg. yiiframework.com points to MX: mxb.cebe.cc.

$ dig yiiframework.com MX

; <<>> DiG 9.11.3-1ubuntu1.9-Ubuntu <<>> yiiframework.com MX
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 55535
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 65494
;; QUESTION SECTION:
;yiiframework.com.		IN	MX

;; ANSWER SECTION:
yiiframework.com.	3561	IN	MX	10 mxb.cebe.cc.
yiiframework.com.	3561	IN	MX	10 mxa.cebe.cc.

;; Query time: 0 msec
;; SERVER: 127.0.0.53#53(127.0.0.53)
;; WHEN: Sat Nov 02 13:17:57 CET 2019
;; MSG SIZE  rcvd: 92

What is the expected result?

From DNS, check only the MX record.

What do you get instead?

MX and A (ipv4) records are checked.

Additional info

Yii2 comes from this commit, which is from yiisoft/yii2#1246.

https://help.dnsmadeeasy.com/managed-dns/dns-record-types/mx-record/

Q A
Version 3.0.x-dev (starting with yii2)
PHP version -
Operating system -

Does IPv6 expand make sense in the IP rule?

What steps will reproduce the problem?

Is the input value overwritten in yii3 meaningful?

validator/src/Rule/Ip.php

Lines 100 to 104 in 725fdfc

/**
* @var bool whether to expand an IPv6 address to the full notation format.
* Defaults to `false`.
*/
private $expandIPv6 = false;

similar:

/**
* @var bool whether to add the CIDR prefix with the smallest length (32 for IPv4 and 128 for IPv6) to an
* address without it. Works only when `subnet` is not `false`. For example:
* - `10.0.1.5` will normalized to `10.0.1.5/32`
* - `2008:db0::1` will be normalized to `2008:db0::1/128`
* Defaults to `false`.
* @see subnet
*/
private $normalize = false;

Q A
Version 3.0.x-dev
PHP version -
Operating system -

yii2 Validator::$skipOnError not implemented

What steps will reproduce the problem?

https://www.yiiframework.com/doc/api/2.0/yii-validators-validator#$skipOnError-detail

Yii2 gave you the option to skip validations if an error was already registered. This is particularly important in terms of performance.

For example, if check a string for both length and uniqueness in a database, then obviously if the length is not good then the uniqueness test does not make sense.

What is the expected result?

The rules should be skippable.

What do you get instead?

All rules are executed.

Q A
Version 3.0.x-dev
PHP version -
Operating system -

EachValidator and client side validation.

Hi,
This issue is to clarify the following question:
Is there any technical reason for the EachValidator not having a client side validation?

This question has already been asked previously in a comment (yiisoft/yii2#9481 (comment)), but the question has not been answered.
I can confirm that the code suggested by the user (bellow) works correctly by displaying the error messages in the specific field where the error occurs. So why do not we have the client side validation in the core ?

class EachValidator extends Validator
...
public function clientValidateAttribute($model, $attribute, $view)
{
    $validator = $this->getValidator();
    $clientJs = $validator->clientValidateAttribute($model, $attribute, $view);
    return 'if (value instanceof Array){value.forEach(function(value){'.$clientJs.'})} else {'.$clientJs.'};';
}

Test:
each

Short declaration for validator initialization

How about to use static factory method ::init, ::create, ::new or other for creating a validator?
For example we can use Number::new()->min(10) instead of (new Number())->min(10).
Short declaration, it seems to me, is more graceful.

Update method rules() in next versions.

Hello!
So, I offer to change syntax in \yii\base\Model::rules()

For example, now we have

public function rules()
{
	return [
		[['login', 'pass'], 'required']
	];
}

I offer try to code something else, for example:

public function rules()
{
    return [
        $this->login => Validator()->required()->string()->min(255)->max(1000)
    ];
}

I like https://github.com/Respect/Validation approach. What do you think?
UPD: I don't know why tabs and spaces are not working...
UPD2: Someone fixed it. Thank you 👍

Russian: хотелось бы писать правила, как в ссылке выше. :)
UPD: Хз почему все переносы и табы слетели... Писал в Notepad++...

UPD2: Кто-то пофиксил. Спасибо 👍

Stabilize tests

Some tests sometimes fail. We should make they more stable.
I attach errors:

1) Yiisoft\Validator\Tests\Rule\GroupRuleTest::testCustomErrorMessage
RuntimeException: In order to use IDN validation intl extension must be installed and enabled.

/home/runner/work/validator/validator/src/Rule/Url.php:105
/home/runner/work/validator/validator/tests/Stub/CustomUrlRule.php:20
/home/runner/work/validator/validator/src/Rule/GroupRule.php:25
/home/runner/work/validator/validator/src/Rule.php:44
/home/runner/work/validator/validator/tests/Rule/GroupRuleTest.php:33

2) Yiisoft\Validator\Tests\Rule\GroupRuleTest::testErrorMessage
RuntimeException: In order to use IDN validation intl extension must be installed and enabled.

/home/runner/work/validator/validator/src/Rule/Url.php:105
/home/runner/work/validator/validator/tests/Stub/CustomUrlRule.php:20
/home/runner/work/validator/validator/src/Rule/GroupRule.php:25
/home/runner/work/validator/validator/src/Rule.php:44
/home/runner/work/validator/validator/tests/Rule/GroupRuleTest.php:27

3) Yiisoft\Validator\Tests\Rule\GroupRuleTest::testOptions
RuntimeException: In order to use IDN validation intl extension must be installed and enabled.

/home/runner/work/validator/validator/src/Rule/Url.php:105
/home/runner/work/validator/validator/tests/Stub/CustomUrlRule.php:20
/home/runner/work/validator/validator/src/Rule/GroupRule.php:41
/home/runner/work/validator/validator/tests/Rule/GroupRuleTest.php:66

4) Yiisoft\Validator\Tests\Rule\GroupRuleTest::testValidate
RuntimeException: In order to use IDN validation intl extension must be installed and enabled.

/home/runner/work/validator/validator/src/Rule/Url.php:105
/home/runner/work/validator/validator/tests/Stub/CustomUrlRule.php:20
/home/runner/work/validator/validator/src/Rule/GroupRule.php:25
/home/runner/work/validator/validator/src/Rule.php:44
/home/runner/work/validator/validator/tests/Rule/GroupRuleTest.php:19

Decouple validators from model

From #11883

I found the Validator is coupled with Model class, it is not easy to use Validators for other classes. For example, I want to validate request parameters in Controller which is irrelevant with any Models, is there any recommended way to do this?

And the rules() for Models could not be edit, adding a method addRules() will be fine.

PHP 8 attributes support

One of the best use cases for the new feature of annotations in PHP 8 is using them for validators. There is also an option to support validators on on PHP 7.4 with the help of Doctrine Annotations, but it would need more work and I'm not sure whether it is worth it.

Adjust "skipOnEmpty"

  1. Empty values always should be validate when rule using separately. For example, (new Number())->validate('')->isValid() should return false.

  2. Validate or not validate value should be decided not at rule level, but above (maybe validator or form).

  3. Check on empty can be differenet in cases. For example, null is empty, but empty string '' is not empty.

CompareValidator client validation does not work with prefixed attributes

In case of using form fields with prefixed attributes, the ID of input will be model-prefix-attribute (for example bellow user-0-password). During the generation of client validation JS in CompareValidator, the compareAttribute (which have to contain ID of target input) will be set to model-password instead of model-0-password (see CompareValidator.php:219), so the JS will generate false errors during the validation.

view.php:

use yii\widgets\ActiveForm;

$form = ActiveForm::begin();
foreach ($models as $i => $model) {
    print $form->field($model, "[$i]password");
    print $form->field($model, "[$i]confirm_password");
}
$form->end();

model.php:

class User extents Model {
...
    function rules() {
        return [
            [
                    ['password'],
                    'compare',
                    'compareAttribute' => 'confirm_password',
                    'on' => ['create'],
                ],
        ];
    }
...
}

Workaround: set enableClientValidation to false in model and use ajax validation with ActiveForm::validateMultiple

And I don't know, how to pass full attribute with prefix form ActiveForm to CompareValidator

Use Injector in the Callback rule

This will give the ability to use callables with dependencies as validation rules.
One more question here: should the injector be optional to support projects without DI container?

Add function exists to DataSetInterface

<?php
namespace Yiisoft\Validator;
/**
 * DataSetInterface represents a key-value data set
 */
interface DataSetInterface
{
    public function getValue(string $attribute);
    public function exists(string $attribute) :bool;
}

Would be nice to have a function exists() or isset() .

We try to access an attribute, which is not set, we receive an exception.

Lets see for example #12 the AtLeastValidator , which checks if the given attributes are set/filled.
When we try to implement it with getValue() we will have loop with a try&catch block...
which I have to admit is a bad habit

False positive validation

Number rule gives false positive on boolean values

What steps will reproduce the problem?

$rule = new \Yiisoft\Validator\Rule\Number();
$result = $rule->validate(false);
var_dump($result->isValid());
$result = $rule->validate(true);
var_dump($result->isValid());

What is the expected result?

false
false

What do you get instead?

true
true

Additional info

Q A
Version 1.0.?
PHP version N/A
Operating system N/A

Validator requires one attribute and cannot see the whole model

What steps will reproduce the problem?

In yii2, it was easy to access any of the model's attributes. In yii3, In Yii3 this option seems to me not feasible.

https://www.yiiframework.com/doc/guide/2.0/en/input-validation#standalone-validators

$results->addResult($attribute, $rules->validate($dataSet->getValue($attribute)));

This issue also affects the Result class because it is not suitable for adding errors to an attribute.

What is the expected result?

I get the whole dataset in an extra parameter, and change return type to ResultSet

public function validate($value, DataSetInterface $dataSet): ResultSet
// or yii2 style
public function validate(?string $attribute, DataSetInterface $dataSet): ResultSet

public function validate($value): Result

public function addError(string $message): void

public function addResult(string $attribute, Result $result): void

usage:

[
  /* numeric index -> attribute=null */ (new MyComplexRule())->moreParameters()...
]

What do you get instead?

[
  'notRelevantAttributeName' => (new MyComplexRule())->with($this /* or $dataset ??*/)->moreParameters()...
]

But in this case, I have no way of returning an arbitrary attribute error of the model.

Additional info

Also, to keep the benefits of the current solution, the Rule class should be somehow allow the Result class to be used internally in simpler cases.

Use case

I need to check for additional attributes depending on a type attribute.

Q A
Version 3.0.x-dev
PHP version -
Operating system -

Rule should force translating error messages

Base Rule implements FormattableRuleInterface but doesn't force user to translate error messages.

  1. Is README example enough to ensure user will actually translate messages by calling $result->addError($this->formatMessage()) instead of $result->addError()?
  2. How can it be improved so there's a formal contract user can not avoid?

[enh] FilterCompare validator

related to #4479 #14013

the proposal is to create a validation to be easily used with the Query::andFilterCompare() method.

the proposed syntax is

[
    'date'
    'comparable',
    'allowedOperators' => ['=', '>=',  '<=', ':']
    'validator' => [
       'date',
       'min' => '2016-01-01',
    ], // date equals '>=2017-01-01' passes
],
[
    'name',
    'allowedOperators' => ['=', '~'],
    'validator' => [
        'string',
    ], // '~hello' passes but '>5' fails
    'defaultOperator' => '~', // 'hello' is turned into '~hello' but '=hello' goes unchanged
]

that way they can be validated before being sent to a query

->andFilterCompare('date', $this->date)
->andFilterCompare('name', $this->name)

getActiveValidators initializes unnecessary validators

Model::getActiveValidators() calls Validator::isActive() which does not take into account attributes present in the scenario - it only checks if scenario is not listed in the except property and on property is empty or scenario is listed there. With common use case where attributes are listed for the scenario in scenarios() method these conditions return still true for validators related to attributes not listed in scenario.

This looks like a bug and unnecessary memory consumption but maybe there is a reason behind this?

Q A
Yii version 2.0.11.2

Ability to validate any data

It's not good that we require users to implement DataSetInterface. Validator should be able to work with any data and should not require and interface.

Consider clientside validation

Need to think about possible ways to implement clientside validation.

  1. It could be done in pure JS or any JS framework.
  2. This library should not have any JS.

Likely that could be introducing a way to convert rules to array that later could be JSON-ized and passed to client side.

no date validation in rules for client-side

public function rules() {
return [
[[['description'], 'string','max' => 80],
['birthday'], 'date', 'format' =>'Y/m/d']];
}
In the example above, you see that every types have their own client-side validation, but there is no such thing for 'date' data-type.

Form validation

How to use form validation in yii3? Is there a complete example or can there be a concept for community discussion?

validate(&$value, &$error = null) and validateValue(&$value)

What steps will reproduce the problem?

I try to create "validator" class.
Validation can change a values under validation (like filter validator)
I wish use validate and nested validateValue functional
I can't change the value in this way.
I am right?

So... How about change signature? Or other way needed?

Additional info

Q A
Yii version 2.0.13@dev
PHP version 7.1.11
Operating system

DateValidator min\max enable Closure

What steps will reproduce the problem?

For exp. you need validate 2 dates, but second date depend on first date:
https://gist.github.com/swods/1fff24a5dec575668a3e517421decb6a

So then then you user load() the validators binding with old value, and only after it's assign a value with 'safe', next step is validate() or save() both of them use already existing validators with old value

In this case validate isn't correct

Часто валидация даты зависит от чего либо, в примере выше 2 даты, вторая дата зависит от первой
Все было бы хорошо и код работал, но когда мы делаем load() валидаторы создаются со старыми значением (пустыми) и записывают в приватную переменную, когда мы вызываем save() или validate() он запускает тот же метод создания валидаторов который видит что они уже есть и использует их, хотя load() уже поменял значения на новые, по этому не получается отвалидировать правильно данные

Idea

  • Add attribute to validate() that reload validators

  • Add Closure to min/max

  • Добавить флаг validate() который бы пересобрал валидаторы

  • Добавить анонимку в min/max

Both is good i think
Можно и то и то, было бы полезно.

What do you think?
Что вы думаете?

Q A
Yii version 2.0.12
PHP version 7.1
Operating system Winux

Why not support php.72

My project is php 7.2 environment, and the extension composer requirements php7.4, unusable

EmailValidator with IDN fails on hyphen

What steps will reproduce the problem?

Use EmailValidator, enable IDN, validate email address: [email protected]

What is the expected result?

This email adres should be valid.

What do you get instead?

The return value of idn_to_ascii is not checked, in this case it returns false, this is evaluated to an empty string, which fails validation for the local part of the email address.

intl_get_error_message() or passing in an array as the 4th argument to idn_to_ascii show that the error is IDNA_ERROR_TRAILING_HYPHEN.

This suggests a trailing hyphen is not valid as input for the function.

Suggested fix

When idn_to_ascii fails we should return the original string and try to validate that instead.

Additional info

Q A
Yii version dev-master
PHP version 7.1
Operating system Alpine

Phone validator

Would be good to have international phone validator.

Input: +7 454 545-44-44, +74545454444, +7 (454)545-4444

Algorithm:

  1. Check if phone starts with +.
  2. Take rest of the string, remove space, -, (, ). Check if string is numeric.

SRP Violation

I think InRange rule violates Single Responsibility Principle. And it will be useful if it is splited into InRange and Subset

What steps will reproduce the problem?

$data1 = [
    'status' => 'active'
];
 
$data2 = [
    'status' => ['active']
];
 
$data3 = [
    'status' => ['active', 'not_active']
];
 
$rules = [
    'status' => [
        new \Yiisoft\Validator\Rule\InRange(['active', 'non_active', 'other_status'])
    ]
];
 
var_dump($validator->validate($data1, $rules)->isValid()); // true
var_dump($validator->validate($data2, $rules)->isValid()); // true
var_dump($validator->validate($data3, $rules)->isValid()); // true

What is the expected result?

true
false
false

What do you get instead?

true
true
true

Rename HasValidationMessage

The trait name doesn't describe what it does properly. It's not validation message, it is validation error message.

[2.1|3.0] proposal ActiveRecords class without validation first

In some simple cases internal model validation not bad, but in more complex cases when validation is in separate classes and save/update operations wrapped into services/repositories, validation-scenario functional seems like overhead and thereare reasons for prohibit direct usage of $model->load($data) && $model->validate() and internal rules configuration;

So my proposal - extract validation feature in trait and add something like SelfValidationInterface, instead of BaseActiveRecord extends Model

JSON Validation using regular expression

As I have mentioned in #65 json validation is a way faster with regular expressions instead of using json_encode. The reason I think is that json_encode does both validation and then parsing (I haven't verified that in source code, but it is safe to assume so) and we don't need any parsing while validating JSON.

So I have prepared full json PCRE regex with unit-tests (tests are from json.org). You can find working regex with tests here.

The regex uses latest JSON specification which is fully compliant with PHP json_encode.

I have also prepared benchmark to show the difference which can be found here. The difference is actually more when profiling locally and looking and php system_time and user_time. So it is obvious that it would be better to validate json using my regular expression.

I will push PR soon.

ResultSet:addResult: errors is overwrite if add valid result.

What steps will reproduce the problem?

If a result for the attribute already exists and add valid result, then simply the valid result overwrites what was stored before.

public function addResult(string $attribute, Result $result): void
{
if (isset($this->results[$attribute]) && !$result->isValid()) {
$errors = $result->getErrors();
$result = $this->results[$attribute];
foreach ($errors as $error) {
$result->addError($error);
}
}
$this->results[$attribute] = $result;
}

What is the expected result?

$resultSet = new ResultSet();
$result = new Result();
$result->addError('error');
$resultSet->addResult('x', $result);
$resultSet->addResult('x', new Result());

// $resultSet->getResult('x')->isValid() === false

What do you get instead?

$resultSet = new ResultSet();
$result = new Result();
$result->addError('error');
$resultSet->addResult('x', $result);
$resultSet->addResult('x', new Result());

// $resultSet->getResult('x')->isValid() === true
Q A
Version 3.0.x-dev
PHP version -
Operating system -

http://localhost/ is not valid url for UrlValidator

Not sure it is by design or bug if bug i can create a PR.

What steps will reproduce the problem?

$val = new UrlValidator;
$result = $val->validate('http://localhost/');

What is the expected result?

true

What do you get instead?

false

Email validator with allowed and disallowed domains

What steps will reproduce the problem?

It is often the case that I do not want to allow disposable email addresses. (https://www.minuteinbox.com)

What is the expected result?

Support in the Email rule class.

// If enable everything and removes:
(new Email())->domainFilters([
  '[email protected]', /* https://www.minuteinbox.com */
  '!*.de',
]);
// If disable everything and add:
(new Email())->domainFilters([
  '!*',
  'mybusiness.com',
]);
// callback
(new Email())->domainFilters([
  function($domain, $email) {
    // Downloaded a larger list from an external source
   return true/false;
  },
]);

What do you get instead?

An additional rule is required eg. MatchRegularExpression.

Q A
Version 3.0.x-dev
PHP version -
Operating system -

Unnesessary dependencies

  • intl php extension usage is very occasional. And there are also a couple of exceptions which say "intl extension must be installed and enabled".
  • Usage of IP rule is not a must too, but it requires yiisoft/network-utilities. But there must be a check with an exception thrown like with the intl extension done.

I think this package should only suggest to install yiisoft/network-utilities and ext-intl and not require them. This way rules should check if the needed dependecy presents and throw an exception if it is not.

TypeError on incorrect url validation with IDN enabled

What steps will reproduce the problem?

(new Url())->enableIDN()->validate('');

What is the expected result?

Return a result object with an error description

What do you get instead?

Yiisoft\Validator\Rule\Url::convertIdn(): Return value must be of type string, bool returned at /var/www/vendor/yiisoft/validator/src/Rule/Url.php:82

Additional info

Q A
Version dev-master
PHP version 8.0.1
Operating system Alpine linux

Additional syntax for `Model::rules()`

To keep things clean usually rules() used that way:

public function rules()
{
    return [
        ['slug', 'required'],

        ['name', 'trim'],
        ['name', 'required'],
        ['name', 'string', 'max' => 255],
        ['name', function () {
            if ($this->hasErrors('slug')) {
                $this->addError('name', Yii::t('app', 'Name is invalid.'));
            }
        }],

        ['nickname', 'trim'],
        ['nickname', 'default', 'value' => null],
        ['nickname', 'string', 'max' => 255],

        ['biography', 'default', 'value' => null],
        ['biography', 'string', 'max' => 65535],

        ['biography_creative', 'default', 'value' => null],
        ['biography_creative', 'string', 'max' => 65535],

        ['biography_booking', 'default', 'value' => null],
        ['biography_booking', 'string', 'max' => 65535],

        ['biography_representative', 'default', 'value' => null],
        ['biography_representative', 'string', 'max' => 65535],

        ['biography_magazine', 'default', 'value' => null],
        ['biography_magazine', 'string', 'max' => 65535],

        ['status', 'default', 'value' => self::STATUS_DRAFT],

        ['is_linked_booking', 'boolean'],

        ['is_linked_representative', 'boolean'],

        ['is_linked_creative', 'boolean'],

        ['is_linked_magazine', 'boolean'],

        ['contactIds', 'exist', 'targetClass' => Contact::className(), 'targetAttribute' => 'id',
            'allowArray' => true],

        ['genreIds', 'exist', 'targetClass' => Genre::className(), 'targetAttribute' => 'id',
            'allowArray' => true],

        ['typeIds', 'exist', 'targetClass' => ArtistType::className(), 'targetAttribute' => 'id',
            'allowArray' => true],

        ['imageFiles', 'safe'],
    ];
}

I suggest to slightly improve possible definition syntax to support above way:

public function rules()
{
    return [
        ['slug', 'required'],

        'name' => [
            'trim',
            'required',
            'string' => ['max' => 255],
            function () {
                if ($this->hasErrors('slug')) {
                    $this->addError('name', Yii::t('app', 'Name is invalid.'));
                }
            },
        ],

        'nickname' => [
            'trim',
            'default' => ['value' => null],
            'string' => ['max' => 255],
        ],

        'biography' => [
            'default' => ['value' => null],
            'string' => ['max' => 255],
        ],

        'biography_creative' => [
            'default' => ['value' => null],
            'string' => ['max' => 255],
        ],

        'biography_booking' => [
            'default' => ['value' => null],
            'string' => ['max' => 255],
        ],

        'biography_representative' => [
            'default' => ['value' => null],
            'string' => ['max' => 255],
        ],

        'biography_magazine' => [
            'default' => ['value' => null],
            'string' => ['max' => 255],
        ],

        ['status', 'default', 'value' => self::STATUS_DRAFT],

        ['is_linked_booking', 'boolean'],

        ['is_linked_representative', 'boolean'],

        ['is_linked_creative', 'boolean'],

        ['is_linked_magazine', 'boolean'],

        ['contactIds', 'exist', 'targetClass' => Contact::className(), 'targetAttribute' => 'id',
            'allowArray' => true],

        ['genreIds', 'exist', 'targetClass' => Genre::className(), 'targetAttribute' => 'id',
            'allowArray' => true],

        ['typeIds', 'exist', 'targetClass' => ArtistType::className(), 'targetAttribute' => 'id',
            'allowArray' => true],

        ['imageFiles', 'safe'],
    ];
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.