├── composer.json ├── LICENSE.md ├── ConditionalValidator.php └── README.md /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "kop/yii2-conditional-validator", 3 | "description": "If-then validation rules for Yii2 Framework", 4 | "homepage": "http://kop.github.io/yii2-conditional-validator/", 5 | "keywords": ["yii", "yii2", "validator", "validation", "conditional"], 6 | "type": "yii2-extension", 7 | "license": "MIT", 8 | "support": { 9 | "issues": "https://github.com/kop/yii2-conditional-validator/issues", 10 | "source": "https://github.com/kop/yii2-conditional-validator" 11 | }, 12 | "authors": [ 13 | { 14 | "name": "Ivan Koptiev", 15 | "email": "ikoptev@gmail.com", 16 | "role": "Developer" 17 | } 18 | ], 19 | "require": { 20 | "php": ">=5.4.0", 21 | "yiisoft/yii2": "*" 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "kop\\y2cv\\": "" 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Ivan Koptiev 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /ConditionalValidator.php: -------------------------------------------------------------------------------- 1 | 16 | * ['dueDate', ConditionalValidator::className(), 17 | * 'if' => [ 18 | * [['id_payment_method'], 'in', 'range' => [PaymentMethod::MONEY, PaymentMethod::CARD], 'allowEmpty' => false] 19 | * ], 20 | * 'then' => [ 21 | * [['dueDate'], 'required'], 22 | * [['dueDate'], 'numerical'] 23 | * ] 24 | * ] 25 | * 26 | * 27 | * This validator is inspired by {@link https://github.com/sidtj/Yii-Conditional-Validator}. 28 | * 29 | * @license https://github.com/kop/Yii2-Conditional-Validator/blob/master/LICENSE.md MIT 30 | * @link http://kop.github.io/yii2-conditional-validator Project page 31 | * 32 | * @author Ivan Koptiev 33 | * @version 0.1 34 | */ 35 | class ConditionalValidator extends Validator 36 | { 37 | /** 38 | * @var array $if "If" conditions. 39 | */ 40 | public $if = []; 41 | 42 | /** 43 | * @var array $then "Then" conditions. 44 | */ 45 | public $then = []; 46 | 47 | /** 48 | * @var boolean $skipOnEmpty Whether this validation rule should be skipped if the attribute value is null or an empty string. 49 | */ 50 | public $skipOnEmpty = false; 51 | 52 | /** 53 | * @inheritdoc 54 | */ 55 | public function init() 56 | { 57 | parent::init(); 58 | 59 | // Validate given conditions 60 | foreach (['if', 'then'] as $attribute) { 61 | if (!is_array($this->$attribute)) { 62 | $className = self::className(); 63 | throw new InvalidConfigException("Invalid argument \"{$attribute}\" for \"{$className}\". Please, supply an array."); 64 | } 65 | } 66 | } 67 | 68 | /** 69 | * @inheritdoc 70 | */ 71 | public function validateAttribute($object, $attribute) 72 | { 73 | // Check "If" condition 74 | $internalObject = clone $object; 75 | $internalObject->clearErrors(); 76 | $attributes = $internalObject->activeAttributes(); 77 | $ifValidators = $this->createValidators($object, $this->if); 78 | foreach ($ifValidators as $validator) { 79 | $validator->validateAttributes($internalObject, $attributes); 80 | } 81 | 82 | // Apply "Then" condition 83 | if (!$internalObject->hasErrors()) { 84 | $thenValidators = $this->createValidators($object, $this->then); 85 | foreach ($thenValidators as $validator) { 86 | $validator->validateAttributes($object, $attributes); 87 | } 88 | } 89 | } 90 | 91 | /** 92 | * Creates validator objects based on the given model object and validation rules. 93 | * 94 | * @param \yii\base\Model $object Model instance to create validators for. 95 | * @param array $rules List of the validation rules declarations. 96 | * 97 | * @throws \yii\base\InvalidConfigException If errors in validation rules declarations found. 98 | * @return Validator[] Validators objects. 99 | */ 100 | protected function createValidators($object, $rules) 101 | { 102 | $validators = new \ArrayObject(); 103 | foreach ($rules as $rule) { 104 | if ($rule instanceof Validator) { 105 | $validators->append($rule); 106 | } elseif (is_array($rule) && isset($rule[0], $rule[1])) { 107 | $validator = Validator::createValidator($rule[1], $object, (array)$rule[0], array_slice($rule, 2)); 108 | $validators->append($validator); 109 | } else { 110 | throw new InvalidConfigException('Invalid validation rule: a rule must specify both attribute names and validator type.'); 111 | } 112 | } 113 | 114 | return $validators; 115 | } 116 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Yii2 Conditional Validator 2 | ========================== 3 | 4 | > Note: 5 | Since version `2.0.0-beta`, [Yii2 has it's own conditional validator](http://www.yiiframework.com/doc-2.0/guide-input-validation.html#conditional-validation) built in to the core. 6 | Please use validator provided by the framework. This extension **will no receive updates any longer**. 7 | 8 | Yii2 Conditional Validator (Y2CV) validates some attributes depending on certain conditions (rules). 9 | You can use any core validator as you usually would do or any other class based or inline validator. 10 | An interesting feature is that you can even use the own Y2CV inside itself to perform more complex conditions. 11 | Basically, Y2CV executes the rules set in the param `if` and if there are no errors executes the rules set in the param `then`. 12 | 13 | ## Requirements 14 | 15 | - Yii 2.0 16 | - PHP 5.4 17 | 18 | 19 | ## Installation 20 | 21 | 22 | The preferred way to install this extension is through [Composer](http://getcomposer.org/). 23 | 24 | Either run 25 | 26 | ``` php composer.phar require kop/yii2-conditional-validator "dev-master" ``` 27 | 28 | or add 29 | 30 | ``` "kop/yii2-conditional-validator": "dev-master"``` 31 | 32 | to the `require` section of your `composer.json` file. 33 | 34 | 35 | ## Syntax Example 36 | 37 | ```php 38 | [['safeAttributes'], `path.to.ConditionalValidator`, 39 | 'if' => [ 40 | // rule1: [['attrX', 'attrY'], 'required', ... ] 41 | // ruleN: ... 42 | ], 43 | 'then' => [ 44 | // rule1: [['attrZ', 'attrG'], 'required', ... ] 45 | // ruleN: ... 46 | ] 47 | ] 48 | ``` 49 | 50 | - `safeAttributes`: The name of the attributes that should be turned safe (since Yii has no way to make dynamic validators to turn attributes safe); 51 | - `path.to.ConditionalValidator`: In the most of cases will be `ConditionalValidator::className()`; 52 | - `if`: (bidimensional array) The conditional rules to be validated. *Only* if they are all valid (i.e., have no errors) then the rules in `then` will be validated; 53 | - `then`: (bidimensional array) The rules that will be validated *only* if there are no errors in rules of `if` param. 54 | 55 | > Note: 56 | Errors in the rules set in the param `if` are discarded after checking. Only errors in the rules set in param `then` are really kept. 57 | 58 | 59 | ## Usage Examples 60 | 61 | `If` *customer_type* is "active" `then` *birthdate* and *city* are `required`: 62 | ```php 63 | public function rules() 64 | { 65 | return [ 66 | [['customer_type'], ConditionalValidator::className(), 67 | 'if' => [ 68 | [['customer_type'], 'compare', 'compareValue' => 'active'] 69 | ], 70 | 'then' => [ 71 | [['birthdate', 'city'], 'required'] 72 | ] 73 | ] 74 | ]; 75 | } 76 | ``` 77 | 78 | `If` *customer_type* is "inactive" `then` *birthdate* and *city* are `required` **and** *city* must be "sao_paulo", "sumare" or "jacarezinho": 79 | ```php 80 | public function rules() 81 | { 82 | return [ 83 | [['customer_type'], ConditionalValidator::className(), 84 | 'if' => [ 85 | [['customer_type'], 'compare', 'compareValue' => 'active'] 86 | ), 87 | 'then' => [ 88 | [['birthdate', 'city'], 'required'], 89 | [['city'], 'in', 'range' => ['sao_paulo', 'sumare', 'jacarezinho']] 90 | ] 91 | ] 92 | ]; 93 | } 94 | ``` 95 | 96 | `If` *information* starts with 'http://' **and** has at least 24 chars length `then` the own *information* must be a valid url: 97 | ```php 98 | public function rules() 99 | { 100 | return [ 101 | [['information'], ConditionalValidator::className(), 102 | 'if' => [ 103 | [['information'], 'match', 'pattern' => '/^http:\/\//'], 104 | [['information'], 'string', 'min' => 24, 'allowEmpty' => false] 105 | ), 106 | 'then' => [ 107 | [['information'], 'url'] 108 | ] 109 | ] 110 | ]; 111 | } 112 | ``` 113 | 114 | 115 | ## License 116 | 117 | **yii2-conditional-validator** is released under the MIT License. See the bundled `LICENSE.md` for details. 118 | 119 | 120 | ## Resources 121 | 122 | - [Project Page](http://kop.github.io/yii2-conditional-validator) 123 | - [Packagist Package](https://packagist.org/packages/kop/yii2-conditional-validator) 124 | - [Source Code](https://github.com/kop/yii2-conditional-validator) 125 | --------------------------------------------------------------------------------