| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  * Copied from | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  |  * Author: paulzi | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  |  * https://gist.github.com/paulzi/ad27c4689475ca442a2ea5880d659ff3 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | namespace Horat1us\Yii\Validators; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | use yii\base\InvalidConfigException; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  | use Yii; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  | use yii\base\Model; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  | use yii\helpers\ArrayHelper; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | use yii\validators\Validator; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  | class CompositeValidator extends Validator | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  | { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |      * @var array | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |     public $rules = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |      * @var boolean | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |     public $allowMessageFromRule = true; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |      * @var Validator[] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |     private $_validators = []; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |      * @inheritdoc | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 35 |  |  |      */ | 
            
                                                                        
                            
            
                                    
            
            
                | 36 |  |  |     public function init() | 
            
                                                                        
                            
            
                                    
            
            
                | 37 |  |  |     { | 
            
                                                                        
                            
            
                                    
            
            
                | 38 |  |  |         parent::init(); | 
            
                                                                        
                            
            
                                    
            
            
                | 39 |  |  |         if ($this->message === null) { | 
            
                                                                        
                            
            
                                    
            
            
                | 40 |  |  |             $this->message = Yii::t('yii', '{attribute} is invalid.'); | 
            
                                                                        
                            
            
                                    
            
            
                | 41 |  |  |         } | 
            
                                                                        
                            
            
                                    
            
            
                | 42 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |      * @param integer $index | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |      * @param Model|null $model | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |      * @return Validator | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |     private function getValidator($index, $model = null) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |         if (!isset($this->_validators[$index])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |             $this->_validators[$index] = $this->createEmbeddedValidator($this->rules[$index], $model); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |         return $this->_validators[$index]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |      * @param array $rule | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |      * @param Model|null $model | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |      * @throws \yii\base\InvalidConfigException | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |      * @return Validator validator instance | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |     private function createEmbeddedValidator($rule, $model) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |         if ($rule instanceof Validator) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |             return $rule; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |         } elseif (is_array($rule) && isset($rule[0]) && isset($rule[1])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |             if (!is_object($model)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |                 $model = new Model(); // mock up context model | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |             return Validator::createValidator($rule[1], $model, $this->attributes, array_slice($rule, 2)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |             throw new InvalidConfigException('Invalid validation rule: a rule must be an array specifying validator type.'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |      * @param Model $model | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |      * @param string $attribute | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |      * @param Validator $validator | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |      * @param array $originalErrors | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |      * @param array $value | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |      * @param string $target | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |     private function validateInternal(&$model, &$attribute, &$validator, &$originalErrors, &$value, $target) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |         $current = explode('[]', $target, 2); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |         if (count($current) > 1) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |             $items = ArrayHelper::getValue($value, $current[0]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |             if ($items) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |                 foreach ($items as $i => $item) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |                     $this->validateInternal($model, $attribute, $validator, $originalErrors, $value, "{$current[0]}.{$i}{$current[1]}"); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |         } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |             $v = $model->$attribute = ArrayHelper::getValue($value, $target); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |             if (!$validator->skipOnEmpty || !$validator->isEmpty($v)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |                 $validator->validateAttribute($model, $attribute); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |             ArrayHelper::setValue($value, $target, $model->$attribute); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |             if ($model->hasErrors($attribute)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |                 $validationErrors = $model->getErrors($attribute); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |                 $model->clearErrors($attribute); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |                 if (!empty($originalErrors)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |                     $model->addErrors([$attribute => $originalErrors]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |                 if ($this->allowMessageFromRule) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |                     $name = "{$attribute}.{$target}"; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |                     $name = preg_replace('/\.(\w+)/', '[\\1]', $name); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |                     $model->addErrors([$name => $validationErrors]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |                 } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |                     $this->addError($model, $attribute, $this->message, ['value' => $v]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |             $model->$attribute = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |      * @inheritdoc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |     public function validateAttribute($model, $attribute) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |         $value = $model->$attribute; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |         foreach ($this->rules as $index => $rule) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |             $validator = $this->getValidator($index, $model); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |             $originalErrors = $model->getErrors($attribute); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |             $targets = (array)$rule[0]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |             foreach ($targets as $target) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |                 $this->validateInternal($model, $attribute, $validator, $originalErrors, $value, $target); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |             $model->$attribute = $value; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |     /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |      * @inheritdoc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |     protected function validateValue($value) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |         foreach ($this->rules as $index => $rule) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |             $validator = $this->getValidator($index); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |             $targets = (array)$rule[0]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |             foreach ($targets as $target) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |                 $v = ArrayHelper::getValue($value, $target); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |                 if ($validator->skipOnEmpty && $validator->isEmpty($v)) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |                     continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |                 $result = $validator->validateValue($v); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |                 if ($result !== null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |                     if ($this->allowMessageFromRule) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |                         $result[1]['value'] = $v; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |                         return $result; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |                     } else { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  |                         return [$this->message, ['value' => $v]]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |                     } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |         return null; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 162 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 163 |  |  |  |