├── LICENSE ├── README.md ├── composer.json └── src ├── Attributes.php ├── Validate.php ├── ValidateException.php ├── When.php ├── locale ├── Locale.php ├── en │ ├── Alnum.php │ ├── Alpha.php │ ├── Arr.php │ ├── Between.php │ ├── BoolLocale.php │ ├── CSRF.php │ ├── Call.php │ ├── Captcha.php │ ├── Closure.php │ ├── Cntrl.php │ ├── Confirm.php │ ├── Contains.php │ ├── Date.php │ ├── Digit.php │ ├── Directory.php │ ├── Domain.php │ ├── Email.php │ ├── EndsWith.php │ ├── Equals.php │ ├── Exists.php │ ├── File.php │ ├── FileExtensions.php │ ├── FileMimeTypes.php │ ├── FileSizeBetween.php │ ├── FileSizeMax.php │ ├── FileSizeMin.php │ ├── FloatLocale.php │ ├── Graph.php │ ├── In.php │ ├── IntLocale.php │ ├── Ip.php │ ├── JSON.php │ ├── Length.php │ ├── Lowercase.php │ ├── Max.php │ ├── Min.php │ ├── Negative.php │ ├── NoWhitespace.php │ ├── NullValue.php │ ├── Numeric.php │ ├── Object.php │ ├── Odd.php │ ├── Positive.php │ ├── Readable.php │ ├── Regex.php │ ├── Required.php │ ├── Space.php │ ├── StartsWith.php │ ├── StringLocale.php │ ├── SymbolicLink.php │ ├── Uploaded.php │ ├── Uppercase.php │ └── Writable.php └── ru │ ├── Alnum.php │ ├── Alpha.php │ ├── Arr.php │ ├── Between.php │ ├── BoolLocale.php │ ├── CSRF.php │ ├── Call.php │ ├── Captcha.php │ ├── Closure.php │ ├── Cntrl.php │ ├── Confirm.php │ ├── Contains.php │ ├── Date.php │ ├── Digit.php │ ├── Directory.php │ ├── Domain.php │ ├── Email.php │ ├── EndsWith.php │ ├── Equals.php │ ├── Exists.php │ ├── File.php │ ├── FileExtensions.php │ ├── FileMimeTypes.php │ ├── FileSizeBetween.php │ ├── FileSizeMax.php │ ├── FileSizeMin.php │ ├── FloatLocale.php │ ├── Graph.php │ ├── In.php │ ├── IntLocale.php │ ├── Ip.php │ ├── JSON.php │ ├── Length.php │ ├── Lowercase.php │ ├── Max.php │ ├── Min.php │ ├── Negative.php │ ├── NoWhitespace.php │ ├── NullValue.php │ ├── Numeric.php │ ├── Object.php │ ├── Odd.php │ ├── Positive.php │ ├── Readable.php │ ├── Regex.php │ ├── Required.php │ ├── Space.php │ ├── StartsWith.php │ ├── StringLocale.php │ ├── SymbolicLink.php │ ├── Uploaded.php │ ├── Uppercase.php │ └── Writable.php └── rules ├── Alnum.php ├── Alpha.php ├── Arr.php ├── Between.php ├── BoolRule.php ├── CSRF.php ├── CType.php ├── Call.php ├── Captcha.php ├── Closure.php ├── Cntrl.php ├── Confirm.php ├── Contains.php ├── Date.php ├── Digit.php ├── Directory.php ├── Domain.php ├── Email.php ├── EndsWith.php ├── Equals.php ├── Exists.php ├── File.php ├── FileExtensions.php ├── FileMimeTypes.php ├── FileSizeBetween.php ├── FileSizeMax.php ├── FileSizeMin.php ├── FloatRule.php ├── Graph.php ├── In.php ├── IntRule.php ├── Ip.php ├── JSON.php ├── Length.php ├── Lowercase.php ├── Max.php ├── Min.php ├── Negative.php ├── NoWhitespace.php ├── NullValue.php ├── Numeric.php ├── Object.php ├── Odd.php ├── Positive.php ├── Readable.php ├── Regex.php ├── Required.php ├── Rule.php ├── Space.php ├── StartsWith.php ├── StringRule.php ├── SymbolicLink.php ├── Uploaded.php ├── Uppercase.php └── Writable.php /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 RomeOz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Validator for PHP 2 | ======================= 3 | 4 | [![Latest Stable Version](https://poser.pugx.org/romeOz/rock-validate/v/stable.svg)](https://packagist.org/packages/romeOz/rock-validate) 5 | [![Total Downloads](https://poser.pugx.org/romeOz/rock-validate/downloads.svg)](https://packagist.org/packages/romeOz/rock-validate) 6 | [![Build Status](https://travis-ci.org/romeOz/rock-validate.svg?branch=master)](https://travis-ci.org/romeOz/rock-validate) 7 | [![HHVM Status](http://hhvm.h4cc.de/badge/romeoz/rock-validate.svg)](http://hhvm.h4cc.de/package/romeoz/rock-validate) 8 | [![Coverage Status](https://coveralls.io/repos/romeOz/rock-validate/badge.svg?branch=master)](https://coveralls.io/r/romeOz/rock-validate?branch=master) 9 | [![License](https://poser.pugx.org/romeOz/rock-validate/license.svg)](https://packagist.org/packages/romeOz/rock-validate) 10 | 11 | Features 12 | ------------------- 13 | 14 | * Supports large many validation rules (string, number, ctype, file, network) 15 | * Validation of scalar variable and array (`attributes()`) 16 | * **Output the list of errors in an associative array** 17 | * **i18n support** 18 | * **Hot replacement of placeholders for messages (`{{name}} must be valid`), as well messages** 19 | * **Customization of validation rules** 20 | * **Module for [Rock Framework](https://github.com/romeOz/rock)** 21 | 22 | > Bolded features are different from [Respect/Validation](https://github.com/Respect/Validation). 23 | 24 | Table of Contents 25 | ------------------- 26 | 27 | * [Installation](#installation) 28 | * [Quick Start](#quick-start) 29 | - [Replacement a placeholder](#replacement-a-placeholder) 30 | - [i18n](#i18n) 31 | - [As array or object](#as-array-or-object) 32 | * [Documentation](#documentation) 33 | * [Demo](#demo) 34 | * [Requirements](#requirements) 35 | 36 | Installation 37 | ------------------- 38 | 39 | From the Command Line: 40 | 41 | ``` 42 | composer require romeoz/rock-validate 43 | ``` 44 | 45 | In your composer.json: 46 | 47 | ```json 48 | { 49 | "require": { 50 | "romeoz/rock-validate": "*" 51 | } 52 | } 53 | ``` 54 | 55 | Quick Start 56 | ------------------- 57 | 58 | ```php 59 | use rock\validate\Validate; 60 | 61 | // Validation length from 10 to 20 characters inclusive + regexp pattern 62 | $v = Validate::length(10, 20, true)->regex('/^[a-z]+$/i'); 63 | $v->validate('O’Reilly'); // output: false 64 | 65 | $v->getErrors(); 66 | /* 67 | output: 68 | 69 | [ 70 | 'length' => 'value must have a length between 10 and 20', 71 | 'regex' => 'value contains invalid characters' 72 | ] 73 | */ 74 | 75 | $v->getFirstError(); 76 | // output: value must have a length between 10 and 20 77 | ``` 78 | 79 | ####Replacement a placeholder 80 | 81 | ```php 82 | use rock\validate\Validate; 83 | 84 | $v = Validate::length(10, 20, true) 85 | ->regex('/^[a-z]+$/i') 86 | ->setPlaceholders(['name' => 'username']); 87 | $v->validate('O’Reilly'); // output: false 88 | 89 | $v->getErrors(); 90 | /* 91 | output: 92 | 93 | [ 94 | 'length' => 'username must have a length between 10 and 20', 95 | 'regex' => 'username contains invalid characters', 96 | ] 97 | */ 98 | ``` 99 | 100 | ####i18n 101 | 102 | ```php 103 | use rock\validate\Validate; 104 | 105 | $v = Validate::length(10, 20, true)->regex('/^[a-z]+$/i')->setLocale('ru'); 106 | $v->validate('O’Reilly'); // output: false 107 | 108 | $v->getErrors(); 109 | /* 110 | output: 111 | 112 | [ 113 | 'length' => 'значение должно иметь длину в диапазоне от 10 до 20', 114 | 'regex' => 'значение содержит неверные символы', 115 | ] 116 | */ 117 | ``` 118 | 119 | ####As Array or Object 120 | 121 | ```php 122 | use rock\validate\Validate; 123 | 124 | $input = [ 125 | 'username' => 'O’Reilly', 126 | 'email' => 'o-reilly@site' 127 | ]; 128 | $attributes = [ 129 | 'username' => Validate::required() 130 | ->length(10, 20, true) 131 | ->regex('/^[a-z]+$/i') 132 | ->setPlaceholders(['name' => 'username']), 133 | 134 | 'email' => Validate::required()->email() 135 | ]; 136 | 137 | $v = Validate::attributes($attributes); 138 | $v->validate($input); // output false 139 | 140 | $v->getErrors(); 141 | /* 142 | output: 143 | 144 | [ 145 | 'username' => [ 146 | 'length' => 'username must have a length between 10 and 20', 147 | 'regex' => 'username contains invalid characters', 148 | ], 149 | 'email' => [ 150 | 'email' => 'email must be valid email', 151 | ] 152 | ] 153 | */ 154 | 155 | $attribute = 'email'; 156 | $v->getFirstError($attribute); 157 | // output: email must be valid 158 | ``` 159 | 160 | Documentation 161 | ------------------- 162 | 163 | * [Rules](https://github.com/romeOz/rock-validate/blob/master/docs/rules.md) 164 | * [Custom messages, placeholders and templates](https://github.com/romeOz/rock-validate/blob/master/docs/custom-messages.md) 165 | * [Custom rules](https://github.com/romeOz/rock-validate/blob/master/docs/custom-rules.md) 166 | 167 | [Demo](https://github.com/romeOz/docker-rock-validate) 168 | ------------------- 169 | 170 | * [Install Docker](https://docs.docker.com/installation/) or [askubuntu](http://askubuntu.com/a/473720) 171 | * `docker run --name demo -d -p 8080:80 romeoz/docker-rock-validate` 172 | * Open demo [http://localhost:8080/](http://localhost:8080/) 173 | 174 | Requirements 175 | ------------------- 176 | 177 | * **PHP 5.4+** 178 | 179 | License 180 | ------------------- 181 | 182 | The Rock Validate is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT). -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "romeoz/rock-validate", 3 | "description": "Flexible validator for PHP with I18N.", 4 | "keywords": ["validate", "validation", "validator"], 5 | "type": "library", 6 | "license": "MIT", 7 | "support": { 8 | "email": "serggalka@gmail.com", 9 | "issues": "https://github.com/romeOz/rock-validate/issues", 10 | "source": "https://github.com/romeOz/rock-validate" 11 | }, 12 | "authors": [ 13 | { 14 | "name": "Ruslan", 15 | "email": "serggalka@gmail.com" 16 | } 17 | ], 18 | "require": { 19 | "php": ">=5.4.0", 20 | "romeoz/rock-base" : "~0.12", 21 | "true/punycode": "~1.0" 22 | }, 23 | "require-dev": { 24 | "phpunit/phpunit": "^4.7.0", 25 | "romeoz/rock-date" : "~0.12" 26 | }, 27 | "autoload": { 28 | "psr-4": { 29 | "rock\\validate\\": "src/" 30 | } 31 | }, 32 | "extra": { 33 | "branch-alias": { 34 | "dev-master": "0.12-dev" 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/Attributes.php: -------------------------------------------------------------------------------- 1 | attributes instanceof Validate) { 28 | $this->each($input); 29 | } 30 | foreach ($this->attributes as $attribute => $validate) { 31 | if (!$validate instanceof Validate) { 32 | throw new ValidateException("`{$attribute}` is not `".Validate::className()."`"); 33 | } 34 | if ($attribute === $this->remainder) { 35 | $this->remainder($validate, $input); 36 | continue; 37 | } 38 | if (!isset($input[$attribute])) { 39 | $input[$attribute] = null; 40 | } 41 | 42 | $validate->invert = $this->invert; 43 | if ($validate->validate($input[$attribute])) { 44 | continue; 45 | } 46 | 47 | if ($errors = $validate->getErrors()) { 48 | $this->errors[$attribute] = $errors; 49 | if ($this->one) { 50 | break; 51 | } 52 | } 53 | } 54 | } 55 | 56 | public function getErrors() 57 | { 58 | return $this->errors; 59 | } 60 | 61 | protected function each($input) 62 | { 63 | $validate = $this->attributes; 64 | $this->attributes = []; 65 | foreach($input as $key => $value) { 66 | $this->attributes[$key] = $validate; 67 | } 68 | } 69 | 70 | protected function remainder(Validate $validate, $input) 71 | { 72 | $input = ArrayHelper::diffByKeys($input, array_keys($this->attributes)); 73 | $config = [ 74 | 'remainder' => $this->remainder, 75 | 'attributes' => $validate 76 | ]; 77 | Instance::configure($this, $config); 78 | $this->validate($input); 79 | } 80 | } -------------------------------------------------------------------------------- /src/Validate.php: -------------------------------------------------------------------------------- 1 | rules = array_merge($this->defaultRules(), $this->rules); 196 | } 197 | 198 | /** 199 | * Sets a locale. 200 | * @param string $locale 201 | * @return $this 202 | */ 203 | public function setLocale($locale) 204 | { 205 | $this->locale = strtolower($locale); 206 | return $this; 207 | } 208 | 209 | /** 210 | * Adds a list rules. 211 | * @param array $rules list rules. 212 | * @return $this 213 | */ 214 | public function setRules(array $rules) 215 | { 216 | $this->rules = array_merge($this->rules, $rules); 217 | return $this; 218 | } 219 | 220 | /** 221 | * Selects a templates. 222 | * 223 | * ```php 224 | * $validate->required() 225 | * ->email() 226 | * ->setTemplates(['required' => Required::NAMED]) 227 | * ->validate('foo@site.com'); 228 | * ``` 229 | * 230 | * @param array $templates 231 | * @return $this 232 | */ 233 | public function setTemplates(array $templates) 234 | { 235 | $this->templates = $templates; 236 | return $this; 237 | } 238 | 239 | /** 240 | * Sets a list placeholders for message. 241 | * 242 | * ```php 243 | * $validate->required() 244 | * ->email() 245 | * ->setPlaceholders(['name' => 'email']) 246 | * ->validate('foo@site.com'); 247 | * ``` 248 | * @param array $placeholders 249 | * @return $this 250 | */ 251 | public function setPlaceholders(array $placeholders) 252 | { 253 | $this->placeholders = $placeholders; 254 | return $this; 255 | } 256 | 257 | /** 258 | * Sets a messages. 259 | * 260 | * ```php 261 | * $validate->required() 262 | * ->email() 263 | * ->setMessages(['required' => 'the value must not be empty']) 264 | * ->validate('foo@site.com'); 265 | * ``` 266 | * @param array $messages 267 | * @return $this 268 | */ 269 | public function setMessages(array $messages) 270 | { 271 | $this->messages = $messages; 272 | return $this; 273 | } 274 | 275 | /** 276 | * Enable skipped if the attribute value is null or an empty string 277 | * @param bool $enable 278 | * @return $this 279 | */ 280 | public function setSkipEmpty($enable) 281 | { 282 | $this->skipEmpty = $enable; 283 | return $this; 284 | } 285 | 286 | /** 287 | * Sets a label remainder. 288 | * @param string $label 289 | * @return $this 290 | */ 291 | public function setRemainder($label) 292 | { 293 | $this->remainder = $label; 294 | return $this; 295 | } 296 | 297 | /** 298 | * Checks a value. 299 | * @param mixed $input 300 | * @return bool 301 | * @throws ValidateException 302 | */ 303 | public function validate($input) 304 | { 305 | $this->errors = []; 306 | 307 | foreach($this->rawRules as $rules){ 308 | 309 | list($ruleName, $rule) = $rules; 310 | 311 | // notOf or oneOf 312 | if ($rule instanceof Validate) { 313 | $rule->validate($input); 314 | $this->errors = array_merge($this->errors, $rule->getErrors()); 315 | continue; 316 | } 317 | 318 | if ($rule instanceof When) { 319 | $rule->invert = $this->invert; 320 | $rule->validate($input); 321 | $this->errors = array_merge($this->errors, $rule->getErrors()); 322 | continue; 323 | } 324 | 325 | if ($rule instanceof Attributes) { 326 | $config = [ 327 | 'one' => $this->one, 328 | 'invert' => $this->invert, 329 | 'remainder' => $this->remainder 330 | ]; 331 | Instance::configure($rule, $config); 332 | $rule->validate($input); 333 | $this->errors = $rule->getErrors(); 334 | break; 335 | } 336 | 337 | if ($this->skipEmpty && $rule->skipEmpty && $this->isEmpty($input, $rule)) { 338 | continue; 339 | } 340 | 341 | if ($rule->validate($input) === !$this->invert) { 342 | continue; 343 | } 344 | $this->errors[$ruleName] = $this->error($ruleName, $rule); 345 | if ($this->one === true) { 346 | break; 347 | } 348 | } 349 | return empty($this->errors); 350 | } 351 | 352 | /** 353 | * Returns all errors. 354 | * @return array 355 | */ 356 | public function getErrors() 357 | { 358 | return $this->errors; 359 | } 360 | 361 | /** 362 | * Returns first error. 363 | * @param string|null $attribute 364 | * @return string|null 365 | */ 366 | public function getFirstError($attribute = null) 367 | { 368 | if (empty($this->errors)) { 369 | return null; 370 | } 371 | if (isset($attribute)) { 372 | if (isset($this->errors[$attribute])) { 373 | return current($this->errors[$attribute]); 374 | } 375 | return null; 376 | } 377 | $error = current($this->errors); 378 | if (is_array($error)) { 379 | return current($error); 380 | } 381 | return $error; 382 | } 383 | 384 | /** 385 | * Returns last error. 386 | * @param string|null $attribute 387 | * @return string|null 388 | */ 389 | public function getLastError($attribute = null) 390 | { 391 | if (empty($this->errors)) { 392 | return null; 393 | } 394 | if (isset($attribute)) { 395 | if (isset($this->errors[$attribute])) { 396 | return end($this->errors[$attribute]); 397 | } 398 | return null; 399 | } 400 | $error = end($this->errors); 401 | if (is_array($error)) { 402 | return end($error); 403 | } 404 | return $error; 405 | } 406 | 407 | /** 408 | * Exists rule. 409 | * @param string $name name of rule. 410 | * @return bool 411 | */ 412 | public function existsRule($name) 413 | { 414 | return isset($this->rules[$name]); 415 | } 416 | 417 | /** 418 | * @return rules\Rule[] 419 | */ 420 | public function getRawRules() 421 | { 422 | return $this->rawRules; 423 | } 424 | 425 | public function __call($name, $arguments) 426 | { 427 | if (method_exists($this, "{$name}Internal")) { 428 | return call_user_func_array([$this, "{$name}Internal"], $arguments); 429 | } 430 | 431 | if (!isset($this->rules[$name])) { 432 | throw new ValidateException("Unknown rule: {$name}"); 433 | } 434 | if (!class_exists($this->rules[$name]['class'])) { 435 | throw new ValidateException(ValidateException::UNKNOWN_CLASS, ['class' => $this->rules[$name]['class']]); 436 | } 437 | 438 | $rule = $this->getInstanceRule($name, $arguments); 439 | $this->rawRules[] = [$name, $rule]; 440 | return $this; 441 | } 442 | 443 | public static function __callStatic($name, $arguments) 444 | { 445 | return call_user_func_array([static::getInstance(), $name], $arguments); 446 | } 447 | 448 | /** 449 | * Checks if the given value is empty. 450 | * 451 | * A value is considered empty if it is null, an empty array, or the trimmed result is an empty string. 452 | * Note that this method is different from PHP empty(). It will return false when the value is 0. 453 | * 454 | * @param mixed $value the value to be checked 455 | * @param Rule $rule 456 | * @return bool whether the value is empty 457 | */ 458 | protected function isEmpty($value, Rule $rule) 459 | { 460 | if (is_callable($rule->isEmpty)) { 461 | return call_user_func($rule->isEmpty, $value); 462 | } 463 | 464 | return $value === null || $value === [] || $value === ''; 465 | } 466 | 467 | protected function attributesInternal($attributes) 468 | { 469 | $this->rawRules = []; 470 | $this->rawRules[] = ['attributes', new Attributes(['attributes' => $attributes, 'one' => $this->one, 'invert' => $this->invert, 'remainder' => $this->remainder])]; 471 | return $this; 472 | } 473 | 474 | protected function oneOfInternal(Validate $validate) 475 | { 476 | $validate->one = true; 477 | $this->rawRules[] = ['oneOf', $validate]; 478 | return $this; 479 | } 480 | 481 | protected function notOfInternal(Validate $validate) 482 | { 483 | $validate->invert = true; 484 | $this->rawRules[] = ['notOf', $validate]; 485 | return $this; 486 | } 487 | 488 | protected function whenInternal(Validate $if, Validate $then, Validate $else = null) 489 | { 490 | $this->rawRules[] = ['when', new When(['if' => $if, 'then' => $then, 'else' => $else, 'invert' => $this->invert])]; 491 | return $this; 492 | } 493 | 494 | protected function error($ruleName, Rule $rule) 495 | { 496 | if (isset($this->messages[$ruleName])) { 497 | return $this->replace($this->messages[$ruleName]); 498 | } 499 | /** @var Locale $locale */ 500 | $locale = isset($this->rules[$ruleName]['locales'][$this->locale]) 501 | ? $this->rules[$ruleName]['locales'][$this->locale] 502 | : current($this->rules[$ruleName]['locales']); 503 | if (!class_exists($locale)) { 504 | throw new ValidateException(ValidateException::UNKNOWN_CLASS, ['class' => $locale]); 505 | } 506 | $locale = new $locale; 507 | if (!$messages = $locale->defaultTemplates()) { 508 | throw new ValidateException("Messages `{$locale}` is empty."); 509 | } 510 | $this->placeholders = array_merge(call_user_func_array([$locale, 'defaultPlaceholders'], $rule->params), $this->placeholders); 511 | $mode = (int)!$this->invert; 512 | if (isset($this->templates[$ruleName])) { 513 | if (!isset($messages[$mode][$this->templates[$ruleName]])) { 514 | throw new ValidateException("Message `{$this->templates[$ruleName]}` is not found."); 515 | } 516 | return $this->replace($messages[$mode][$this->templates[$ruleName]]); 517 | } 518 | 519 | return $this->replace($messages[$mode][$locale->defaultTemplate]); 520 | } 521 | 522 | protected function replace($message) 523 | { 524 | if (empty($this->placeholders)) { 525 | return $message; 526 | } 527 | return StringHelper::replace($message, $this->placeholders); 528 | } 529 | 530 | /** 531 | * Returns instance rule. 532 | * @param string $name name of rule 533 | * @param array $arguments 534 | * @return Rule 535 | */ 536 | protected function getInstanceRule($name, array $arguments) 537 | { 538 | $reflect = new \ReflectionClass($this->rules[$name]['class']); 539 | return $reflect->newInstanceArgs($arguments); 540 | } 541 | 542 | /** 543 | * Returns instance. 544 | * 545 | * If exists {@see \rock\di\Container} that uses it. 546 | * @return static 547 | */ 548 | protected static function getInstance() 549 | { 550 | if (class_exists('\rock\di\Container')) { 551 | return \rock\di\Container::load(static::className()); 552 | } 553 | return new static(); 554 | } 555 | 556 | protected function defaultRules() 557 | { 558 | return [ 559 | 'alnum' => [ 560 | 'class' => Alnum::className(), 561 | 'locales' => [ 562 | 'en' => \rock\validate\locale\en\Alnum::className(), 563 | 'ru' => \rock\validate\locale\ru\Alnum::className(), 564 | ] 565 | ], 566 | 'alpha' => [ 567 | 'class' => Alpha::className(), 568 | 'locales' => [ 569 | 'en' => \rock\validate\locale\en\Alpha::className(), 570 | 'ru' => \rock\validate\locale\ru\Alpha::className(), 571 | ] 572 | ], 573 | 'arr' => [ 574 | 'class' => Arr::className(), 575 | 'locales' => [ 576 | 'en' => \rock\validate\locale\en\Arr::className(), 577 | 'ru' => \rock\validate\locale\ru\Arr::className(), 578 | ] 579 | ], 580 | 'between' => [ 581 | 'class' => Between::className(), 582 | 'locales' => [ 583 | 'en' => \rock\validate\locale\en\Between::className(), 584 | 'ru' => \rock\validate\locale\ru\Between::className(), 585 | ] 586 | ], 587 | 'bool' => [ 588 | 'class' => BoolRule::className(), 589 | 'locales' => [ 590 | 'en' => \rock\validate\locale\en\BoolLocale::className(), 591 | 'ru' => \rock\validate\locale\ru\BoolLocale::className(), 592 | ] 593 | ], 594 | 'call' => [ 595 | 'class' => Call::className(), 596 | 'locales' => [ 597 | 'en' => \rock\validate\locale\en\Call::className(), 598 | 'ru' => \rock\validate\locale\ru\Call::className(), 599 | ] 600 | ], 601 | 'captcha' => [ 602 | 'class' => Captcha::className(), 603 | 'locales' => [ 604 | 'en' => \rock\validate\locale\en\Captcha::className(), 605 | 'ru' => \rock\validate\locale\ru\Captcha::className(), 606 | ] 607 | ], 608 | 'closure' => [ 609 | 'class' => Closure::className(), 610 | 'locales' => [ 611 | 'en' => \rock\validate\locale\en\Closure::className(), 612 | 'ru' => \rock\validate\locale\ru\Closure::className(), 613 | ] 614 | ], 615 | 'cntrl' => [ 616 | 'class' => Cntrl::className(), 617 | 'locales' => [ 618 | 'en' => \rock\validate\locale\en\Cntrl::className(), 619 | 'ru' => \rock\validate\locale\ru\Cntrl::className(), 620 | ] 621 | ], 622 | 'confirm' => [ 623 | 'class' => Confirm::className(), 624 | 'locales' => [ 625 | 'en' => \rock\validate\locale\en\Confirm::className(), 626 | 'ru' => \rock\validate\locale\ru\Confirm::className(), 627 | ] 628 | ], 629 | 'contains' => [ 630 | 'class' => Contains::className(), 631 | 'locales' => [ 632 | 'en' => \rock\validate\locale\en\Contains::className(), 633 | 'ru' => \rock\validate\locale\ru\Contains::className(), 634 | ] 635 | ], 636 | 'csrf' => [ 637 | 'class' => CSRF::className(), 638 | 'locales' => [ 639 | 'en' => \rock\validate\locale\en\CSRF::className(), 640 | 'ru' => \rock\validate\locale\ru\CSRF::className(), 641 | ] 642 | ], 643 | 'date' => [ 644 | 'class' => Date::className(), 645 | 'locales' => [ 646 | 'en' => \rock\validate\locale\en\Date::className(), 647 | 'ru' => \rock\validate\locale\ru\Date::className(), 648 | ] 649 | ], 650 | 'digit' => [ 651 | 'class' => Digit::className(), 652 | 'locales' => [ 653 | 'en' => \rock\validate\locale\en\Digit::className(), 654 | 'ru' => \rock\validate\locale\ru\Digit::className(), 655 | ] 656 | ], 657 | 'directory' => [ 658 | 'class' => Directory::className(), 659 | 'locales' => [ 660 | 'en' => \rock\validate\locale\en\Directory::className(), 661 | 'ru' => \rock\validate\locale\ru\Directory::className(), 662 | ] 663 | ], 664 | 'domain' => [ 665 | 'class' => Domain::className(), 666 | 'locales' => [ 667 | 'en' => \rock\validate\locale\en\Domain::className(), 668 | 'ru' => \rock\validate\locale\ru\Domain::className(), 669 | ] 670 | ], 671 | 'email' => [ 672 | 'class' => Email::className(), 673 | 'locales' => [ 674 | 'en' => \rock\validate\locale\en\Email::className(), 675 | 'ru' => \rock\validate\locale\ru\Email::className(), 676 | ] 677 | ], 678 | 'endsWith' => [ 679 | 'class' => EndsWith::className(), 680 | 'locales' => [ 681 | 'en' => \rock\validate\locale\en\EndsWith::className(), 682 | 'ru' => \rock\validate\locale\ru\EndsWith::className(), 683 | ] 684 | ], 685 | 'equals' => [ 686 | 'class' => Equals::className(), 687 | 'locales' => [ 688 | 'en' => \rock\validate\locale\en\Equals::className(), 689 | 'ru' => \rock\validate\locale\ru\Equals::className(), 690 | ] 691 | ], 692 | 'file' => [ 693 | 'class' => File::className(), 694 | 'locales' => [ 695 | 'en' => \rock\validate\locale\en\File::className(), 696 | 'ru' => \rock\validate\locale\ru\File::className(), 697 | ] 698 | ], 699 | 'fileExists' => [ 700 | 'class' => Exists::className(), 701 | 'locales' => [ 702 | 'en' => \rock\validate\locale\en\Exists::className(), 703 | 'ru' => \rock\validate\locale\ru\Exists::className(), 704 | ] 705 | ], 706 | 'fileExtensions' => [ 707 | 'class' => FileExtensions::className(), 708 | 'locales' => [ 709 | 'en' => \rock\validate\locale\en\FileExtensions::className(), 710 | 'ru' => \rock\validate\locale\ru\FileExtensions::className(), 711 | ] 712 | ], 713 | 'fileMimeTypes' => [ 714 | 'class' => FileMimeTypes::className(), 715 | 'locales' => [ 716 | 'en' => \rock\validate\locale\en\FileMimeTypes::className(), 717 | 'ru' => \rock\validate\locale\ru\FileMimeTypes::className(), 718 | ] 719 | ], 720 | 'fileSizeBetween' => [ 721 | 'class' => FileSizeBetween::className(), 722 | 'locales' => [ 723 | 'en' => \rock\validate\locale\en\FileSizeBetween::className(), 724 | 'ru' => \rock\validate\locale\ru\FileSizeBetween::className(), 725 | ] 726 | ], 727 | 'fileSizeMax' => [ 728 | 'class' => FileSizeMax::className(), 729 | 'locales' => [ 730 | 'en' => \rock\validate\locale\en\FileSizeMax::className(), 731 | 'ru' => \rock\validate\locale\ru\FileSizeMax::className(), 732 | ] 733 | ], 734 | 'fileSizeMin' => [ 735 | 'class' => FileSizeMin::className(), 736 | 'locales' => [ 737 | 'en' => \rock\validate\locale\en\FileSizeMin::className(), 738 | 'ru' => \rock\validate\locale\ru\FileSizeMin::className(), 739 | ] 740 | ], 741 | 'float' => [ 742 | 'class' => FloatRule::className(), 743 | 'locales' => [ 744 | 'en' => \rock\validate\locale\en\FloatLocale::className(), 745 | 'ru' => \rock\validate\locale\ru\FloatLocale::className(), 746 | ] 747 | ], 748 | 'graph' => [ 749 | 'class' => Graph::className(), 750 | 'locales' => [ 751 | 'en' => \rock\validate\locale\en\Graph::className(), 752 | 'ru' => \rock\validate\locale\ru\Graph::className(), 753 | ] 754 | ], 755 | 'in' => [ 756 | 'class' => In::className(), 757 | 'locales' => [ 758 | 'en' => \rock\validate\locale\en\In::className(), 759 | 'ru' => \rock\validate\locale\ru\In::className(), 760 | ] 761 | ], 762 | 'int' => [ 763 | 'class' => IntRule::className(), 764 | 'locales' => [ 765 | 'en' => \rock\validate\locale\en\IntLocale::className(), 766 | 'ru' => \rock\validate\locale\ru\IntLocale::className(), 767 | ] 768 | ], 769 | 'ip' => [ 770 | 'class' => Ip::className(), 771 | 'locales' => [ 772 | 'en' => \rock\validate\locale\en\Ip::className(), 773 | 'ru' => \rock\validate\locale\ru\Ip::className(), 774 | ] 775 | ], 776 | 'json' => [ 777 | 'class' => JSON::className(), 778 | 'locales' => [ 779 | 'en' => \rock\validate\locale\en\JSON::className(), 780 | 'ru' => \rock\validate\locale\ru\JSON::className(), 781 | ] 782 | ], 783 | 'length' => [ 784 | 'class' => Length::className(), 785 | 'locales' => [ 786 | 'en' => \rock\validate\locale\en\Length::className(), 787 | 'ru' => \rock\validate\locale\ru\Length::className(), 788 | ] 789 | ], 790 | 'lowercase' => [ 791 | 'class' => Lowercase::className(), 792 | 'locales' => [ 793 | 'en' => \rock\validate\locale\en\Lowercase::className(), 794 | 'ru' => \rock\validate\locale\ru\Lowercase::className(), 795 | ] 796 | ], 797 | 'max' => [ 798 | 'class' => Max::className(), 799 | 'locales' => [ 800 | 'en' => \rock\validate\locale\en\Max::className(), 801 | 'ru' => \rock\validate\locale\ru\Max::className(), 802 | ] 803 | ], 804 | 'min' => [ 805 | 'class' => Min::className(), 806 | 'locales' => [ 807 | 'en' => \rock\validate\locale\en\Min::className(), 808 | 'ru' => \rock\validate\locale\ru\Min::className(), 809 | ] 810 | ], 811 | 'negative' => [ 812 | 'class' => Negative::className(), 813 | 'locales' => [ 814 | 'en' => \rock\validate\locale\en\Negative::className(), 815 | 'ru' => \rock\validate\locale\ru\Negative::className(), 816 | ] 817 | ], 818 | 'required' => [ 819 | 'class' => Required::className(), 820 | 'locales' => [ 821 | 'en' => \rock\validate\locale\en\Required::className(), 822 | 'ru' =>\rock\validate\locale\ru\Required::className(), 823 | ] 824 | ], 825 | 'noWhitespace' => [ 826 | 'class' => NoWhitespace::className(), 827 | 'locales' => [ 828 | 'en' => \rock\validate\locale\en\NoWhitespace::className(), 829 | 'ru' =>\rock\validate\locale\ru\NoWhitespace::className(), 830 | ] 831 | ], 832 | 'nullValue' => [ 833 | 'class' => NullValue::className(), 834 | 'locales' => [ 835 | 'en' => \rock\validate\locale\en\NullValue::className(), 836 | 'ru' =>\rock\validate\locale\ru\NullValue::className(), 837 | ] 838 | ], 839 | 'numeric' => [ 840 | 'class' => Numeric::className(), 841 | 'locales' => [ 842 | 'en' => \rock\validate\locale\en\Numeric::className(), 843 | 'ru' =>\rock\validate\locale\ru\Numeric::className(), 844 | ] 845 | ], 846 | 'object' => [ 847 | 'class' => Object::className(), 848 | 'locales' => [ 849 | 'en' => \rock\validate\locale\en\Object::className(), 850 | 'ru' =>\rock\validate\locale\ru\Object::className(), 851 | ] 852 | ], 853 | 'odd' => [ 854 | 'class' => Odd::className(), 855 | 'locales' => [ 856 | 'en' => \rock\validate\locale\en\Odd::className(), 857 | 'ru' =>\rock\validate\locale\ru\Odd::className(), 858 | ] 859 | ], 860 | 'positive' => [ 861 | 'class' => Positive::className(), 862 | 'locales' => [ 863 | 'en' => \rock\validate\locale\en\Positive::className(), 864 | 'ru' =>\rock\validate\locale\ru\Positive::className(), 865 | ] 866 | ], 867 | 'readable' => [ 868 | 'class' => Readable::className(), 869 | 'locales' => [ 870 | 'en' => \rock\validate\locale\en\Readable::className(), 871 | 'ru' =>\rock\validate\locale\ru\Readable::className(), 872 | ] 873 | ], 874 | 'regex' => [ 875 | 'class' => Regex::className(), 876 | 'locales' => [ 877 | 'en' => \rock\validate\locale\en\Regex::className(), 878 | 'ru' =>\rock\validate\locale\ru\Regex::className(), 879 | ] 880 | ], 881 | 'space' => [ 882 | 'class' => Space::className(), 883 | 'locales' => [ 884 | 'en' => \rock\validate\locale\en\Space::className(), 885 | 'ru' =>\rock\validate\locale\ru\Space::className(), 886 | ] 887 | ], 888 | 'startsWith' => [ 889 | 'class' => StartsWith::className(), 890 | 'locales' => [ 891 | 'en' => \rock\validate\locale\en\StartsWith::className(), 892 | 'ru' =>\rock\validate\locale\ru\StartsWith::className(), 893 | ] 894 | ], 895 | 'string' => [ 896 | 'class' => \rock\validate\rules\StringRule::className(), 897 | 'locales' => [ 898 | 'en' => \rock\validate\locale\en\StringLocale::className(), 899 | 'ru' => \rock\validate\locale\ru\StringLocale::className(), 900 | ] 901 | ], 902 | 'symbolicLink' => [ 903 | 'class' => SymbolicLink::className(), 904 | 'locales' => [ 905 | 'en' => \rock\validate\locale\en\SymbolicLink::className(), 906 | 'ru' => \rock\validate\locale\ru\SymbolicLink::className(), 907 | ] 908 | ], 909 | 'uploaded' => [ 910 | 'class' => Uploaded::className(), 911 | 'locales' => [ 912 | 'en' => \rock\validate\locale\en\Uploaded::className(), 913 | 'ru' => \rock\validate\locale\ru\Uploaded::className(), 914 | ] 915 | ], 916 | 'uppercase' => [ 917 | 'class' => Uppercase::className(), 918 | 'locales' => [ 919 | 'en' => \rock\validate\locale\en\Uppercase::className(), 920 | 'ru' => \rock\validate\locale\ru\Uppercase::className(), 921 | ] 922 | ], 923 | 'writable' => [ 924 | 'class' => Writable::className(), 925 | 'locales' => [ 926 | 'en' => \rock\validate\locale\en\Writable::className(), 927 | 'ru' => \rock\validate\locale\ru\Writable::className(), 928 | ] 929 | ], 930 | ]; 931 | } 932 | } -------------------------------------------------------------------------------- /src/ValidateException.php: -------------------------------------------------------------------------------- 1 | parentConstruct($config); 26 | } 27 | 28 | public function validate($value) 29 | { 30 | $this->if->invert = $this->then->invert = $this->invert; 31 | if ($this->if->validate($value)) { 32 | if (!$this->then->validate($value)) { 33 | $this->errors = $this->then->getErrors(); 34 | return false; 35 | } 36 | return true; 37 | } 38 | 39 | if (!isset($this->else)) { 40 | return $this->invert; 41 | } 42 | 43 | $this->else->invert = $this->invert; 44 | if (!$this->else->validate($value)) { 45 | $this->errors = $this->else->getErrors(); 46 | return false; 47 | } 48 | return true; 49 | } 50 | 51 | public function getErrors() 52 | { 53 | return $this->errors; 54 | } 55 | } -------------------------------------------------------------------------------- /src/locale/Locale.php: -------------------------------------------------------------------------------- 1 | 'value']; 36 | } 37 | } -------------------------------------------------------------------------------- /src/locale/en/Alnum.php: -------------------------------------------------------------------------------- 1 | [ 16 | self::STANDARD => '{{name}} must not contain letters (a-z)', 17 | self::EXTRA => '{{name}} must not contain letters (a-z) and "{{additionalChars}}"' 18 | ], 19 | self::MODE_NEGATIVE => [ 20 | self::STANDARD => '{{name}} must not contain letters (a-z)', 21 | self::EXTRA => '{{name}} must not contain letters (a-z) or "{{additionalChars}}"' 22 | ] 23 | ]; 24 | } 25 | 26 | public function defaultPlaceholders($additionalChars = '') 27 | { 28 | $this->defaultTemplate = $additionalChars ? self::EXTRA : self::STANDARD; 29 | return ['name' => 'value', 'additionalChars' => $additionalChars]; 30 | } 31 | } -------------------------------------------------------------------------------- /src/locale/en/Alpha.php: -------------------------------------------------------------------------------- 1 | [ 16 | self::STANDARD => '{{name}} must contain only letters (a-z)', 17 | self::EXTRA => '{{name}} must contain only letters (a-z) and "{{additionalChars}}"' 18 | ], 19 | self::MODE_NEGATIVE => [ 20 | self::STANDARD => '{{name}} must not contain letters (a-z)', 21 | self::EXTRA => '{{name}} must not contain letters (a-z) or "{{additionalChars}}"' 22 | ] 23 | ]; 24 | } 25 | 26 | public function defaultPlaceholders($additionalChars = '') 27 | { 28 | $this->defaultTemplate = $additionalChars ? self::EXTRA : self::STANDARD; 29 | return ['name' => 'value', 'additionalChars' => $additionalChars]; 30 | } 31 | } -------------------------------------------------------------------------------- /src/locale/en/Arr.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be an array', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be an array', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Between.php: -------------------------------------------------------------------------------- 1 | [ 19 | self::BOTH => '{{name}} must be between {{minValue}} and {{maxValue}}', 20 | self::LOWER => '{{name}} must be greater than {{minValue}}', 21 | self::GREATER => '{{name}} must be lower than {{maxValue}}', 22 | ], 23 | self::MODE_NEGATIVE => [ 24 | self::BOTH => '{{name}} must not be between {{minValue}} and {{maxValue}}', 25 | self::LOWER => '{{name}} must not be greater than {{minValue}}', 26 | self::GREATER => '{{name}} must not be lower than {{maxValue}}', 27 | ] 28 | ]; 29 | } 30 | 31 | public function defaultPlaceholders($minValue = null, $maxValue = null) 32 | { 33 | if (!isset($minValue)) { 34 | $this->defaultTemplate = static::GREATER; 35 | } elseif (!isset($maxValue)) { 36 | $this->defaultTemplate = static::LOWER; 37 | } else { 38 | $this->defaultTemplate = static::BOTH; 39 | } 40 | if ($minValue instanceof \DateTime) { 41 | $minValue = $minValue->format('Y-m-d H:i:s'); 42 | } elseif ($minValue instanceof DateTime) { 43 | $minValue = $minValue->format(); 44 | } 45 | 46 | if ($maxValue instanceof \DateTime) { 47 | $maxValue = $maxValue->format('Y-m-d H:i:s'); 48 | } elseif ($maxValue instanceof DateTime) { 49 | $maxValue = $maxValue->format(); 50 | } 51 | return [ 52 | 'name' => 'value', 53 | 'minValue' => $minValue, 54 | 'maxValue' => $maxValue 55 | ]; 56 | } 57 | } -------------------------------------------------------------------------------- /src/locale/en/BoolLocale.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be a boolean', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be a boolean', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/CSRF.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => 'CSRF-token must be valid', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => 'CSRF-token must not be valid', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Call.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be valid', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be valid', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Captcha.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => 'captcha must be valid', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => 'captcha must not be valid', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Closure.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be a callable', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be a callable', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Cntrl.php: -------------------------------------------------------------------------------- 1 | [ 16 | self::STANDARD => '{{name}} must contain only control characters', 17 | self::EXTRA => '{{name}} must contain only control characters and "{{additionalChars}}"' 18 | ], 19 | self::MODE_NEGATIVE => [ 20 | self::STANDARD => '{{name}} must not contain control characters', 21 | self::EXTRA => '{{name}} must not contain control characters or "{{additionalChars}}"' 22 | ] 23 | ]; 24 | } 25 | 26 | public function defaultPlaceholders($additionalChars = '') 27 | { 28 | $this->defaultTemplate = $additionalChars ? self::EXTRA : self::STANDARD; 29 | return ['name' => 'value', 'additionalChars' => $additionalChars]; 30 | } 31 | } -------------------------------------------------------------------------------- /src/locale/en/Confirm.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => 'values must be equals', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => 'values must not be equals', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Contains.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must contain the value "{{containsValue}}"', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not contain the value "{{containsValue}}"', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders($containsValue = null) 23 | { 24 | return [ 25 | 'name' => 'value', 26 | 'containsValue' => $containsValue 27 | ]; 28 | } 29 | } -------------------------------------------------------------------------------- /src/locale/en/Date.php: -------------------------------------------------------------------------------- 1 | [ 16 | self::STANDARD => '{{name}} must be date', 17 | self::FORMAT => '{{name}} must be a valid date. Sample format: {{format}}' 18 | ], 19 | self::MODE_NEGATIVE => [ 20 | self::STANDARD => '{{name}} must not be date', 21 | self::FORMAT => '{{name}} must not be a valid date in the format {{format}}' 22 | ] 23 | ]; 24 | } 25 | 26 | public function defaultPlaceholders($format = null) 27 | { 28 | if (empty($format)) { 29 | return [ 30 | 'name' => 'value', 31 | ]; 32 | } 33 | 34 | return [ 35 | 'name' => 'value', 36 | 'format' => date($format, strtotime('2005-12-30 01:02:03')) 37 | ]; 38 | } 39 | } -------------------------------------------------------------------------------- /src/locale/en/Digit.php: -------------------------------------------------------------------------------- 1 | [ 16 | self::STANDARD => '{{name}} must contain only digits (0-9)', 17 | self::EXTRA => '{{name}} must contain only digits (0-9) and "{{additionalChars}}"' 18 | ], 19 | self::MODE_NEGATIVE => [ 20 | self::STANDARD => '{{name}} must not contain digits (0-9)', 21 | self::EXTRA => '{{name}} must not contain digits (0-9) or "{{additionalChars}}"' 22 | ] 23 | ]; 24 | } 25 | 26 | public function defaultPlaceholders($additionalChars = '') 27 | { 28 | $this->defaultTemplate = $additionalChars ? self::EXTRA : self::STANDARD; 29 | return ['name' => 'value', 'additionalChars' => $additionalChars]; 30 | } 31 | } -------------------------------------------------------------------------------- /src/locale/en/Directory.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be a directory', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be a directory', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders() 23 | { 24 | return ['name' => 'value']; 25 | } 26 | } -------------------------------------------------------------------------------- /src/locale/en/Domain.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be a valid domain', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be a valid domain', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders() 23 | { 24 | return ['name' => 'domain']; 25 | } 26 | } -------------------------------------------------------------------------------- /src/locale/en/Email.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be valid', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be valid', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders() 23 | { 24 | return ['name' => 'email']; 25 | } 26 | } -------------------------------------------------------------------------------- /src/locale/en/EndsWith.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must end with "{{endValue}}"', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not end with "{{endValue}}"', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders($endValue = null) 23 | { 24 | return [ 25 | 'name' => 'value', 26 | 'endValue' => $endValue 27 | ]; 28 | } 29 | } -------------------------------------------------------------------------------- /src/locale/en/Equals.php: -------------------------------------------------------------------------------- 1 | [ 17 | self::EQUALS => '{{name}} must be equals {{compareTo}}', 18 | self::IDENTICAL => '{{name}} must be identical as {{compareTo}}', 19 | ], 20 | self::MODE_NEGATIVE => [ 21 | self::EQUALS => '{{name}} must not be equals {{compareTo}}', 22 | self::IDENTICAL => '{{name}} must not be identical as {{compareTo}}', 23 | ] 24 | ]; 25 | } 26 | 27 | public function defaultPlaceholders($compareTo = null, $compareIdentical = false) 28 | { 29 | $this->defaultTemplate = $compareIdentical ? self::IDENTICAL : self::EQUALS; 30 | return ['name' => 'value']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/en/Exists.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must exists', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not exists', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders() 23 | { 24 | return ['name' => 'file']; 25 | } 26 | } -------------------------------------------------------------------------------- /src/locale/en/File.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be a file', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be a file', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/FileExtensions.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => 'Extension of {{name}} must be: {{extensions}}', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => 'Extension of {{name}} must not be: {{extensions}}', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders($extensions = null) 23 | { 24 | if (is_array($extensions)) { 25 | $extensions = implode(', ', $extensions); 26 | } 27 | return [ 28 | 'name' => 'file', 29 | 'extensions' => $extensions 30 | ]; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/en/FileMimeTypes.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => 'Mime-type of {{name}} must be: {{mimeTypes}}', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => 'Mime-type of {{name}} must not be: {{mimeTypes}}', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders($mimeTypes = null) 23 | { 24 | return [ 25 | 'name' => 'file', 26 | 'mimeTypes' => $mimeTypes 27 | ]; 28 | } 29 | } -------------------------------------------------------------------------------- /src/locale/en/FileSizeBetween.php: -------------------------------------------------------------------------------- 1 | [ 19 | self::BOTH => 'Size of {{name}} must be between {{minValue}} and {{maxValue}} bytes', 20 | self::LOWER => 'Size of {{name}} must be greater than {{minValue}} bytes', 21 | self::GREATER => 'Size of {{name}} must be lower than {{maxValue}} bytes', 22 | ], 23 | self::MODE_NEGATIVE => [ 24 | self::BOTH => 'Size of {{name}} must not be between {{minValue}} and {{maxValue}} bytes', 25 | self::LOWER => 'Size of {{name}} must not be greater than {{minValue}} bytes', 26 | self::GREATER => 'Size of {{name}} must not be lower than {{maxValue}} bytes', 27 | ] 28 | ]; 29 | } 30 | 31 | public function defaultPlaceholders($minValue = null, $maxValue = null) 32 | { 33 | if (!isset($minValue)) { 34 | $this->defaultTemplate = static::GREATER; 35 | } elseif (!isset($maxValue)) { 36 | $this->defaultTemplate = static::LOWER; 37 | } else { 38 | $this->defaultTemplate = static::BOTH; 39 | } 40 | 41 | return [ 42 | 'name' => 'file', 43 | 'minValue' => $minValue, 44 | 'maxValue' => $maxValue 45 | ]; 46 | } 47 | } -------------------------------------------------------------------------------- /src/locale/en/FileSizeMax.php: -------------------------------------------------------------------------------- 1 | [ 16 | self::STANDARD => 'Size of {{name}} must be lower than {{maxValue}} bytes', 17 | self::INCLUSIVE => 'Size of {{name}} must be lower than or equals {{maxValue}} bytes', 18 | ], 19 | self::MODE_NEGATIVE => [ 20 | self::STANDARD => 'Size of {{name}} must not be lower than {{maxValue}} bytes', 21 | self::INCLUSIVE => 'Size of {{name}} must not be lower than or equals {{maxValue}} bytes', 22 | ] 23 | ]; 24 | } 25 | 26 | public function defaultPlaceholders($maxValue = null, $inclusive = false) 27 | { 28 | $this->defaultTemplate = $inclusive ? static::INCLUSIVE : static::STANDARD; 29 | return [ 30 | 'name' => 'file', 31 | 'maxValue' => $maxValue 32 | ]; 33 | } 34 | } -------------------------------------------------------------------------------- /src/locale/en/FileSizeMin.php: -------------------------------------------------------------------------------- 1 | [ 16 | self::STANDARD => '{{name}} size must be greater than {{minValue}} bytes', 17 | self::INCLUSIVE => '{{name}} size must be greater than or equals {{minValue}} bytes', 18 | ], 19 | self::MODE_NEGATIVE => [ 20 | self::STANDARD => '{{name}} size must not be greater than {{minValue}} bytes', 21 | self::INCLUSIVE => '{{name}} size must not be greater than or equals {{minValue}} bytes', 22 | ] 23 | ]; 24 | } 25 | 26 | public function defaultPlaceholders($minValue = null, $inclusive = false) 27 | { 28 | $this->defaultTemplate = $inclusive ? static::INCLUSIVE : static::STANDARD; 29 | return [ 30 | 'name' => 'file', 31 | 'minValue' => $minValue 32 | ]; 33 | } 34 | } -------------------------------------------------------------------------------- /src/locale/en/FloatLocale.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be a float number', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be a float number', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Graph.php: -------------------------------------------------------------------------------- 1 | [ 16 | self::STANDARD => '{{name}} must contain only graphical characters', 17 | self::EXTRA => '{{name}} must contain only graphical characters and "{{additionalChars}}"' 18 | ], 19 | self::MODE_NEGATIVE => [ 20 | self::STANDARD => '{{name}} must not contain graphical characters', 21 | self::EXTRA => '{{name}} must not contain graphical characters or "{{additionalChars}}"' 22 | ] 23 | ]; 24 | } 25 | 26 | public function defaultPlaceholders($additionalChars = '') 27 | { 28 | $this->defaultTemplate = $additionalChars ? self::EXTRA : self::STANDARD; 29 | return ['name' => 'value', 'additionalChars' => $additionalChars]; 30 | } 31 | } -------------------------------------------------------------------------------- /src/locale/en/In.php: -------------------------------------------------------------------------------- 1 | [ 16 | self::STANDARD => '{{name}} must be in: {{haystack}}', 17 | ], 18 | self::MODE_NEGATIVE => [ 19 | self::STANDARD => '{{name}} must not be in: {{haystack}}', 20 | ] 21 | ]; 22 | } 23 | 24 | public function defaultPlaceholders($haystack = null) 25 | { 26 | return [ 27 | 'name' => 'value', 28 | 'haystack' => is_array($haystack) ? implode(', ', $haystack) : $haystack 29 | ]; 30 | } 31 | } -------------------------------------------------------------------------------- /src/locale/en/IntLocale.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be an integer number', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be an integer number', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Ip.php: -------------------------------------------------------------------------------- 1 | [ 17 | self::STANDARD => '{{name}} must be an IP address', 18 | self::NETWORK_RANGE => '{{name}} must be an IP address in the {{range}} range', 19 | ], 20 | self::MODE_NEGATIVE => [ 21 | self::STANDARD => '{{name}} must not be an IP address', 22 | self::NETWORK_RANGE => '{{name}} must not be an IP address in the {{range}} range', 23 | ] 24 | ]; 25 | } 26 | 27 | public function defaultPlaceholders(array $range = null) 28 | { 29 | $message = ''; 30 | if (!empty($range)) { 31 | $message = $range['min']; 32 | $message .= isset($range['max']) ? '-' . $range['max'] : '/' . long2ip((int)$range['mask']); 33 | } 34 | $this->defaultTemplate = !empty($message) ? self::NETWORK_RANGE : self::STANDARD; 35 | return [ 36 | 'name' => 'value', 37 | 'range' => $message 38 | ]; 39 | } 40 | } -------------------------------------------------------------------------------- /src/locale/en/JSON.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be a valid JSON string', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be a valid JSON string', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Length.php: -------------------------------------------------------------------------------- 1 | [ 18 | self::BOTH => '{{name}} must have a length between {{minValue}} and {{maxValue}}', 19 | self::LOWER => '{{name}} must have a length greater than {{minValue}}', 20 | self::GREATER => '{{name}} must have a length lower than {{maxValue}}', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::BOTH => '{{name}} must not have a length between {{minValue}} and {{maxValue}}', 24 | self::LOWER => '{{name}} must not have a length greater than {{minValue}}', 25 | self::GREATER => '{{name}} must not have a length lower than {{maxValue}}', 26 | ] 27 | ]; 28 | } 29 | 30 | public function defaultPlaceholders($minValue = null, $maxValue = null) 31 | { 32 | if (!isset($minValue)) { 33 | $this->defaultTemplate = static::GREATER; 34 | } elseif (!isset($maxValue)) { 35 | $this->defaultTemplate = static::LOWER; 36 | } else { 37 | $this->defaultTemplate = static::BOTH; 38 | } 39 | return [ 40 | 'name' => 'value', 41 | 'minValue' => $minValue, 42 | 'maxValue' => $maxValue 43 | ]; 44 | } 45 | } -------------------------------------------------------------------------------- /src/locale/en/Lowercase.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be lowercase', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be lowercase', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Max.php: -------------------------------------------------------------------------------- 1 | [ 17 | self::STANDARD => '{{name}} must be lower than {{maxValue}}', 18 | self::INCLUSIVE => '{{name}} must be lower than or equals {{maxValue}}', 19 | ], 20 | self::MODE_NEGATIVE => [ 21 | self::STANDARD => '{{name}} must not be lower than {{maxValue}}', 22 | self::INCLUSIVE => '{{name}} must not be lower than or equals {{maxValue}}', 23 | ] 24 | ]; 25 | } 26 | 27 | public function defaultPlaceholders($maxValue = null, $inclusive = false) 28 | { 29 | $this->defaultTemplate = $inclusive ? static::INCLUSIVE : static::STANDARD; 30 | if ($maxValue instanceof \DateTime) { 31 | $maxValue = $maxValue->format('Y-m-d H:i:s'); 32 | } elseif ($maxValue instanceof DateTime) { 33 | $maxValue = $maxValue->format(); 34 | } 35 | return [ 36 | 'name' => 'value', 37 | 'maxValue' => $maxValue 38 | ]; 39 | } 40 | } -------------------------------------------------------------------------------- /src/locale/en/Min.php: -------------------------------------------------------------------------------- 1 | [ 17 | self::STANDARD => '{{name}} must be greater than {{minValue}}', 18 | self::INCLUSIVE => '{{name}} must be greater than or equals {{minValue}}', 19 | ], 20 | self::MODE_NEGATIVE => [ 21 | self::STANDARD => '{{name}} must not be greater than {{minValue}}', 22 | self::INCLUSIVE => '{{name}} must not be greater than or equals {{minValue}}', 23 | ] 24 | ]; 25 | } 26 | 27 | public function defaultPlaceholders($minValue = null, $inclusive = false) 28 | { 29 | $this->defaultTemplate = $inclusive ? static::INCLUSIVE : static::STANDARD; 30 | if ($minValue instanceof \DateTime) { 31 | $minValue = $minValue->format('Y-m-d H:i:s'); 32 | } elseif ($minValue instanceof DateTime) { 33 | $minValue = $minValue->format(); 34 | } 35 | return [ 36 | 'name' => 'value', 37 | 'minValue' => $minValue 38 | ]; 39 | } 40 | } -------------------------------------------------------------------------------- /src/locale/en/Negative.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be negative', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be negative', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/NoWhitespace.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must not contain whitespace', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must contain whitespace', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/NullValue.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be null', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be null', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Numeric.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be numeric', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be numeric', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Object.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be an object', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be an object', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Odd.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be an odd number', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be an odd number', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders() 23 | { 24 | return ['name' => 'значение']; 25 | } 26 | } -------------------------------------------------------------------------------- /src/locale/en/Positive.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be positive', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be positive', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Readable.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be readable', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be readable', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders() 23 | { 24 | return ['name' => 'file']; 25 | } 26 | } -------------------------------------------------------------------------------- /src/locale/en/Regex.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} contains invalid characters', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} does not contain invalid characters', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Required.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must not be empty', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must be empty', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Space.php: -------------------------------------------------------------------------------- 1 | [ 16 | self::STANDARD => '{{name}} must contain only space characters', 17 | self::EXTRA => '{{name}} must contain only space characters and "{{additionalChars}}"' 18 | ], 19 | self::MODE_NEGATIVE => [ 20 | self::STANDARD => '{{name}} must not contain space characters', 21 | self::EXTRA => '{{name}} must not contain space characters or "{{additionalChars}}"' 22 | ] 23 | ]; 24 | } 25 | 26 | public function defaultPlaceholders($additionalChars = '') 27 | { 28 | $this->defaultTemplate = $additionalChars ? self::EXTRA : self::STANDARD; 29 | return ['name' => 'value', 'additionalChars' => $additionalChars]; 30 | } 31 | } -------------------------------------------------------------------------------- /src/locale/en/StartsWith.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must start with ({{startValue}})', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not start with ({{startValue}})', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders($startValue = null) 23 | { 24 | return [ 25 | 'name' => 'value', 26 | 'startValue' => $startValue 27 | ]; 28 | } 29 | } -------------------------------------------------------------------------------- /src/locale/en/StringLocale.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be string', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be string', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/SymbolicLink.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be a symbolic link', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be a symbolic link', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders() 23 | { 24 | return ['name' => 'file']; 25 | } 26 | } -------------------------------------------------------------------------------- /src/locale/en/Uploaded.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be an uploaded file', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be an uploaded file', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders() 23 | { 24 | return ['name' => 'file']; 25 | } 26 | } -------------------------------------------------------------------------------- /src/locale/en/Uppercase.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be uppercase', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be uppercase', 18 | ] 19 | ]; 20 | } 21 | } -------------------------------------------------------------------------------- /src/locale/en/Writable.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} must be writable', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} must not be writable', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders() 23 | { 24 | return ['name' => 'file']; 25 | } 26 | } -------------------------------------------------------------------------------- /src/locale/ru/Alnum.php: -------------------------------------------------------------------------------- 1 | [ 22 | self::STANDARD => '{{name}} должно содержать только буквы или цифры', 23 | self::EXTRA => '{{name}} должно содержать только буквы, цифры и "{{additionalChars}}"' 24 | ], 25 | self::MODE_NEGATIVE => [ 26 | self::STANDARD => '{{name}} не должно содержать буквы и цифры', 27 | self::EXTRA => '{{name}} не должно содержать буквы, цифры или "{{additionalChars}}"' 28 | ] 29 | ]; 30 | } 31 | 32 | public function defaultPlaceholders($additionalChars = '') 33 | { 34 | $this->defaultTemplate = $additionalChars ? self::EXTRA : self::STANDARD; 35 | return ['name' => 'значение', 'additionalChars' => $additionalChars]; 36 | } 37 | } -------------------------------------------------------------------------------- /src/locale/ru/Alpha.php: -------------------------------------------------------------------------------- 1 | [ 22 | self::STANDARD => '{{name}} должно содержать только буквы', 23 | self::EXTRA => '{{name}} должно содержать только буквы и "{{additionalChars}}"' 24 | ], 25 | self::MODE_NEGATIVE => [ 26 | self::STANDARD => '{{name}} не должно содержать буквы', 27 | self::EXTRA => '{{name}} не должно содержать буквы или "{{additionalChars}}"' 28 | ] 29 | ]; 30 | } 31 | 32 | public function defaultPlaceholders($additionalChars = '') 33 | { 34 | $this->defaultTemplate = $additionalChars ? self::EXTRA : self::STANDARD; 35 | return ['name' => 'значение', 'additionalChars' => $additionalChars]; 36 | } 37 | } -------------------------------------------------------------------------------- /src/locale/ru/Arr.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть массивом', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть массивом', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Between.php: -------------------------------------------------------------------------------- 1 | [ 25 | self::BOTH => '{{name}} должно быть между {{minValue}} и {{maxValue}}', 26 | self::LOWER => '{{name}} должно быть больше чем {{minValue}}', 27 | self::GREATER => '{{name}} должно быть меньше чем {{maxValue}}', 28 | ], 29 | self::MODE_NEGATIVE => [ 30 | self::BOTH => '{{name}} не должно быть между {{minValue}} и {{maxValue}}', 31 | self::LOWER => '{{name}} не должно быть больше {{minValue}}', 32 | self::GREATER => '{{name}} не должно быть меньше {{maxValue}}', 33 | ] 34 | ]; 35 | } 36 | 37 | public function defaultPlaceholders($minValue = null, $maxValue = null) 38 | { 39 | if (!isset($minValue)) { 40 | $this->defaultTemplate = static::GREATER; 41 | } elseif (!isset($maxValue)) { 42 | $this->defaultTemplate = static::LOWER; 43 | } else { 44 | $this->defaultTemplate = static::BOTH; 45 | } 46 | if ($minValue instanceof DateTime) { 47 | $minValue = $minValue->format(); 48 | } elseif ($minValue instanceof \DateTime) { 49 | $minValue = $minValue->format('Y-m-d H:i:s'); 50 | } 51 | 52 | if ($maxValue instanceof DateTime) { 53 | $maxValue = $maxValue->format(); 54 | } elseif ($maxValue instanceof \DateTime) { 55 | $maxValue = $maxValue->format('Y-m-d H:i:s'); 56 | } 57 | 58 | return [ 59 | 'name' => 'значение', 60 | 'minValue' => $minValue, 61 | 'maxValue' => $maxValue 62 | ]; 63 | } 64 | } -------------------------------------------------------------------------------- /src/locale/ru/BoolLocale.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть булевым', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть булевым', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/CSRF.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => 'CSRF-токен должен быть верным', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => 'CSRF-токен не должен быть верным', 24 | ] 25 | ]; 26 | } 27 | } -------------------------------------------------------------------------------- /src/locale/ru/Call.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть верным', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть верным', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Captcha.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => 'каптча должна быть верной', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => 'каптча не должна быть верной', 24 | ] 25 | ]; 26 | } 27 | } -------------------------------------------------------------------------------- /src/locale/ru/Closure.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть анонимной функцией', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть анонимной функцией', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Cntrl.php: -------------------------------------------------------------------------------- 1 | [ 22 | self::STANDARD => '{{name}} должно содержать только управляющие символы', 23 | self::EXTRA => '{{name}} должно содержать только управляющие символы и "{{additionalChars}}"' 24 | ], 25 | self::MODE_NEGATIVE => [ 26 | self::STANDARD => '{{name}} не должно содержать управляющих символов', 27 | self::EXTRA => '{{name}} не должно содержать управляющих символов или "{{additionalChars}}"' 28 | ] 29 | ]; 30 | } 31 | 32 | public function defaultPlaceholders($additionalChars = '') 33 | { 34 | $this->defaultTemplate = $additionalChars ? self::EXTRA : self::STANDARD; 35 | return ['name' => 'значение', 'additionalChars' => $additionalChars]; 36 | } 37 | } -------------------------------------------------------------------------------- /src/locale/ru/Confirm.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => 'значения должны совпадать', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => 'значения не должны совпадать', 24 | ] 25 | ]; 26 | } 27 | } -------------------------------------------------------------------------------- /src/locale/ru/Contains.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно содержать "{{containsValue}}"', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно содержать "{{containsValue}}"', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders($containsValue = null) 29 | { 30 | return [ 31 | 'name' => 'значение', 32 | 'containsValue' => $containsValue 33 | ]; 34 | } 35 | } -------------------------------------------------------------------------------- /src/locale/ru/Date.php: -------------------------------------------------------------------------------- 1 | [ 22 | self::STANDARD => '{{name}} должно быть датой', 23 | self::FORMAT => '{{name}} должно соответствовать формату: {{format}}' 24 | ], 25 | self::MODE_NEGATIVE => [ 26 | self::STANDARD => '{{name}} не должно быть датой', 27 | self::FORMAT => '{{name}} не должно соответствовать формату: {{format}}' 28 | ] 29 | ]; 30 | } 31 | 32 | public function defaultPlaceholders($format = null) 33 | { 34 | if (empty($format)) { 35 | return [ 36 | 'name' => 'значение', 37 | ]; 38 | } 39 | 40 | return [ 41 | 'name' => 'значение', 42 | 'format' => date($format, strtotime('2005-12-30 01:02:03')) 43 | ]; 44 | } 45 | } -------------------------------------------------------------------------------- /src/locale/ru/Digit.php: -------------------------------------------------------------------------------- 1 | [ 22 | self::STANDARD => '{{name}} должно содержать только цифры', 23 | self::EXTRA => '{{name}} должно содержать только цифры или "{{additionalChars}}"' 24 | ], 25 | self::MODE_NEGATIVE => [ 26 | self::STANDARD => '{{name}} не должно содержать только цифры', 27 | self::EXTRA => '{{name}} не должно содержать только цифры или "{{additionalChars}}"' 28 | ] 29 | ]; 30 | } 31 | 32 | public function defaultPlaceholders($additionalChars = '') 33 | { 34 | $this->defaultTemplate = $additionalChars ? self::EXTRA : self::STANDARD; 35 | return ['name' => 'значение', 'additionalChars' => $additionalChars]; 36 | } 37 | } -------------------------------------------------------------------------------- /src/locale/ru/Directory.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть директорией', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть директорией', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Domain.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должен быть верным', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должен быть верным', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'домен']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Email.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должен быть верным', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должен быть верным', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'email']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/EndsWith.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно заканчиваться на "{{endValue}}"', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно заканчиваться на "{{endValue}}"', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders($endValue = null) 29 | { 30 | return [ 31 | 'name' => 'значение', 32 | 'endValue' => $endValue 33 | ]; 34 | } 35 | } -------------------------------------------------------------------------------- /src/locale/ru/Equals.php: -------------------------------------------------------------------------------- 1 | [ 23 | self::EQUALS => '{{name}} должно быть равным {{compareTo}}', 24 | self::IDENTICAL => '{{name}} должно быть идентично {{compareTo}}', 25 | ], 26 | self::MODE_NEGATIVE => [ 27 | self::EQUALS => '{{name}} не должно быть равным {{compareTo}}', 28 | self::IDENTICAL => '{{name}} не должно быть идентично {{compareTo}}', 29 | ] 30 | ]; 31 | } 32 | 33 | public function defaultPlaceholders($compareTo = null, $compareIdentical = false) 34 | { 35 | $this->defaultTemplate = $compareIdentical ? self::IDENTICAL : self::EQUALS; 36 | return ['name' => 'значение']; 37 | } 38 | } -------------------------------------------------------------------------------- /src/locale/ru/Exists.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должен существовать', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должен существовать', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'файл']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/File.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть файлом', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть файлом', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/FileExtensions.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => 'Расширение {{name}} должно быть: {{extensions}}', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => 'Расширение {{name}} не должно быть: {{extensions}}', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders($extensions = null) 29 | { 30 | if (is_array($extensions)) { 31 | $extensions = implode(', ', $extensions); 32 | } 33 | return [ 34 | 'name' => 'файл', 35 | 'extensions' => $extensions 36 | ]; 37 | } 38 | } -------------------------------------------------------------------------------- /src/locale/ru/FileMimeTypes.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => 'Mime-type {{name}} должен быть: {{mimeTypes}}', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => 'Mime-type {{name}} не должен быть: {{mimeTypes}}', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders($mimeTypes = null) 29 | { 30 | return [ 31 | 'name' => 'файла', 32 | 'mimeTypes' => $mimeTypes 33 | ]; 34 | } 35 | } -------------------------------------------------------------------------------- /src/locale/ru/FileSizeBetween.php: -------------------------------------------------------------------------------- 1 | [ 25 | self::BOTH => 'Размер {{name}} должен быть в диапазоне между {{minValue}} и {{maxValue}} байт', 26 | self::LOWER => 'Размер {{name}} должен быть больше чем {{maxValue}} байт', 27 | self::GREATER => 'Размер {{name}} должен быть меньше чем {{maxValue}} байт', 28 | ], 29 | self::MODE_NEGATIVE => [ 30 | self::BOTH => 'Размер {{name}} не должен быть в диапазоне между {{minValue}} и {{maxValue}} байт', 31 | self::LOWER => 'Размер {{name}} не должен быть больше чем {{maxValue}} байт', 32 | self::GREATER => 'Размер {{name}} не должен быть меньше чем {{maxValue}} байт', 33 | ] 34 | ]; 35 | } 36 | 37 | public function defaultPlaceholders($minValue = null, $maxValue = null) 38 | { 39 | if (!isset($minValue)) { 40 | $this->defaultTemplate = static::GREATER; 41 | } elseif (!isset($maxValue)) { 42 | $this->defaultTemplate = static::LOWER; 43 | } else { 44 | $this->defaultTemplate = static::BOTH; 45 | } 46 | 47 | return [ 48 | 'name' => 'файл', 49 | 'minValue' => $minValue, 50 | 'maxValue' => $maxValue 51 | ]; 52 | } 53 | } -------------------------------------------------------------------------------- /src/locale/ru/FileSizeMax.php: -------------------------------------------------------------------------------- 1 | [ 22 | self::STANDARD => 'Размер {{name}} должен быть меньше {{maxValue}} байт', 23 | self::INCLUSIVE => 'Размер {{name}} должен быть меньше или равен {{maxValue}} байт', 24 | ], 25 | self::MODE_NEGATIVE => [ 26 | self::STANDARD => 'Размер {{name}} не должен быть меньше {{maxValue}} байт', 27 | self::INCLUSIVE => 'Размер {{name}} не дожен быть меньше или равен {{maxValue}} байт', 28 | ] 29 | ]; 30 | } 31 | 32 | public function defaultPlaceholders($maxValue = null, $inclusive = false) 33 | { 34 | $this->defaultTemplate = $inclusive ? static::INCLUSIVE : static::STANDARD; 35 | return [ 36 | 'name' => 'файл', 37 | 'maxValue' => $maxValue 38 | ]; 39 | } 40 | } -------------------------------------------------------------------------------- /src/locale/ru/FileSizeMin.php: -------------------------------------------------------------------------------- 1 | [ 22 | self::STANDARD => 'Размер {{name}} должен быть больше {{minValue}} байт', 23 | self::INCLUSIVE => 'Размер {{name}} должен быть больше или равен {{minValue}} байт', 24 | ], 25 | self::MODE_NEGATIVE => [ 26 | self::STANDARD => 'Размер {{name}} не должен быть больше {{minValue}} байт', 27 | self::INCLUSIVE => 'Размер {{name}} не дожен быть больше или равен {{minValue}} байт', 28 | ] 29 | ]; 30 | } 31 | 32 | public function defaultPlaceholders($minValue = null, $inclusive = false) 33 | { 34 | $this->defaultTemplate = $inclusive ? static::INCLUSIVE : static::STANDARD; 35 | return [ 36 | 'name' => 'файл', 37 | 'minValue' => $minValue 38 | ]; 39 | } 40 | } -------------------------------------------------------------------------------- /src/locale/ru/FloatLocale.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть вещественным числом', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть вещественным числом', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Graph.php: -------------------------------------------------------------------------------- 1 | [ 22 | self::STANDARD => '{{name}} должно содержать все символы, кроме пробелов', 23 | self::EXTRA => '{{name}} должно содержать все символы, кроме пробелов и "{{additionalChars}}"' 24 | ], 25 | self::MODE_NEGATIVE => [ 26 | self::STANDARD => '{{name}} должно содержать только пробелы', 27 | self::EXTRA => '{{name}} должно содержать только пробелы или "{{additionalChars}}"' 28 | ] 29 | ]; 30 | } 31 | 32 | public function defaultPlaceholders($additionalChars = '') 33 | { 34 | $this->defaultTemplate = $additionalChars ? self::EXTRA : self::STANDARD; 35 | return ['name' => 'значение', 'additionalChars' => $additionalChars]; 36 | } 37 | } -------------------------------------------------------------------------------- /src/locale/ru/In.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно совпадать с: {{haystack}}', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно совпадать с: {{haystack}}', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders($haystack = null) 29 | { 30 | return [ 31 | 'name' => 'значение', 32 | 'haystack' => is_array($haystack) ? implode(', ', $haystack) : $haystack 33 | ]; 34 | } 35 | } -------------------------------------------------------------------------------- /src/locale/ru/IntLocale.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть целым числом', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть целым числом', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Ip.php: -------------------------------------------------------------------------------- 1 | [ 23 | self::STANDARD => '{{name}} должно быть IP-адрессом', 24 | self::NETWORK_RANGE => '{{name}} должно быть IP-адрессом в диапазоне {{range}}', 25 | ], 26 | self::MODE_NEGATIVE => [ 27 | self::STANDARD => '{{name}} не должно быть IP-адрессом', 28 | self::NETWORK_RANGE => '{{name}} не должно быть IP-адрессом в диапазоне {{range}}', 29 | ] 30 | ]; 31 | } 32 | public function defaultPlaceholders(array $range = null) 33 | { 34 | $message = ''; 35 | if (!empty($range)) { 36 | $message = $range['min']; 37 | $message .= isset($range['max']) ? '-' . $range['max'] : '/' . long2ip((int)$range['mask']); 38 | } 39 | $this->defaultTemplate = !empty($message) ? self::NETWORK_RANGE : self::STANDARD; 40 | return [ 41 | 'name' => 'value', 42 | 'range' => $message 43 | ]; 44 | } 45 | } -------------------------------------------------------------------------------- /src/locale/ru/JSON.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть JSON-представлением', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть JSON-представлением', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Length.php: -------------------------------------------------------------------------------- 1 | [ 24 | self::BOTH => '{{name}} должно иметь длину в диапазоне от {{minValue}} до {{maxValue}}', 25 | self::LOWER => '{{name}} должно иметь длину больше {{minValue}}', 26 | self::GREATER => '{{name}} должно иметь длину меньше {{maxValue}}', 27 | ], 28 | self::MODE_NEGATIVE => [ 29 | self::BOTH => '{{name}} не должно иметь длину в диапазоне от {{minValue}} до {{maxValue}}', 30 | self::LOWER => '{{name}} не должно иметь длину больше {{minValue}}', 31 | self::GREATER => '{{name}} не должно иметь длину меньше {{maxValue}}', 32 | ] 33 | ]; 34 | } 35 | 36 | public function defaultPlaceholders($minValue = null, $maxValue = null) 37 | { 38 | if (!isset($minValue)) { 39 | $this->defaultTemplate = static::GREATER; 40 | } elseif (!isset($maxValue)) { 41 | $this->defaultTemplate = static::LOWER; 42 | } else { 43 | $this->defaultTemplate = static::BOTH; 44 | } 45 | return [ 46 | 'name' => 'значение', 47 | 'minValue' => $minValue, 48 | 'maxValue' => $maxValue 49 | ]; 50 | } 51 | } -------------------------------------------------------------------------------- /src/locale/ru/Lowercase.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть в нижнем регистре', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть в нижнем регистре', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Max.php: -------------------------------------------------------------------------------- 1 | [ 23 | self::STANDARD => '{{name}} должно быть меньше {{maxValue}}', 24 | self::INCLUSIVE => '{{name}} должно быть меньше или равно {{maxValue}}', 25 | ], 26 | self::MODE_NEGATIVE => [ 27 | self::STANDARD => '{{name}} не должно быть меньше {{maxValue}}', 28 | self::INCLUSIVE => '{{name}} не дожно быть меньше или равно {{maxValue}}', 29 | ] 30 | ]; 31 | } 32 | 33 | public function defaultPlaceholders($maxValue = null, $inclusive = false) 34 | { 35 | $this->defaultTemplate = $inclusive ? static::INCLUSIVE : static::STANDARD; 36 | if ($maxValue instanceof \DateTime) { 37 | $maxValue = $maxValue->format('Y-m-d H:i:s'); 38 | } elseif ($maxValue instanceof DateTime) { 39 | $maxValue = $maxValue->format(); 40 | } 41 | return [ 42 | 'name' => 'значение', 43 | 'maxValue' => $maxValue 44 | ]; 45 | } 46 | } -------------------------------------------------------------------------------- /src/locale/ru/Min.php: -------------------------------------------------------------------------------- 1 | [ 23 | self::STANDARD => '{{name}} должно быть больше {{minValue}}', 24 | self::INCLUSIVE => '{{name}} должно быть больше или равно {{minValue}}', 25 | ], 26 | self::MODE_NEGATIVE => [ 27 | self::STANDARD => '{{name}} не должно быть больше {{minValue}}', 28 | self::INCLUSIVE => '{{name}} не должно быть больше или равно {{minValue}}', 29 | ] 30 | ]; 31 | } 32 | 33 | public function defaultPlaceholders($minValue = null, $inclusive = false) 34 | { 35 | $this->defaultTemplate = $inclusive ? static::INCLUSIVE : static::STANDARD; 36 | if ($minValue instanceof \DateTime) { 37 | $minValue = $minValue->format('Y-m-d H:i:s'); 38 | } elseif ($minValue instanceof DateTime) { 39 | $minValue = $minValue->format(); 40 | } 41 | return [ 42 | 'name' => 'значение', 43 | 'minValue' => $minValue 44 | ]; 45 | } 46 | } -------------------------------------------------------------------------------- /src/locale/ru/Negative.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть отрицательным', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть отрицательным', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/NoWhitespace.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => 'в {{name}} не должно быть пробельных символов', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => 'в {{name}} должны быть пробельные символы', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значении']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/NullValue.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть NULL', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть NULL', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Numeric.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть числом', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть числом', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return [ 31 | 'name' => 'значение' 32 | ]; 33 | } 34 | } -------------------------------------------------------------------------------- /src/locale/ru/Object.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть объектом', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть объектом', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Odd.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть чётным числом', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть чётным числом', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Positive.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть положительным', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть положительным', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Readable.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должен быть доступен для чтения', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должен быть доступен для чтения', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'файл']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Regex.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} содержит неверные символы', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не содержит верные символы', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Required.php: -------------------------------------------------------------------------------- 1 | [ 14 | self::STANDARD => '{{name}} не должно быть пустым', 15 | ], 16 | self::MODE_NEGATIVE => [ 17 | self::STANDARD => '{{name}} должно быть пустым', 18 | ] 19 | ]; 20 | } 21 | 22 | public function defaultPlaceholders() 23 | { 24 | return [ 25 | 'name' => 'значение' 26 | ]; 27 | } 28 | } -------------------------------------------------------------------------------- /src/locale/ru/Space.php: -------------------------------------------------------------------------------- 1 | [ 22 | self::STANDARD => '{{name}} должно содержать только пробельные символы', 23 | self::EXTRA => '{{name}} должно содержать только пробельные символы и "{{additionalChars}}"' 24 | ], 25 | self::MODE_NEGATIVE => [ 26 | self::STANDARD => '{{name}} не должно содержать пробельные символы', 27 | self::EXTRA => '{{name}} не должно содержать пробельные символы и "{{additionalChars}}"' 28 | ] 29 | ]; 30 | } 31 | 32 | public function defaultPlaceholders($additionalChars = '') 33 | { 34 | $this->defaultTemplate = $additionalChars ? self::EXTRA : self::STANDARD; 35 | return ['name' => 'значение', 'additionalChars' => $additionalChars]; 36 | } 37 | } -------------------------------------------------------------------------------- /src/locale/ru/StartsWith.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно начинаться с "{{startValue}}"', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно начинаться с "{{startValue}}"', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders($startValue = null) 29 | { 30 | return [ 31 | 'name' => 'значение', 32 | 'startValue' => $startValue 33 | ]; 34 | } 35 | } -------------------------------------------------------------------------------- /src/locale/ru/StringLocale.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть строкой', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть строкой', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/SymbolicLink.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должен быть символической ссылкой', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должен быть символической ссылкой', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'файл']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Uploaded.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должен быть загружен', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должен быть загружен', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'файл']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Uppercase.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должно быть в верхнем регистре', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должно быть в верхнем регистре', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'значение']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/locale/ru/Writable.php: -------------------------------------------------------------------------------- 1 | [ 20 | self::STANDARD => '{{name}} должен быть доступен для записи', 21 | ], 22 | self::MODE_NEGATIVE => [ 23 | self::STANDARD => '{{name}} не должен быть доступен для записи', 24 | ] 25 | ]; 26 | } 27 | 28 | public function defaultPlaceholders() 29 | { 30 | return ['name' => 'файл']; 31 | } 32 | } -------------------------------------------------------------------------------- /src/rules/Alnum.php: -------------------------------------------------------------------------------- 1 | filterWhiteSpace((string)$input); 16 | return $input === '' || ctype_alnum($input); 17 | } 18 | } -------------------------------------------------------------------------------- /src/rules/Alpha.php: -------------------------------------------------------------------------------- 1 | filterWhiteSpace((string)$input); 16 | return $input === '' || ctype_alpha($input); 17 | } 18 | } -------------------------------------------------------------------------------- /src/rules/Arr.php: -------------------------------------------------------------------------------- 1 | $max) { 13 | throw new ValidateException(sprintf('%s cannot be less than %s for validation', $min, $max)); 14 | } 15 | parent::__construct($config); 16 | $this->params['minValue'] = $min; 17 | $this->params['maxValue'] = $max; 18 | $this->params['inclusive'] = $inclusive; 19 | } 20 | 21 | public function validate($input) 22 | { 23 | 24 | if (!is_null($this->params['minValue'])) { 25 | if (!(new Min($this->params['minValue'], $this->params['inclusive']))->validate($input)) { 26 | return false; 27 | } 28 | } 29 | if (!is_null($this->params['maxValue'])) { 30 | if (!(new Max($this->params['maxValue'], $this->params['inclusive']))->validate($input)) { 31 | return false; 32 | } 33 | } 34 | return true; 35 | } 36 | } -------------------------------------------------------------------------------- /src/rules/BoolRule.php: -------------------------------------------------------------------------------- 1 | csrf = Instance::ensure($this->csrf, '\rock\csrf\CSRF'); 16 | } 17 | 18 | /** 19 | * @inheritdoc 20 | */ 21 | public function validate($input) 22 | { 23 | return $this->csrf->check($input); 24 | } 25 | } -------------------------------------------------------------------------------- /src/rules/CType.php: -------------------------------------------------------------------------------- 1 | params['additionalChars'] = $additionalChars; 19 | } 20 | 21 | protected function filterWhiteSpace($input) 22 | { 23 | if (!empty($this->params['additionalChars'])) { 24 | $input = str_replace(str_split($this->params['additionalChars']), '', $input); 25 | } 26 | return preg_replace('/\s/', '', $input); 27 | } 28 | } -------------------------------------------------------------------------------- /src/rules/Call.php: -------------------------------------------------------------------------------- 1 | call = $call; 13 | if (!empty($args)) { 14 | $this->args = $args; 15 | } 16 | } 17 | 18 | /** 19 | * @inheritdoc 20 | */ 21 | public function validate($input) 22 | { 23 | 24 | $args = $this->args; 25 | array_unshift($args, $input); 26 | 27 | return (bool)call_user_func_array($this->call, $args); 28 | } 29 | } -------------------------------------------------------------------------------- /src/rules/Captcha.php: -------------------------------------------------------------------------------- 1 | params['additionalChars']), '', (string)$input); 16 | return $input === '' || ctype_cntrl($input); 17 | } 18 | } -------------------------------------------------------------------------------- /src/rules/Confirm.php: -------------------------------------------------------------------------------- 1 | params['containsValue'] = $containsValue; 12 | $this->params['identical'] = $identical; 13 | } 14 | 15 | /** 16 | * @inheritdoc 17 | */ 18 | public function validate($input) 19 | { 20 | if ($this->params['identical']) { 21 | return $this->validateIdentical($input); 22 | } 23 | return $this->validateEquals($input); 24 | } 25 | 26 | protected function validateEquals($input) 27 | { 28 | if (is_array($input)) { 29 | return in_array($this->params['containsValue'], $input); 30 | } 31 | return \rock\helpers\StringHelper::contains($input, $this->params['containsValue'], false); 32 | } 33 | 34 | protected function validateIdentical($input) 35 | { 36 | if (is_array($input)) { 37 | return in_array($this->params['containsValue'], $input, true); 38 | } 39 | return \rock\helpers\StringHelper::contains($input, $this->params['containsValue'], true); 40 | } 41 | } -------------------------------------------------------------------------------- /src/rules/Date.php: -------------------------------------------------------------------------------- 1 | params['format'] = $format; 13 | } 14 | 15 | /** 16 | * @inheritdoc 17 | */ 18 | public function validate($input) 19 | { 20 | if ($input instanceof DateTime) { 21 | return true; 22 | } elseif (!is_string($input)) { 23 | return false; 24 | } elseif (is_null($this->params['format'])) { 25 | return false !== strtotime($input); 26 | } 27 | $dateFromFormat = DateTime::createFromFormat($this->params['format'], $input); 28 | 29 | if (DateTime::getLastErrors()['warning_count'] > 0) { 30 | return false; 31 | } 32 | return $dateFromFormat 33 | && $input === date($this->params['format'], $dateFromFormat->getTimestamp()); 34 | } 35 | } -------------------------------------------------------------------------------- /src/rules/Digit.php: -------------------------------------------------------------------------------- 1 | filterWhiteSpace((string)$input); 16 | return $input === '' || ctype_digit($input); 17 | } 18 | } -------------------------------------------------------------------------------- /src/rules/Directory.php: -------------------------------------------------------------------------------- 1 | isDir(); 12 | } 13 | return is_string($input) && is_dir($input); 14 | } 15 | } -------------------------------------------------------------------------------- /src/rules/Domain.php: -------------------------------------------------------------------------------- 1 | encodeEmail($input)); 16 | } 17 | 18 | /** 19 | * Encode an internationalized domain name 20 | * 21 | * @param string $domain The domain name 22 | * @return string The encoded domain name 23 | */ 24 | protected function encode($domain) 25 | { 26 | $objPunycode = new Punycode(); 27 | return $objPunycode->encode($domain); 28 | } 29 | 30 | /** 31 | * Encode all e-mail addresses within a string 32 | * 33 | * @param string $email The string to encode 34 | * @return string The encoded string 35 | */ 36 | protected function encodeEmail($email) 37 | { 38 | if ($email == '') 39 | { 40 | return ''; 41 | } 42 | if (strpos($email, '@') === false) 43 | { 44 | return $email; // see #6241 45 | } 46 | $arrChunks = explode('@', $email); 47 | $strHost = array_pop($arrChunks); 48 | return implode('@', $arrChunks) . '@' . static::encode($strHost); 49 | } 50 | } -------------------------------------------------------------------------------- /src/rules/EndsWith.php: -------------------------------------------------------------------------------- 1 | params['endValue'] = $endValue; 11 | $this->params['identical'] = $identical; 12 | } 13 | 14 | /** 15 | * @inheritdoc 16 | */ 17 | public function validate($input) 18 | { 19 | if ($this->params['identical'] ) { 20 | return $this->validateIdentical($input); 21 | } 22 | return $this->validateEquals($input); 23 | } 24 | 25 | protected function validateEquals($input) 26 | { 27 | if (is_array($input)) { 28 | return end($input) == $this->params['endValue']; 29 | } 30 | return \rock\helpers\StringHelper::endsWith($input, $this->params['endValue'], false); 31 | } 32 | 33 | protected function validateIdentical($input) 34 | { 35 | if (is_array($input)) { 36 | return end($input) === $this->params['endValue']; 37 | } 38 | return \rock\helpers\StringHelper::endsWith($input, $this->params['endValue'], true); 39 | } 40 | } -------------------------------------------------------------------------------- /src/rules/Equals.php: -------------------------------------------------------------------------------- 1 | params['compareTo'] = $compareTo; 11 | $this->params['compareIdentical'] = $compareIdentical; 12 | } 13 | 14 | /** 15 | * @inheritdoc 16 | */ 17 | public function validate($input) 18 | { 19 | if ($this->params['compareIdentical']) { 20 | return $input === $this->params['compareTo']; 21 | } else { 22 | return $input == $this->params['compareTo']; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/rules/Exists.php: -------------------------------------------------------------------------------- 1 | getPathname(); 18 | } 19 | return is_string($input) && file_exists($input); 20 | } 21 | } -------------------------------------------------------------------------------- /src/rules/File.php: -------------------------------------------------------------------------------- 1 | isFile(); 18 | } 19 | return is_string($input) && is_file($input); 20 | } 21 | } -------------------------------------------------------------------------------- /src/rules/FileExtensions.php: -------------------------------------------------------------------------------- 1 | params['extensions'] = $this->toArray($extensions); 15 | $this->params['checkExtensionByMimeType'] = $checkExtensionByMimeType; 16 | } 17 | 18 | /** 19 | * @inheritdoc 20 | */ 21 | public function validate($input) 22 | { 23 | if ($input instanceof UploadedFile) { 24 | if ($input->error !== UPLOAD_ERR_OK) { 25 | $this->params['extensions'] = $this->toString($this->params['extensions']); 26 | return false; 27 | } 28 | $extension = mb_strtolower($input->extension, 'utf-8'); 29 | $input = $input->tempName; 30 | } elseif(is_string($input)) { 31 | if (!$extension = strtolower(pathinfo($input, PATHINFO_EXTENSION))) { 32 | $this->params['extensions'] = $this->toString($this->params['extensions']); 33 | return false; 34 | } 35 | //$extension = $extension['extension']; 36 | } else { 37 | throw new ValidateException(ValidateException::UNKNOWN_VAR, ['name'=> 'input']); 38 | } 39 | 40 | if ($this->params['checkExtensionByMimeType']) { 41 | $mimeType = \rock\helpers\FileHelper::getMimeType($input); 42 | if ($mimeType === null) { 43 | $this->params['extensions'] = $this->toString($this->params['extensions']); 44 | return false; 45 | } 46 | $extensionsByMimeType = \rock\helpers\FileHelper::getExtensionsByMimeType($mimeType); 47 | if (!in_array($extension, $extensionsByMimeType, true)) { 48 | $this->params['extensions'] = $this->toString($this->params['extensions']); 49 | return false; 50 | } 51 | } 52 | if (!in_array($extension, $this->toArray($this->params['extensions']), true)) { 53 | $this->params['extensions'] = $this->toString($this->params['extensions']); 54 | return false; 55 | } 56 | 57 | return true; 58 | } 59 | 60 | protected function toArray($value) 61 | { 62 | if (!is_array($value)) { 63 | return preg_split('/[\s,]+/', strtolower($value), -1, PREG_SPLIT_NO_EMPTY); 64 | } 65 | return $value; 66 | } 67 | 68 | 69 | protected function toString($value) 70 | { 71 | if (is_array($value)) { 72 | return implode(', ', $value); 73 | } 74 | return $value; 75 | } 76 | } -------------------------------------------------------------------------------- /src/rules/FileMimeTypes.php: -------------------------------------------------------------------------------- 1 | params['mimeTypes'] = $this->toArray($mimeTypes); 13 | } 14 | 15 | /** 16 | * @inheritdoc 17 | */ 18 | public function validate($input) 19 | { 20 | if ($input instanceof UploadedFile) { 21 | if ($input->error !== UPLOAD_ERR_OK) { 22 | $this->params['mimeTypes'] = $this->toString($this->params['mimeTypes']); 23 | return false; 24 | } 25 | $input = $input->tempName; 26 | } 27 | if (in_array(\rock\helpers\FileHelper::getMimeType($input), $this->toArray($this->params['mimeTypes']), true)) { 28 | return true; 29 | } 30 | if (is_array($this->params['mimeTypes'])) { 31 | $this->params['mimeTypes'] = $this->toString($this->params['mimeTypes']); 32 | } 33 | return false; 34 | } 35 | 36 | protected function toArray($value) 37 | { 38 | if (!is_array($value)) { 39 | return preg_split('/[\s,]+/', strtolower($value), -1, PREG_SPLIT_NO_EMPTY); 40 | } 41 | return $value; 42 | } 43 | 44 | protected function toString($value) 45 | { 46 | if (is_array($value)) { 47 | return implode(', ', $value); 48 | } 49 | return $value; 50 | } 51 | } -------------------------------------------------------------------------------- /src/rules/FileSizeBetween.php: -------------------------------------------------------------------------------- 1 | $max) { 14 | throw new ValidateException(sprintf('%s cannot be less than %s for validation', $min, $max)); 15 | } 16 | $this->params['minValue'] = \rock\helpers\FileHelper::sizeToBytes($min);; 17 | $this->params['maxValue'] = \rock\helpers\FileHelper::sizeToBytes($max); 18 | $this->params['inclusive'] = $inclusive; 19 | } 20 | 21 | public function validate($input) 22 | { 23 | 24 | if (!is_null($this->params['minValue'])) { 25 | if (!(new FileSizeMin($this->params['minValue'], $this->params['inclusive']))->validate($input)) { 26 | return false; 27 | } 28 | } 29 | if (!is_null($this->params['maxValue'])) { 30 | if (!(new FileSizeMax($this->params['maxValue'], $this->params['inclusive']))->validate($input)) { 31 | return false; 32 | } 33 | } 34 | return true; 35 | } 36 | } -------------------------------------------------------------------------------- /src/rules/FileSizeMax.php: -------------------------------------------------------------------------------- 1 | params['maxValue'] = class_exists('rock\file\UploadedFile') 14 | ? UploadedFile::getSizeLimit($maxValue) 15 | : FileHelper::sizeToBytes(ini_get('upload_max_filesize')); 16 | $this->params['inclusive'] = $inclusive; 17 | } 18 | 19 | /** 20 | * @inheritdoc 21 | */ 22 | public function validate($input) 23 | { 24 | $maxValue = $this->params['maxValue']; 25 | if ($input instanceof UploadedFile) { 26 | if ($input->error === UPLOAD_ERR_INI_SIZE || $input->error === UPLOAD_ERR_FORM_SIZE) { 27 | return false; 28 | } 29 | $input = $input->size; 30 | $maxValue = UploadedFile::getSizeLimit($maxValue); 31 | } elseif ($input instanceof \SplFileInfo) { 32 | $input = $input->getSize(); 33 | } 34 | if ($this->params['inclusive']) { 35 | return $input <= $maxValue; 36 | } else { 37 | return $input < $maxValue; 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/rules/FileSizeMin.php: -------------------------------------------------------------------------------- 1 | params['minValue'] = FileHelper::sizeToBytes($minValue); 14 | $this->params['inclusive'] = $inclusive; 15 | } 16 | 17 | /** 18 | * @inheritdoc 19 | */ 20 | public function validate($input) 21 | { 22 | $minValue = $this->params['minValue']; 23 | if ($input instanceof UploadedFile) { 24 | $input = $input->size; 25 | } elseif ($input instanceof \SplFileInfo) { 26 | $input = $input->getSize(); 27 | } 28 | if ($this->params['inclusive']) { 29 | return $input >= $minValue; 30 | } else { 31 | return $input > $minValue; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/rules/FloatRule.php: -------------------------------------------------------------------------------- 1 | params['additionalChars']), '', (string)$input); 16 | return $input === '' || ctype_graph($input); 17 | } 18 | } -------------------------------------------------------------------------------- /src/rules/In.php: -------------------------------------------------------------------------------- 1 | params['haystack'] = $haystack; 11 | $this->params['compareIdentical'] = $compareIdentical; 12 | } 13 | 14 | /** 15 | * @inheritdoc 16 | */ 17 | public function validate($input) 18 | { 19 | if (is_array($this->params['haystack'])) { 20 | return in_array($input, $this->params['haystack'], $this->params['compareIdentical']); 21 | } 22 | if (!is_string($this->params['haystack'])) { 23 | return false; 24 | } 25 | $enc = mb_detect_encoding($input); 26 | 27 | if ($this->params['compareIdentical']) { 28 | return mb_strpos($this->params['haystack'], $input, 0, $enc) !== false; 29 | } 30 | return mb_stripos($this->params['haystack'], $input, 0, $enc) !== false; 31 | } 32 | } -------------------------------------------------------------------------------- /src/rules/IntRule.php: -------------------------------------------------------------------------------- 1 | params = [ 14 | 'range' => $this->parseRange($range), 15 | 'options' => $options 16 | ]; 17 | } 18 | 19 | /** 20 | * @inheritdoc 21 | */ 22 | public function validate($input) 23 | { 24 | return $this->verifyAddress($input) && $this->verifyNetwork($input); 25 | } 26 | 27 | protected function parseRange($input) 28 | { 29 | if ($input === null || $input == '*' || $input == '*.*.*.*' 30 | || $input == '0.0.0.0-255.255.255.255') { 31 | return null; 32 | } 33 | if ($input == '*:*:*:*:*:*' || $input == '0:0:0:0:0:0-ffff:ffff:ffff:ffff:ffff:ffff') { 34 | return null; 35 | } 36 | $range = ['min' => null, 'max' => null, 'mask' => null]; 37 | 38 | if (strpos($input, '-') !== false) { 39 | list($range['min'], $range['max']) = explode('-', $input); 40 | } elseif (strpos($input, '*') !== false) { 41 | $this->parseRangeUsingWildcards($input, $range); 42 | } elseif (strpos($input, '/') !== false) { 43 | $this->parseRangeUsingCidr($input, $range); 44 | } else { 45 | throw new ValidateException('Invalid network range'); 46 | } 47 | 48 | if (!$this->verifyAddress($range['min'])) { 49 | throw new ValidateException('Invalid network range'); 50 | } 51 | 52 | if (isset($range['max']) && !$this->verifyAddress($range['max'])) { 53 | throw new ValidateException('Invalid network range.'); 54 | } 55 | return $range; 56 | } 57 | 58 | protected function fillAddress($input, $char = '*') 59 | { 60 | if (strpos($input, ':') !== false) { 61 | while (substr_count($input, ':') < 7) { 62 | $input .= ':' . $char; 63 | } 64 | return $input; 65 | } 66 | while (substr_count($input, '.') < 3) { 67 | $input .= '.' . $char; 68 | } 69 | return $input; 70 | } 71 | 72 | protected function parseRangeUsingWildcards($input, &$range) 73 | { 74 | $input = $this->fillAddress($input); 75 | 76 | if (strpos($input, ':') !== false) { 77 | $range['min'] = strtr($input, '*', '0000'); 78 | $range['max'] = str_replace('*', 'ffff', $input); 79 | return; 80 | } 81 | $range['min'] = strtr($input, '*', '0'); 82 | $range['max'] = str_replace('*', '255', $input); 83 | } 84 | 85 | protected function parseRangeUsingCidr($input, &$range) 86 | { 87 | $input = explode('/', $input); 88 | 89 | if (strpos($input[0], ':') !== false) { 90 | $range['min'] = $input[0]; 91 | if (strpos($input[1], ':') !== false) { 92 | $range['mask'] = strlen(str_replace('0', '', $this->IPv6toBit(inet_pton($input[1])))); 93 | return; 94 | } 95 | $range['mask'] = $input[1]; 96 | return; 97 | } 98 | $range['min'] = $this->fillAddress($input[0], '0'); 99 | if (strpos($input[1], '.') !== false && $this->verifyAddress($input[1])) { 100 | $range['mask'] = sprintf('%032b', ip2long($input[1])); 101 | 102 | return ; 103 | } 104 | 105 | if ($input[1] < 8 || $input[1] > 30) { 106 | throw new ValidateException('Invalid network mask.'); 107 | } 108 | 109 | $range['mask'] = sprintf('%032b', ip2long(long2ip(~(pow(2, (32 - $input[1])) - 1)))); 110 | } 111 | 112 | protected function verifyAddress($address) 113 | { 114 | return (boolean) filter_var($address, FILTER_VALIDATE_IP, isset($this->params['options']) ? ['flags' => $this->params['options']] : null); 115 | } 116 | 117 | protected function verifyNetwork($input) 118 | { 119 | if ($this->params['range'] === null) { 120 | return true; 121 | } 122 | 123 | if (isset($this->params['range']['mask'])) { 124 | return $this->belongsToSubnet($input); 125 | } 126 | 127 | $min = $this->ip2long($this->params['range']['min']); 128 | $max = $this->ip2long($this->params['range']['max']); 129 | $input = $this->ip2long($input); 130 | return $input >= $min && $input <= $max; 131 | } 132 | 133 | protected function belongsToSubnet($input) 134 | { 135 | $range = $this->params['range']; 136 | if ($this->isIPv6($input)) { 137 | $input = $this->IPv6toBit(inet_pton($input)); 138 | $range['min'] = $this->IPv6toBit(inet_pton($range['min'])); 139 | 140 | return substr($input, 0, $range['mask']) === substr($range['min'], 0, $range['mask']); 141 | } 142 | 143 | $min = sprintf('%032b', ip2long($range['min'])); 144 | $input = sprintf('%032b', ip2long($input)); 145 | 146 | return ($input & $range['mask']) === ($min & $range['mask']); 147 | } 148 | 149 | protected function ip2long($ip) 150 | { 151 | $long = -1; 152 | if ($this->isIPv6($ip)) { 153 | if (!function_exists('bcadd')) { 154 | throw new \RuntimeException('BCMATH extension not installed.'); 155 | } 156 | $ip_n = inet_pton($ip); 157 | $bin = ''; 158 | for ($bit = strlen($ip_n) - 1; $bit >= 0; $bit--) { 159 | $bin = sprintf('%08b', ord($ip_n[$bit])) . $bin; 160 | } 161 | $dec = '0'; 162 | for ($i = 0; $i < strlen($bin); $i++) { 163 | $dec = bcmul($dec, '2', 0); 164 | $dec = bcadd($dec, $bin[$i], 0); 165 | } 166 | $long = $dec; 167 | } elseif ($this->isIPv4($ip)) { 168 | $long = ip2long($ip); 169 | } 170 | return $long; 171 | } 172 | 173 | /** 174 | * Gets IP string representation from IP long. 175 | * 176 | * @param string $dec IPv4 or IPv6 long 177 | * @param bool $ipv6 178 | * @return string If IP is valid returns IP string representation, otherwise ''. 179 | */ 180 | protected function long2ip($dec, $ipv6 = false) 181 | { 182 | if ($ipv6) { 183 | if (!function_exists('bcadd')) { 184 | throw new \RuntimeException('BCMATH extension not installed.'); 185 | } 186 | $bin = ''; 187 | do { 188 | $bin = bcmod($dec, '2') . $bin; 189 | $dec = bcdiv($dec, '2', 0); 190 | } while (bccomp($dec, '0')); 191 | $bin = str_pad($bin, 128, '0', STR_PAD_LEFT); 192 | $ip = []; 193 | for ($bit = 0; $bit <= 7; $bit++) { 194 | $bin_part = substr($bin, $bit * 16, 16); 195 | $ip[] = dechex(bindec($bin_part)); 196 | } 197 | $ip = implode(':', $ip); 198 | $ipstr = inet_ntop(inet_pton($ip)); 199 | } else { 200 | $ipstr = long2ip($dec); 201 | } 202 | return $ipstr; 203 | } 204 | 205 | /** 206 | * @link http://stackoverflow.com/a/7951507 207 | * @param string $ip 208 | * @return string 209 | */ 210 | protected function IPv6toBit($ip) 211 | { 212 | $result = ''; 213 | $ip = str_split(unpack('A16', $ip)[1]); 214 | foreach ($ip as $char) { 215 | $result .= str_pad(decbin(ord($char)), 8, '0', STR_PAD_LEFT); 216 | } 217 | return $result; 218 | } 219 | 220 | protected function isIPv6($ip) 221 | { 222 | return (bool)filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); 223 | } 224 | 225 | protected function isIPv4($ip) 226 | { 227 | return (bool)filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); 228 | } 229 | } -------------------------------------------------------------------------------- /src/rules/JSON.php: -------------------------------------------------------------------------------- 1 | $max) { 23 | throw new ValidateException(sprintf('%s cannot be less than %s for validation', $min, $max)); 24 | } 25 | $this->params['minValue'] = $min; 26 | $this->params['maxValue'] = $max; 27 | $this->params['inclusive'] = $inclusive; 28 | } 29 | 30 | /** 31 | * @inheritdoc 32 | */ 33 | public function validate($input) 34 | { 35 | if (is_int($input)) { 36 | $input = (string)$input; 37 | } 38 | $length = $this->extractLength($input); 39 | return $this->validateMin($length) && $this->validateMax($length); 40 | } 41 | 42 | protected function extractLength($input) 43 | { 44 | if (is_string($input)) { 45 | return mb_strlen($input, mb_detect_encoding($input)); 46 | } elseif (is_array($input) || $input instanceof Countable) { 47 | return count($input); 48 | } elseif (is_object($input)) { 49 | return count(get_object_vars($input)); 50 | } else { 51 | return false; 52 | } 53 | } 54 | 55 | protected function validateMin($length) 56 | { 57 | if (is_null($this->params['minValue'])) { 58 | return true; 59 | } 60 | if ($this->params['inclusive']) { 61 | return $length >= $this->params['minValue']; 62 | } 63 | return $length > $this->params['minValue']; 64 | } 65 | 66 | protected function validateMax($length) 67 | { 68 | if (is_null($this->params['maxValue'])) { 69 | return true; 70 | } 71 | if ($this->params['inclusive']) { 72 | return $length <= $this->params['maxValue']; 73 | } 74 | return $length < $this->params['maxValue']; 75 | } 76 | } -------------------------------------------------------------------------------- /src/rules/Lowercase.php: -------------------------------------------------------------------------------- 1 | params['maxValue'] = $max; 12 | $this->params['inclusive'] = $inclusive; 13 | } 14 | 15 | public function validate($input) 16 | { 17 | $maxValue = $this->params['maxValue']; 18 | if ($maxValue instanceof \DateTime && !$input instanceof \DateTime){ 19 | try { 20 | $input = new \DateTime($input); 21 | } catch (\Exception $e){ 22 | return false; 23 | } 24 | } 25 | if ($this->params['inclusive']) { 26 | return $input <= $maxValue; 27 | } else { 28 | return $input < $maxValue; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/rules/Min.php: -------------------------------------------------------------------------------- 1 | params['minValue'] = $min; 12 | $this->params['inclusive'] = $inclusive; 13 | } 14 | 15 | public function validate($input) 16 | { 17 | $minValue = $this->params['minValue']; 18 | if ($minValue instanceof \DateTime && !$input instanceof \DateTime){ 19 | try { 20 | $input = new \DateTime($input); 21 | } catch (\Exception $e){ 22 | return false; 23 | } 24 | } 25 | 26 | if ($this->params['inclusive']) { 27 | return $input >= $minValue; 28 | } else { 29 | return $input > $minValue; 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/rules/Negative.php: -------------------------------------------------------------------------------- 1 | 0; 14 | } 15 | } -------------------------------------------------------------------------------- /src/rules/Readable.php: -------------------------------------------------------------------------------- 1 | isReadable(); 18 | } 19 | return (is_string($input) && is_readable($input)); 20 | } 21 | } -------------------------------------------------------------------------------- /src/rules/Regex.php: -------------------------------------------------------------------------------- 1 | params['regex'] = $regex; 12 | } 13 | 14 | /** 15 | * @inheritdoc 16 | */ 17 | public function validate($input) 18 | { 19 | return (bool)preg_match($this->params['regex'], $input); 20 | } 21 | } -------------------------------------------------------------------------------- /src/rules/Required.php: -------------------------------------------------------------------------------- 1 | params['strict'] = $strict; 14 | } 15 | 16 | /** 17 | * @inheritdoc 18 | */ 19 | public function validate($input) 20 | { 21 | if (is_string($input)) { 22 | $input = trim($input); 23 | } 24 | 25 | if ($this->params['strict']) { 26 | return !empty($input); 27 | } 28 | 29 | return $input !== '' && $input !== null; 30 | } 31 | } -------------------------------------------------------------------------------- /src/rules/Rule.php: -------------------------------------------------------------------------------- 1 | params['additionalChars']), '', (string)$input); 16 | return $input === '' || ctype_space($input); 17 | } 18 | } -------------------------------------------------------------------------------- /src/rules/StartsWith.php: -------------------------------------------------------------------------------- 1 | params['startValue'] = $startValue; 11 | $this->params['identical'] = $identical; 12 | } 13 | 14 | /** 15 | * @inheritdoc 16 | */ 17 | public function validate($input) 18 | { 19 | if ($this->params['identical']) { 20 | return $this->validateIdentical($input); 21 | } 22 | return $this->validateEquals($input); 23 | } 24 | 25 | protected function validateEquals($input) 26 | { 27 | if (is_array($input)) { 28 | return reset($input) == $this->params['startValue']; 29 | } 30 | return \rock\helpers\StringHelper::startsWith($input, $this->params['startValue'], false); 31 | } 32 | 33 | protected function validateIdentical($input) 34 | { 35 | if (is_array($input)) { 36 | return reset($input) === $this->params['startValue']; 37 | } 38 | return \rock\helpers\StringHelper::startsWith($input, $this->params['startValue'], true); 39 | } 40 | } -------------------------------------------------------------------------------- /src/rules/StringRule.php: -------------------------------------------------------------------------------- 1 | isLink(); 17 | } 18 | 19 | return (is_string($input) && is_link($input)); 20 | } 21 | } -------------------------------------------------------------------------------- /src/rules/Uploaded.php: -------------------------------------------------------------------------------- 1 | error === UPLOAD_ERR_OK) { 25 | return true; 26 | } 27 | if ($input->error === UPLOAD_ERR_NO_FILE) { 28 | return false; 29 | } 30 | 31 | switch ($input->error) { 32 | /* case UPLOAD_ERR_INI_SIZE: 33 | case UPLOAD_ERR_FORM_SIZE: 34 | //$this->addRule(new FileSizeMax(UploadedFile::getSizeLimit())); 35 | return false;*/ 36 | case UPLOAD_ERR_PARTIAL: 37 | $this->log('File was only partially uploaded: '. $input->name); 38 | return false; 39 | case UPLOAD_ERR_NO_TMP_DIR: 40 | $this->log('Missing the temporary folder to store the uploaded file: '. $input->name); 41 | return false; 42 | case UPLOAD_ERR_CANT_WRITE: 43 | $this->log('Failed to write the uploaded file to disk: '. $input->name); 44 | return false; 45 | case UPLOAD_ERR_EXTENSION: 46 | $this->log('File upload was stopped by some PHP extension: '. $input->name); 47 | return false; 48 | default: 49 | break; 50 | } 51 | return true; 52 | } 53 | 54 | if ($input instanceof \SplFileInfo) { 55 | $input = $input->getPathname(); 56 | } 57 | 58 | return is_string($input) && is_uploaded_file($input); 59 | } 60 | 61 | protected function log($message) 62 | { 63 | if (!class_exists('\rock\log\Log')) { 64 | return; 65 | } 66 | $message = BaseException::convertExceptionToString(new ValidateException($message)); 67 | Log::warn($message); 68 | } 69 | } -------------------------------------------------------------------------------- /src/rules/Uppercase.php: -------------------------------------------------------------------------------- 1 | isWritable(); 18 | } 19 | 20 | return (is_string($input) && is_writable($input)); 21 | } 22 | } --------------------------------------------------------------------------------