├── .gitignore ├── .travis.yml ├── README.md ├── changelog.md ├── codeception.dist.yml ├── composer.json ├── src ├── AbstractRule.php ├── Field.php ├── FieldInterface.php ├── InvalidFieldException.php ├── InvalidRuleException.php ├── Provider │ └── FuelServiceProvider.php ├── Result.php ├── ResultInterface.php ├── Rule │ ├── Date.php │ ├── Email.php │ ├── Enum.php │ ├── EnumMulti.php │ ├── ExactLength.php │ ├── Ip.php │ ├── Mac.php │ ├── MatchField.php │ ├── MaxLength.php │ ├── MinLength.php │ ├── Number.php │ ├── NumericBetween.php │ ├── NumericMax.php │ ├── NumericMin.php │ ├── Regex.php │ ├── Required.php │ ├── RequiredIf.php │ ├── RequiredWith.php │ ├── Type.php │ ├── Url.php │ └── Validator.php ├── RuleInterface.php ├── RuleProvider │ └── FromArray.php ├── ValidatableInterface.php ├── ValidationAwareInterface.php └── Validator.php └── tests ├── _bootstrap.php ├── _data └── dump.sql ├── _helpers ├── AbstractRequiredTest.php ├── AbstractRuleTest.php ├── CodeGuy.php ├── CodeHelper.php └── _generated │ └── CodeGuyActions.php ├── _log └── .gitkeep ├── stubs ├── ClassWithToString.php └── DummyAbstractRule.php ├── unit.suite.yml └── unit ├── AbstractRuleTest.php ├── CodeGuy.php ├── FieldTest.php ├── ResultTest.php ├── Rule ├── DateTest.php ├── EmailTest.php ├── EnumMultiTest.php ├── EnumTest.php ├── ExactLengthTest.php ├── IpTest.php ├── MacTest.php ├── MatchFieldTest.php ├── MaxLengthTest.php ├── MinLengthTest.php ├── NumberTest.php ├── NumericBetweenTest.php ├── NumericMaxTest.php ├── NumericMinTest.php ├── RegexTest.php ├── RequiredIfTest.php ├── RequiredTest.php ├── RequiredWithTest.php ├── TypeTest.php ├── UrlTest.php └── ValidatorTest.php ├── RuleProvider └── FromArrayTest.php ├── ValidatorTest.php └── _bootstrap.php /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /vendor 3 | coverage 4 | cache 5 | composer.lock 6 | *.bak 7 | Thumbs.db 8 | desktop.ini 9 | .buildpath 10 | .project 11 | .settings 12 | nbproject/ 13 | .idea 14 | *.tmproj 15 | *.sublime-project 16 | *.sublime-workspace 17 | index.php 18 | composer.phar 19 | /tests/_log/* 20 | /codeception.yml 21 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | sudo: false 4 | 5 | php: 6 | - 5.5 7 | - 5.6 8 | - 7.0 9 | - hhvm 10 | 11 | before_script: 12 | - bash -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then wget https://scrutinizer-ci.com/ocular.phar; fi;' 13 | - composer install 14 | 15 | script: 16 | - bash -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then vendor/bin/codecept run unit --coverage-xml; fi;' 17 | - bash -c 'if [ "$TRAVIS_PHP_VERSION" == "hhvm" ]; then vendor/bin/codecept run unit; fi;' 18 | 19 | after_script: 20 | - bash -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then php ocular.phar code-coverage:upload --format=php-clover tests/_log/coverage.xml; fi;' 21 | 22 | notifications: 23 | irc: "irc.freenode.org#fuelphp-status" 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FuelPHP Validation library. 2 | 3 | [![Build Status](https://travis-ci.org/fuelphp/validation.png?branch=master)](https://travis-ci.org/fuelphp/validation) 4 | [![Code Coverage](https://scrutinizer-ci.com/g/fuelphp/validation/badges/coverage.png?s=5e3f0a0ed61d5d772c9ceb7da8d29046edaa0970)](https://scrutinizer-ci.com/g/fuelphp/validation/) 5 | [![Code Quality](https://scrutinizer-ci.com/g/fuelphp/validation/badges/quality-score.png?s=b16b5378dd8e42e052a94772477cc5a0279ca944)](https://scrutinizer-ci.com/g/fuelphp/validation/) 6 | [![HHVM Status](http://hhvm.h4cc.de/badge/fuelphp/validation.svg)](http://hhvm.h4cc.de/package/fuelphp/validation) 7 | 8 | A flexible library to validate different kinds of data. 9 | 10 | ## Simple usage 11 | 12 | ```php 13 | addField('name', 'User Name') 22 | ->required() 23 | ->addField('email', 'Email Address') 24 | ->required() 25 | ->email() 26 | ->addField('age', 'Current Age') 27 | ->number(); 28 | 29 | // Create some dummy data to validate 30 | $data = array( 31 | 'name' => 'John', 32 | 'email' => 'john@doe.example', 33 | 'age' => 32, 34 | ); 35 | 36 | // Perform the validation 37 | $result = $v->run($data); 38 | 39 | var_dump($result->isValid()); // true 40 | var_dump($result->getValidated()); // List of all the fields that passed validation 41 | 42 | ``` 43 | 44 | ### Current validation rules 45 | 46 | All core rule classes can be found under the `Fuel\Validation\Rule` namespace. 47 | 48 | - email - Checks for a valid email format 49 | - ip - Checks for a valid IP address 50 | - matchField - Compares the given field against another field being validated 51 | - minLength - Checks if the value is >= a given value 52 | - maxLength - Checks if the value is <= a given value 53 | - number - Checks if the value is numeric or not 54 | - numericBetween - Checks if a numeric value falls between an upper and lower band 55 | - numericMax - Checks if the value is less than or equal to a given value 56 | - numericMin - Checks if the value is greater than or equal to a given value 57 | - regex - Checks if the value matches against a given regular expression 58 | - required - Checks if the value exists in the data being validated 59 | - url - Checks if the given value is a valid url or not 60 | - date - Checks if the given value matches a given date format 61 | - type - Checks if a value is a typeof or instanceof parameter(s) 62 | - enum - Checks if a value is in an allowed list of values 63 | - enumMulti - Checks if all values in an array are in an allowed list of values 64 | - validator - For validating nested child models 65 | 66 | ## Error messages 67 | 68 | Messages can be retrieved from the result object after validatoin has been performed 69 | 70 | ```php 71 | addField('name', 'User Name') 80 | ->required() 81 | ->addField('email', 'Email Address') 82 | ->required() 83 | ->email() 84 | ->addField('age', 'Current Age') 85 | ->number(); 86 | 87 | // Create some dummy data to validate 88 | $data = array( 89 | 'email' => 'john', 90 | 'age' => 'not a number', 91 | ); 92 | 93 | // Perform the validation 94 | $result = $v->run($data); 95 | 96 | var_dump($result->isValid()); // false 97 | var_dump($result->getValidated()); // array() 98 | 99 | var_dump($result->getErrors()); // returns an array of all the error messages encountered 100 | var_dump($result->getError('name')); // Returns the error message for the 'name' field 101 | ``` 102 | 103 | ### Custom messages 104 | Messages can be set in two ways, directly on a rule instance or as part of the method chain. 105 | 106 | ```php 107 | 108 | use Fuel\Validation\Validator; 109 | 110 | $v = new Validator; 111 | 112 | $v->addField('name', 'User Name') 113 | ->required() 114 | ->setMessage('{label} is required, please enter a value'); 115 | 116 | ``` 117 | Now when the `required()` rule fails the custom message will be used. 118 | 119 | There are several tokens that can be used as substitutions for various values. As in the example `{label}` will be replaced 120 | with the field's label and `{name}` will be replaced with the field's name. (`name` in the example above). Rules can also 121 | provide other values, for instance `NumericBetween` will allow you to use `{upperBound}` and `{lowerBound}`. Please refer to each rule 122 | on the custom tokens provided. 123 | 124 | If a token in a string is not found then it will simply be ignored and not replaced. 125 | 126 | ### Default messages 127 | 128 | It is possible to change the default message for a given rule by calling `setGlobalMessage()` on the `Validator` object. 129 | After this method is called any rules created through the `Validatator` via either magic methods or `createRuleInstance()` will 130 | have the specified message set by default. 131 | 132 | ```php 133 | use Fuel\Validation\Validator; 134 | 135 | // Create a new validator instance to play with 136 | $v = new Validator; 137 | 138 | $v->setGlobalMessage('required', 'Sorry, my chum, but {label} is a required field and you did not enter anything'); 139 | 140 | ``` 141 | 142 | ## Manually adding rules and rule overriding 143 | As well as using the default core rules it is possible to dynamically add your own rules or override existing rules. 144 | 145 | This is done by calling the `addCustomRule()` function on a `Validator` like so: `$v->addCustomRule('myCustomRule', 'My\App\Rules\CustomRule')`. 146 | If the class cannot be loaded for any reason an `InvalidRuleException` will be thrown when the rule gets used. 147 | 148 | The `myCustomRule` rule is now available for use with the `Validator` instance and can be called via the magic method syntax as well as the `createRuleInstance()` function in `Validator`. 149 | 150 | ```php 151 | addCustomRule('myCustomRule', 'My\App\Rules\CustomRule'); 159 | 160 | // Example of adding the new rule via magic method syntax 161 | $v->addField('foobar') 162 | ->myCustomRule(); 163 | 164 | $instance = $v->getRuleInstance('myCustomRule'); 165 | var_dump($instance); // instance of My\App\Rules\CustomRule 166 | ``` 167 | 168 | ### Overriding existing rules 169 | It is possible to replace existing rules simply by calling `addCustomRule()` as in the previous example and passing the name of an existing rule 170 | 171 | ```php 172 | addCustomRule('required', 'My\App\Rules\CustomRule'); 180 | 181 | // Example of adding the new rule via magic method syntax 182 | $v->addField('foobar') 183 | ->required(); 184 | 185 | $instance = $v->getRuleInstance('required'); 186 | var_dump($instance); // instance of My\App\Rules\CustomRule 187 | ``` 188 | 189 | ### Nested validators 190 | 191 | It is possible to use a validator itself as a rule for an entry in the data being validated. This allows child models to be validated along with the parent data. 192 | This can be done using the `Fuel\Validation\Rule\Validator` rule and can be nested as deeply as you desire. 193 | 194 | ``` 195 | addField('test') 200 | ->maxLength(5); 201 | 202 | $parentValidator = new Validator(); 203 | $parentValidator 204 | ->addField('child') 205 | ->validator($childValidator); 206 | 207 | $parentValidator 208 | ->addField('foobar') 209 | ->required(); 210 | 211 | $result = $parentValidator->run([ 212 | 'foobar' => 'test', 213 | // 'child' contains our child model data and is validted by $childValidator 214 | 'child' => ['test' => '1234'] 215 | ]); 216 | ``` 217 | 218 | ## Automatic `Validator` population 219 | Through the use of `RuleProvider` classes it is possible to automatically create rule sets for a given `Validator` this can be used to automatically create validation for any kind of object from forms to ORM models. 220 | At the moment only one provider exists to serve as an example that creates rule sets from a config array. In the future Fieldset and ORM will provide their own providers. 221 | 222 | The provider is used by creating a new `Validator`, setting up your config array and then populating the `Validator`. 223 | 224 | ```php 225 | array( 233 | 'required', // Rules with no parameters can be specified like this 234 | ), 235 | 'email' => array( 236 | 'required', 237 | 'email', // Make sure this is a valid email address 238 | ), 239 | 'age' => array( 240 | 'number', 241 | 'numericMin' => 18, // Make sure the value is 18 or greater 242 | ), 243 | 244 | // The exact parameters for each rule are documented with the rule itself and can differ between rules. 245 | ); 246 | 247 | $v = new Validator; 248 | 249 | $generator = new FromArray; 250 | $generator->setData($config)->populateValidator($v); 251 | 252 | // $v is now populated with the fields and rules specified in the config array. 253 | ``` 254 | 255 | The `RuleProvider`s will also be aware of custom rules that are added to the `Validator` that they are passed. 256 | 257 | ```php 258 | array( 265 | 'myCustomRule', 266 | ), 267 | ); 268 | 269 | $v = new Validator; 270 | 271 | $v->addRule('myCustomRule', 'My\App\Rules\CustomRule'); 272 | 273 | $generator = new FromArray; 274 | $generator->setData($config)->populateValidator($v); 275 | 276 | ``` 277 | 278 | You can also add a config with your custom structure. 279 | 280 | ```php 281 | array( 289 | 'label' => 'Name' 290 | 'validation' => array( 291 | 'required', 292 | ), 293 | ), 294 | 'email' => array( 295 | 'label' => 'Email address', 296 | 'validation' => array( 297 | 'required', 298 | 'email', 299 | ), 300 | ), 301 | 'age' => array( 302 | 'label' => 'Age', 303 | 'validation' => array( 304 | 'number', 305 | 'numericMin' => 18, 306 | ), 307 | ), 308 | ); 309 | 310 | $v = new Validator; 311 | 312 | // First parameter: label key, default: disabled 313 | // Second parameter: rules key, default: rules 314 | $generator = new FromArray(true, 'validation'); // same as new FromArray('label', 'validation'); 315 | $generator->setData($config)->populateValidator($v); 316 | 317 | // $v is now populated with the fields and rules specified in the config array. 318 | ``` 319 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this package will be documented in this file. 3 | 4 | ## [Unreleased][unreleased] 5 | ### Added 6 | - Enum rule 7 | - EnumMulti rule [#34](https://github.com/fuelphp/validation/issues/34) 8 | 9 | ### Removed 10 | - Value rule in favour of better named `Enum` 11 | 12 | ## [2.0.0] - 2015-01-01 13 | ### Added 14 | - Inital release 15 | 16 | -------------------------------------------------------------------------------- /codeception.dist.yml: -------------------------------------------------------------------------------- 1 | paths: 2 | tests: tests 3 | log: tests/_log 4 | data: tests/_data 5 | helpers: tests/_helpers 6 | settings: 7 | bootstrap: _bootstrap.php 8 | suite_class: \PHPUnit_Framework_TestSuite 9 | colors: true 10 | memory_limit: 1024M 11 | log: true 12 | coverage: 13 | enabled: true 14 | include: 15 | - src/* 16 | exclude: 17 | - src/Provider/* 18 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fuelphp/validation", 3 | "type": "library", 4 | "description": ".", 5 | "keywords": ["Validation"], 6 | "homepage": "https://github.com/fuelphp/validation", 7 | "license": "MIT", 8 | "authors": [ 9 | { 10 | "name": "FuelPHP Development Team", 11 | "email": "team@fuelphp.com" 12 | } 13 | ], 14 | "require": { 15 | "php": ">=5.3.3" 16 | }, 17 | "require-dev": { 18 | "codeception/codeception": "~2.0", 19 | "codeception/mockery-module": "dev-master" 20 | }, 21 | "autoload": { 22 | "psr-4": { "Fuel\\Validation\\": "src/" } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/AbstractRule.php: -------------------------------------------------------------------------------- 1 | setParameter($params); 55 | 56 | if ($message) 57 | { 58 | $this->setMessage($message); 59 | } 60 | } 61 | 62 | /** 63 | * Gets the failure message for this rule 64 | * 65 | * @return string 66 | * 67 | * @since 2.0 68 | */ 69 | public function getMessage() 70 | { 71 | return $this->message; 72 | } 73 | 74 | /** 75 | * Should return a list of tokens that can be inserted into this rule's error message. 76 | * For example this might be an upper bound for MaxValue or the regex passed to the Regex rule. 77 | * Values should always have a string key so they can be easily identified. 78 | * 79 | * @return string[] 80 | */ 81 | public function getMessageParameters() 82 | { 83 | return array(); 84 | } 85 | 86 | /** 87 | * Sets the failure message for this rule 88 | * 89 | * @param string $message 90 | * 91 | * @return $this 92 | * 93 | * @since 2.0 94 | */ 95 | public function setMessage($message) 96 | { 97 | $this->message = $message; 98 | 99 | return $this; 100 | } 101 | 102 | /** 103 | * Sets the parameter for this validation rule. 104 | * See each Rule's documentation for what this should be. 105 | * 106 | * @param mixed $params 107 | * 108 | * @return $this 109 | * 110 | * @since 2.0 111 | */ 112 | public function setParameter($params) 113 | { 114 | $this->params = $params; 115 | 116 | return $this; 117 | } 118 | 119 | /** 120 | * Returns the value of the set parameter. 121 | * See each Rule's documentation for what the parameter does. 122 | * 123 | * @return mixed 124 | * 125 | * @since 2.0 126 | */ 127 | public function getParameter() 128 | { 129 | return $this->params; 130 | } 131 | 132 | public function canAlwaysRun() 133 | { 134 | return $this->alwaysRun; 135 | } 136 | 137 | } 138 | -------------------------------------------------------------------------------- /src/Field.php: -------------------------------------------------------------------------------- 1 | setName($name); 46 | $this->setLabel($friendlyName); 47 | } 48 | 49 | /** 50 | * Sets the label of this field 51 | * 52 | * @param string $friendlyName 53 | * 54 | * @return $this 55 | * 56 | * @since 2.0 57 | */ 58 | public function setLabel($friendlyName) 59 | { 60 | $this->label = $friendlyName; 61 | 62 | return $this; 63 | } 64 | 65 | /** 66 | * Gets the label of this field 67 | * 68 | * @return string 69 | * 70 | * @since 2.0 71 | */ 72 | public function getLabel() 73 | { 74 | if ($this->label === null) 75 | { 76 | return $this->getName(); 77 | } 78 | 79 | return $this->label; 80 | } 81 | 82 | /** 83 | * Sets the machine name of this field 84 | * 85 | * @param string $name 86 | * 87 | * @return $this 88 | * 89 | * @since 2.0 90 | */ 91 | public function setName($name) 92 | { 93 | $this->name = $name; 94 | 95 | return $this; 96 | } 97 | 98 | /** 99 | * Gets the machine name of this field 100 | * 101 | * @return string 102 | * 103 | * @since 2.0 104 | */ 105 | public function getName() 106 | { 107 | return $this->name; 108 | } 109 | 110 | /** 111 | * Sets a rule to validate this field with 112 | * 113 | * @param RuleInterface $rule 114 | * 115 | * @return $this 116 | * 117 | * @since 2.0 118 | */ 119 | public function addRule(RuleInterface $rule) 120 | { 121 | $this->rules[] = $rule; 122 | 123 | return $this; 124 | } 125 | 126 | /** 127 | * Returns a list of rules that will be used to validate this field 128 | * 129 | * @return RuleInterface[] 130 | * 131 | * @since 2.0 132 | */ 133 | public function getRules() 134 | { 135 | return $this->rules; 136 | } 137 | 138 | } 139 | -------------------------------------------------------------------------------- /src/FieldInterface.php: -------------------------------------------------------------------------------- 1 | register('validator', function ($dic) 30 | { 31 | return $dic->resolve('Fuel\Validation\Validator'); 32 | }); 33 | 34 | $this->register('validation.ruleprovider.array', function ($dic) 35 | { 36 | return $dic->resolve('Fuel\Validation\RuleProvider\FromArray'); 37 | }); 38 | } 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /src/Result.php: -------------------------------------------------------------------------------- 1 | result = $isValid; 62 | 63 | return $this; 64 | } 65 | 66 | /** 67 | * @return bool 68 | * 69 | * @since 2.0 70 | */ 71 | public function isValid() 72 | { 73 | return $this->result; 74 | } 75 | 76 | /** 77 | * @param string $field 78 | * 79 | * @return string 80 | * @throws InvalidFieldException 81 | * 82 | * @since 2.0 83 | */ 84 | public function getError($field) 85 | { 86 | if ( ! isset($this->errors[$field])) 87 | { 88 | throw new InvalidFieldException($field); 89 | } 90 | 91 | return $this->errors[$field]; 92 | } 93 | 94 | /** 95 | * @return string[] 96 | * 97 | * @since 2.0 98 | */ 99 | public function getErrors() 100 | { 101 | return $this->errors; 102 | } 103 | 104 | /** 105 | * Sets the error message for the given field 106 | * 107 | * @param string $field 108 | * @param string $message 109 | * @param string $rule 110 | * 111 | * @return $this 112 | * 113 | * @since 2.0 114 | */ 115 | public function setError($field, $message, $rule) 116 | { 117 | $this->errors[$field] = $message; 118 | $this->failedRules[$field] = $rule; 119 | 120 | return $this; 121 | } 122 | 123 | /** 124 | * @return string[] 125 | * 126 | * @since 2.0 127 | */ 128 | public function getValidated() 129 | { 130 | return $this->validated; 131 | } 132 | 133 | /** 134 | * @param string $field 135 | * 136 | * @return $this 137 | * 138 | * @since 2.0 139 | */ 140 | public function setValidated($field) 141 | { 142 | $this->validated[] = $field; 143 | 144 | return $this; 145 | } 146 | 147 | /** 148 | * Returns a list of rules that caused fields to fail, indexed by the field name. 149 | * 150 | * @return RuleInterface[] 151 | * 152 | * @since 2.0 153 | */ 154 | public function getFailedRules() 155 | { 156 | return $this->failedRules; 157 | } 158 | 159 | /** 160 | * {@inheritdoc} 161 | */ 162 | public function merge(ResultInterface $resultInterface, $fieldPrefix = '') 163 | { 164 | foreach ($resultInterface->getErrors() as $key => $error) 165 | { 166 | $this->errors[$fieldPrefix . $key] = $error; 167 | } 168 | 169 | foreach ($resultInterface->getFailedRules() as $key => $rules) 170 | { 171 | $this->failedRules[$fieldPrefix . $key] = $rules; 172 | } 173 | 174 | foreach ($resultInterface->getValidated() as $name) 175 | { 176 | $this->validated[] = $fieldPrefix . $name; 177 | } 178 | 179 | if ( ! $resultInterface->isValid()) 180 | { 181 | $this->result = false; 182 | } 183 | 184 | return $this; 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /src/ResultInterface.php: -------------------------------------------------------------------------------- 1 | getParameter(); 47 | $format = $parameters['format']; 48 | 49 | if ( (is_object($value) and ! method_exists($value, '__toString')) or $this->getParameter() === null ) 50 | { 51 | return false; 52 | } 53 | 54 | if ( ! $format ) 55 | { 56 | return false; 57 | } 58 | 59 | $date = date_parse_from_format($format, (string) $value); 60 | 61 | return ( $date['error_count'] + $date['warning_count'] === 0 ); 62 | 63 | } 64 | 65 | /** 66 | * Returns 67 | * 68 | * array( 69 | * 'format' => 70 | * ); 71 | * 72 | * @return array 73 | * 74 | * @since 2.0 75 | */ 76 | public function getMessageParameters() 77 | { 78 | $parameters = $this->getParameter(); 79 | $format = $parameters['format']; 80 | 81 | return array( 82 | 'format' => $format, 83 | ); 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /src/Rule/Email.php: -------------------------------------------------------------------------------- 1 | getParameter(); 54 | 55 | return in_array($value, $values, $this->strict); 56 | } 57 | 58 | /** 59 | * Sets the value(s) and mode to check against 60 | * 61 | * @param string $params 62 | * 63 | * @return $this 64 | * 65 | * @since 2.0 66 | */ 67 | public function setParameter($params) 68 | { 69 | if (is_array($params) === false) 70 | { 71 | $params = (array) $params; 72 | } 73 | elseif (array_key_exists('strict', $params) and array_key_exists('values', $params)) 74 | { 75 | $this->strict = (bool) $params['strict']; 76 | $params = $params['values']; 77 | } 78 | 79 | return parent::setParameter($params); 80 | } 81 | 82 | /** 83 | * Check strict mode 84 | * 85 | * @return bool 86 | * 87 | * @since 2.0 88 | */ 89 | public function isStrict() 90 | { 91 | return $this->strict; 92 | } 93 | 94 | /** 95 | * Set strict mode 96 | * 97 | * @param bool $strict 98 | * 99 | * @return $this 100 | * 101 | * @since 2.0 102 | */ 103 | public function setStrict($strict) 104 | { 105 | $this->strict = (bool) $strict; 106 | 107 | return $this; 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /src/Rule/EnumMulti.php: -------------------------------------------------------------------------------- 1 | 49 | * ); 50 | * 51 | * @return string[] 52 | */ 53 | public function getMessageParameters() 54 | { 55 | return array( 56 | 'values' => implode('|', $this->getParameter()), 57 | ); 58 | } 59 | 60 | /** 61 | * {@inheritdoc} 62 | */ 63 | public function validate($value, $field = null, $allFields = null) 64 | { 65 | return count(array_diff($value, $this->getParameter())) == 0; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/Rule/ExactLength.php: -------------------------------------------------------------------------------- 1 | getParameter() === null ) 45 | { 46 | return false; 47 | } 48 | 49 | mb_internal_encoding('UTF-8'); 50 | 51 | return (mb_strlen(( string ) $value) == $this->getParameter()); 52 | } 53 | 54 | /** 55 | * Sets the value to check against 56 | * 57 | * @param string $params If an array the first value will be used 58 | * 59 | * @return $this 60 | * 61 | * @since 2.0 62 | */ 63 | public function setParameter($params) 64 | { 65 | // Ensure we have only a single thing to match against 66 | if (is_array($params)) 67 | { 68 | $params = array_shift($params); 69 | } 70 | 71 | return parent::setParameter($params); 72 | } 73 | 74 | /** 75 | * Returns 76 | * 77 | * array( 78 | * 'length' => 79 | * ); 80 | * 81 | * @return string[] 82 | */ 83 | public function getMessageParameters() 84 | { 85 | return array( 86 | 'length' => $this->getParameter(), 87 | ); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/Rule/Ip.php: -------------------------------------------------------------------------------- 1 | getParameter(); 49 | 50 | // If any of the needed settings are missing, return false and 51 | // check if the array key exists, if not nothing to validate against 52 | if ($allFields === null or $matchAgainst === null or ! isset($allFields[$matchAgainst])) 53 | { 54 | return false; 55 | } 56 | 57 | return $allFields[$matchAgainst] == $value; 58 | } 59 | 60 | /** 61 | * Sets the field name to match against 62 | * 63 | * @param string $params If an array the first value will be used 64 | * 65 | * @return $this 66 | * 67 | * @since 2.0 68 | */ 69 | public function setParameter($params) 70 | { 71 | // Ensure we have only a single thing to match against 72 | if (is_array($params)) 73 | { 74 | $params = array_shift($params); 75 | } 76 | 77 | return parent::setParameter($params); 78 | } 79 | 80 | /** 81 | * Returns 82 | * 83 | * array( 84 | * 'field' => 85 | * ); 86 | * 87 | * @return string[] 88 | */ 89 | public function getMessageParameters() 90 | { 91 | return array( 92 | 'field' => $this->getParameter(), 93 | ); 94 | } 95 | 96 | } 97 | -------------------------------------------------------------------------------- /src/Rule/MaxLength.php: -------------------------------------------------------------------------------- 1 | getParameter() === null) 45 | { 46 | return false; 47 | } 48 | 49 | mb_internal_encoding('UTF-8'); 50 | 51 | return (mb_strlen(( string ) $value) <= $this->getParameter()); 52 | } 53 | 54 | /** 55 | * Sets the value to check against 56 | * 57 | * @param string $params If an array the first value will be used 58 | * 59 | * @return $this 60 | * 61 | * @since 2.0 62 | */ 63 | public function setParameter($params) 64 | { 65 | // Ensure we have only a single thing to match against 66 | if (is_array($params)) 67 | { 68 | $params = array_shift($params); 69 | } 70 | 71 | return parent::setParameter($params); 72 | } 73 | 74 | /** 75 | * Returns 76 | * 77 | * array( 78 | * 'maxLength' => 79 | * ); 80 | * 81 | * @return string[] 82 | */ 83 | public function getMessageParameters() 84 | { 85 | return array( 86 | 'maxLength' => $this->getParameter(), 87 | ); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/Rule/MinLength.php: -------------------------------------------------------------------------------- 1 | getParameter() === null ) 46 | { 47 | return false; 48 | } 49 | 50 | mb_internal_encoding('UTF-8'); 51 | 52 | return (mb_strlen(( string ) $value) >= $this->getParameter()); 53 | } 54 | 55 | /** 56 | * Sets the value to check against 57 | * 58 | * @param string $params If an array the first value will be used 59 | * 60 | * @return $this 61 | * 62 | * @since 2.0 63 | */ 64 | public function setParameter($params) 65 | { 66 | // Ensure we have only a single thing to match against 67 | if (is_array($params)) 68 | { 69 | $params = array_shift($params); 70 | } 71 | 72 | return parent::setParameter($params); 73 | } 74 | 75 | /** 76 | * Returns 77 | * 78 | * array( 79 | * 'minLength' => 80 | * ); 81 | * 82 | * @return string[] 83 | */ 84 | public function getMessageParameters() 85 | { 86 | return array( 87 | 'minLength' => $this->getParameter(), 88 | ); 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /src/Rule/Number.php: -------------------------------------------------------------------------------- 1 | getParameter(); 48 | 49 | if ( ! $this->paramsValid($params) or ! is_numeric($value)) 50 | { 51 | return false; 52 | } 53 | 54 | // We know the params are valid at this point so pull them out 55 | list($lower, $upper) = $params; 56 | 57 | return ($value >= $lower and $value <= $upper); 58 | } 59 | 60 | /** 61 | * Returns true if the given params are not null, an array and has at least two values 62 | * 63 | * @param $params 64 | * 65 | * @return bool 66 | * 67 | * @since 2.0 68 | */ 69 | protected function paramsValid($params) 70 | { 71 | if ($params === null or ! is_array($params) or count($params) < 2) 72 | { 73 | return false; 74 | } 75 | 76 | return true; 77 | } 78 | 79 | /** 80 | * Returns 81 | * 82 | * array( 83 | * 'lowerBound' => , 84 | * 'upperBound' => , 85 | * ) 86 | * 87 | * @return string[] 88 | * 89 | * @since 2.0 90 | */ 91 | public function getMessageParameters() 92 | { 93 | $upperBound = null; 94 | $lowerBound = null; 95 | 96 | $params = $this->getParameter(); 97 | 98 | if (isset($params[0])) 99 | { 100 | $lowerBound = $params[0]; 101 | } 102 | 103 | if (isset($params[1])) 104 | { 105 | $upperBound = $params[1]; 106 | } 107 | 108 | return array( 109 | 'lowerBound' => $lowerBound, 110 | 'upperBound' => $upperBound, 111 | ); 112 | } 113 | 114 | } 115 | -------------------------------------------------------------------------------- /src/Rule/NumericMax.php: -------------------------------------------------------------------------------- 1 | getParameter(); 44 | 45 | if ($max === null or ! is_numeric($value)) 46 | { 47 | return false; 48 | } 49 | 50 | return $value <= $max; 51 | } 52 | 53 | /** 54 | * Sets the value to check against 55 | * 56 | * @param string $params If an array the first value will be used 57 | * 58 | * @return $this 59 | * 60 | * @since 2.0 61 | */ 62 | public function setParameter($params) 63 | { 64 | // Ensure we have only a single thing to match against 65 | if (is_array($params)) 66 | { 67 | $params = array_shift($params); 68 | } 69 | 70 | return parent::setParameter($params); 71 | } 72 | 73 | /** 74 | * Returns 75 | * 76 | * array( 77 | * 'maxValue' => 78 | * ); 79 | * 80 | * @return string[] 81 | */ 82 | public function getMessageParameters() 83 | { 84 | return array( 85 | 'maxValue' => $this->getParameter(), 86 | ); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/Rule/NumericMin.php: -------------------------------------------------------------------------------- 1 | getParameter(); 44 | 45 | if ($min === null or ! is_numeric($value)) 46 | { 47 | return false; 48 | } 49 | 50 | return $value >= $min; 51 | } 52 | 53 | /** 54 | * Sets the value to check against 55 | * 56 | * @param string $params If an array the first value will be used 57 | * 58 | * @return $this 59 | * 60 | * @since 2.0 61 | */ 62 | public function setParameter($params) 63 | { 64 | // Ensure we have only a single thing to match against 65 | if (is_array($params)) 66 | { 67 | $params = array_shift($params); 68 | } 69 | 70 | return parent::setParameter($params); 71 | } 72 | 73 | /** 74 | * Returns 75 | * 76 | * array( 77 | * 'minValue' => 78 | * ); 79 | * 80 | * @return string[] 81 | */ 82 | public function getMessageParameters() 83 | { 84 | return array( 85 | 'minValue' => $this->getParameter(), 86 | ); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /src/Rule/Regex.php: -------------------------------------------------------------------------------- 1 | getParameter(); 45 | 46 | if ( ! is_string($value) or $regex === null) 47 | { 48 | return false; 49 | } 50 | 51 | return preg_match($regex, $value) == true; 52 | } 53 | 54 | /** 55 | * Sets the value to check against 56 | * 57 | * @param string $params If an array the first value will be used 58 | * 59 | * @return $this 60 | * 61 | * @since 2.0 62 | */ 63 | public function setParameter($params) 64 | { 65 | // Ensure we have only a single thing to match against 66 | if (is_array($params)) 67 | { 68 | $params = array_shift($params); 69 | } 70 | 71 | return parent::setParameter($params); 72 | } 73 | 74 | /** 75 | * Returns 76 | * 77 | * array( 78 | * 'pattern' => 79 | * ); 80 | * 81 | * @return string[] 82 | */ 83 | public function getMessageParameters() 84 | { 85 | return array( 86 | 'pattern' => $this->getParameter(), 87 | ); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /src/Rule/Required.php: -------------------------------------------------------------------------------- 1 | getParameter(); 36 | 37 | if ($allFields !== null and array_key_exists($requiredField, $allFields) and ! empty($allFields[$requiredField])) 38 | { 39 | return parent::validate($value, $field, $allFields); 40 | } 41 | 42 | return true; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/Rule/RequiredWith.php: -------------------------------------------------------------------------------- 1 | getParameter(); 36 | 37 | if ($allFields !== null and array_key_exists($requiredField, $allFields)) 38 | { 39 | return parent::validate($value, $field, $allFields); 40 | } 41 | 42 | return true; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/Rule/Type.php: -------------------------------------------------------------------------------- 1 | getParameter(); 47 | 48 | foreach ($allowedTypes as $type) 49 | { 50 | $isFunction = 'is_'.$type; 51 | 52 | if (function_exists($isFunction) and $isFunction($value)) 53 | { 54 | return true; 55 | } 56 | elseif ($value instanceof $type) 57 | { 58 | return true; 59 | } 60 | } 61 | 62 | return false; 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /src/Rule/Url.php: -------------------------------------------------------------------------------- 1 | getParameter(); 54 | 55 | return $validator->run($value); 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/RuleInterface.php: -------------------------------------------------------------------------------- 1 | labelKey = $labelKey; 52 | } 53 | 54 | $this->ruleKey = $ruleKey; 55 | } 56 | 57 | /** 58 | * Sets the array that will be used to generate 59 | * 60 | * @param array $data 61 | * 62 | * @return $this 63 | * 64 | * @throws InvalidArgumentException 65 | * 66 | * @since 2.0 67 | */ 68 | public function setData($data) 69 | { 70 | if ( ! is_array($data) && ! $data instanceof ArrayAccess) 71 | { 72 | throw new InvalidArgumentException('VAL-008: $data must be an array or implement the ArrayAccess interface.'); 73 | } 74 | 75 | $this->data = $data; 76 | 77 | return $this; 78 | } 79 | 80 | /** 81 | * @return array 82 | * 83 | * @since 2.0 84 | */ 85 | public function getData() 86 | { 87 | return $this->data; 88 | } 89 | 90 | /** 91 | * Should populate the given validator with the needed rules. 92 | * 93 | * @param Validator $validator 94 | * 95 | * @return Validator 96 | * 97 | * @throws InvalidArgumentException 98 | * 99 | * @since 2.0 100 | */ 101 | public function populateValidator(Validator $validator) 102 | { 103 | $data = $this->getData(); 104 | 105 | if ($data === null) 106 | { 107 | throw new InvalidArgumentException('VAL-005: No data specified. Please call setData() first.'); 108 | } 109 | 110 | // Loop through and add all the rules 111 | foreach ($data as $field => $rules) 112 | { 113 | $this->addFieldRules($field, $rules, $validator); 114 | } 115 | 116 | return $validator; 117 | } 118 | 119 | /** 120 | * Processes the given field and rules to add them to the validator. 121 | * 122 | * @param string $field Name of the field to add rules to 123 | * @param array $rules Array of any rules to be added to the field 124 | * @param Validator $validator Validator object to apply rules to 125 | * 126 | * @since 2.0 127 | */ 128 | protected function addFieldRules($field, $rules, Validator $validator) 129 | { 130 | $label = null; 131 | 132 | if ( ! empty($this->labelKey)) 133 | { 134 | if (array_key_exists($this->labelKey, $rules)) 135 | { 136 | $label = $rules[$this->labelKey]; 137 | } 138 | 139 | if (array_key_exists($this->ruleKey, $rules)) 140 | { 141 | $rules = $rules[$this->ruleKey]; 142 | } 143 | else 144 | { 145 | $rules = array(); 146 | } 147 | } 148 | 149 | $validator->addField($field, $label); 150 | 151 | // Add each of the rules 152 | foreach ($rules as $ruleName => $params) 153 | { 154 | $this->addFieldRule($field, $ruleName, $params, $validator); 155 | } 156 | } 157 | 158 | /** 159 | * Adds an individual rule for the given field to the given validator. 160 | * If the $ruleName is numeric the function will assume that $params is the rule name and that there are no 161 | * parameters. 162 | * 163 | * @param string $fieldName 164 | * @param string|int $ruleName 165 | * @param mixed $params 166 | * @param Validator $validator 167 | * 168 | * @since 2.0 169 | */ 170 | protected function addFieldRule($fieldName, $ruleName, $params, Validator $validator) 171 | { 172 | // If $ruleName is numeric assume that $params is the name and there are no actual parameters 173 | if (is_numeric($ruleName)) 174 | { 175 | $ruleName = $params; 176 | $params = []; 177 | } 178 | 179 | // Create and add the rule 180 | $ruleInstance = $validator->createRuleInstance($ruleName, $params); 181 | $validator->addRule($fieldName, $ruleInstance); 182 | } 183 | 184 | /** 185 | * @return string 186 | */ 187 | public function getLabelKey() 188 | { 189 | return $this->labelKey; 190 | } 191 | 192 | /** 193 | * @return string 194 | */ 195 | public function getRuleKey() 196 | { 197 | return $this->ruleKey; 198 | } 199 | 200 | } 201 | -------------------------------------------------------------------------------- /src/ValidatableInterface.php: -------------------------------------------------------------------------------- 1 | string $format]) 37 | * @method $this type(string $type) 38 | * @method $this enum(array $values) 39 | * @method $this enumMulti(array $values) 40 | * @method $this validator(ValidatableInterface $validator) 41 | */ 42 | class Validator implements ValidatableInterface 43 | { 44 | 45 | /** 46 | * Contains a list of fields to be validated 47 | * 48 | * @var FieldInterface[] 49 | */ 50 | protected $fields = array(); 51 | 52 | /** 53 | * Contains a list of any custom validation rules 54 | * 55 | * @var string[] 56 | */ 57 | protected $customRules = array(); 58 | 59 | /** 60 | * @var string[] 61 | */ 62 | protected $messages = array(); 63 | 64 | /** 65 | * Keeps track of the last field added for magic method chaining 66 | * 67 | * @var FieldInterface 68 | */ 69 | protected $lastAddedField; 70 | 71 | /** 72 | * Keeps track of the last rule added for message setting 73 | * 74 | * @var RuleInterface 75 | */ 76 | protected $lastAddedRule; 77 | 78 | /** 79 | * Default namespace to look for rules in when a rule is not known 80 | * 81 | * @var string 82 | */ 83 | protected $ruleNamespace = 'Fuel\Validation\Rule\\'; 84 | 85 | /** 86 | * Adds a rule that can be used to validate a field 87 | * 88 | * @param string|FieldInterface $field 89 | * @param RuleInterface $rule 90 | * 91 | * @return $this 92 | * 93 | * @since 2.0 94 | */ 95 | public function addRule($field, RuleInterface $rule) 96 | { 97 | if (is_string($field)) 98 | { 99 | try 100 | { 101 | $field = $this->getField($field); 102 | } 103 | catch (InvalidFieldException $ife) 104 | { 105 | // The field does not exist so create it 106 | $this->addField($field); 107 | $field = $this->getField($field); 108 | } 109 | } 110 | 111 | // We have a valid field now so add the rule 112 | $field->addRule($rule); 113 | 114 | $this->lastAddedRule = $rule; 115 | 116 | return $this; 117 | } 118 | 119 | /** 120 | * Adds a new field to the validation object 121 | * 122 | * @param string|FieldInterface $field 123 | * @param string $label Field name to use in messages, set to null to use $field 124 | * 125 | * @return $this 126 | * 127 | * @throws InvalidArgumentException 128 | * 129 | * @since 2.0 130 | */ 131 | public function addField($field, $label = null) 132 | { 133 | if (is_string($field)) 134 | { 135 | $field = new Field($field, $label); 136 | } 137 | 138 | if ( ! $field instanceof FieldInterface) 139 | { 140 | throw new InvalidArgumentException('VAL-007: Only FieldInterfaces can be added as a field.'); 141 | } 142 | 143 | $this->fields[$field->getName()] = $field; 144 | $this->lastAddedField = $field; 145 | 146 | return $this; 147 | } 148 | 149 | /** 150 | * Returns the given field 151 | * 152 | * @param $name 153 | * 154 | * @return FieldInterface 155 | * 156 | * @throws InvalidFieldException 157 | * 158 | * @since 2.0 159 | */ 160 | public function getField($name) 161 | { 162 | if ( ! isset($this->fields[$name])) 163 | { 164 | throw new InvalidFieldException($name); 165 | } 166 | 167 | return $this->fields[$name]; 168 | } 169 | 170 | /** 171 | * Takes an array of data and validates that against the assigned rules. 172 | * The array is expected to have keys named after fields. 173 | * This function will call reset() before it runs. 174 | * 175 | * @param array $data 176 | * @param ResultInterface $result 177 | * 178 | * @return ResultInterface 179 | * 180 | * @since 2.0 181 | */ 182 | public function run($data, ResultInterface $result = null) 183 | { 184 | if ($result === null) 185 | { 186 | $result = new Result; 187 | } 188 | 189 | $result->setResult(true); 190 | 191 | foreach ($this->fields as $fieldName => $rules) 192 | { 193 | $fieldResult = $this->validateField($fieldName, $data, $result); 194 | 195 | if ( ! $fieldResult) 196 | { 197 | // There was a failure so log it to the result object 198 | $result->setResult(false); 199 | } 200 | } 201 | 202 | return $result; 203 | } 204 | 205 | /** 206 | * Takes a field name and an array of data and validates the field against the assigned rules. 207 | * The array is expected to have keys named after fields. 208 | * This function will call reset() before it runs. 209 | * 210 | * @param string $field 211 | * @param array $data 212 | * @param ResultInterface $result 213 | * 214 | * @return ResultInterface 215 | * 216 | * @since 2.0 217 | */ 218 | public function runField($field, array $data, ResultInterface $result = null) 219 | { 220 | if ($result === null) 221 | { 222 | $result = new Result; 223 | } 224 | 225 | $fieldResult = false; 226 | 227 | if (isset($data[$field])) 228 | { 229 | $fieldResult = $this->validateField($field, $data, $result); 230 | } 231 | 232 | // Log the result 233 | $result->setResult($fieldResult); 234 | 235 | return $result; 236 | } 237 | 238 | /** 239 | * Validates a single field 240 | * 241 | * @param string $field 242 | * @param mixed[] $data 243 | * @param ResultInterface $result 244 | * 245 | * @return bool 246 | * 247 | * @since 2.0 248 | */ 249 | protected function validateField($field, $data, ResultInterface $result) 250 | { 251 | $value = null; 252 | 253 | // If there is data, and the data is not empty and not numeric. This allows for strings such as '0' to be passed 254 | // as valid values. 255 | $dataPresent = isset($data[$field]) && ! (empty($data[$field]) && ! is_numeric($data[$field])); 256 | 257 | if ($dataPresent) 258 | { 259 | $value = $data[$field]; 260 | } 261 | 262 | $rules = $this->getFieldRules($field); 263 | 264 | foreach ($rules as $rule) 265 | { 266 | if ( ! $dataPresent && ! $rule->canAlwaysRun()) 267 | { 268 | continue; 269 | } 270 | 271 | $validateResult = $rule->validate($value, $field, $data); 272 | 273 | if ($validateResult instanceof ResultInterface) 274 | { 275 | $result->merge($validateResult, $field . '.'); 276 | return $validateResult->isValid(); 277 | } 278 | 279 | if ( ! $validateResult) 280 | { 281 | // Don't allow any others to run if this one failed 282 | $result->setError($field, $this->buildMessage($this->getField($field), $rule, $value), $rule); 283 | 284 | return false; 285 | } 286 | } 287 | 288 | // All is good so make sure the field gets added as one of the validated fields 289 | $result->setValidated($field); 290 | 291 | return true; 292 | } 293 | 294 | /** 295 | * Gets a Rule's message and processes that with various tokens 296 | * 297 | * @param FieldInterface $field 298 | * @param RuleInterface $rule 299 | * 300 | * @return string 301 | */ 302 | protected function buildMessage(FieldInterface $field, RuleInterface $rule, $value) 303 | { 304 | // Build an array with all the token values 305 | $tokens = array( 306 | 'name' => $field->getName(), 307 | 'label' => $field->getLabel(), 308 | 'value' => $value, 309 | ) + $rule->getMessageParameters(); 310 | 311 | return $this->processMessageTokens($tokens, $rule->getMessage()); 312 | } 313 | 314 | /** 315 | * Replaces any {} tokens with the matching value from $tokens. 316 | * 317 | * @param array $tokens Associative array of token names and values 318 | * @param string $message 319 | * 320 | * @return string 321 | * 322 | * @since 2.0 323 | */ 324 | protected function processMessageTokens(array $tokens, $message) 325 | { 326 | foreach ($tokens as $token => $value) 327 | { 328 | // Only string values can be used in a message 329 | if (is_scalar($value) or method_exists($value, '__toString')) 330 | { 331 | $message = str_replace('{' . $token . '}', $value, $message); 332 | } 333 | } 334 | 335 | return $message; 336 | } 337 | 338 | /** 339 | * @param string $fieldName 340 | * 341 | * @return RuleInterface[] 342 | */ 343 | public function getFieldRules($fieldName) 344 | { 345 | try 346 | { 347 | $field = $this->getField($fieldName); 348 | } 349 | catch (InvalidFieldException $ife) 350 | { 351 | // No field found so no rules 352 | return array(); 353 | } 354 | 355 | return $field->getRules(); 356 | } 357 | 358 | /** 359 | * Allows validation rules to be dynamically added using method chaining. 360 | * 361 | * @param string $name 362 | * @param array $arguments 363 | * 364 | * @return $this 365 | * @throws InvalidRuleException 366 | * 367 | * @since 2.0 368 | */ 369 | public function __call($name, $arguments) 370 | { 371 | // Create and then add the new rule to the last added field 372 | $rule = $this->createRuleInstance($name, $arguments); 373 | 374 | $this->addRule($this->lastAddedField, $rule); 375 | 376 | return $this; 377 | } 378 | 379 | /** 380 | * Sets the failure message for the last added rule 381 | * 382 | * @param string $message 383 | * 384 | * @return $this 385 | * 386 | * @throws LogicException 387 | * 388 | * @since 2.0 389 | */ 390 | public function setMessage($message) 391 | { 392 | if ( ! $this->lastAddedRule) 393 | { 394 | throw new LogicException('VAL-006: A rule should be added before setting a message.'); 395 | } 396 | 397 | $this->lastAddedRule->setMessage($message); 398 | 399 | return $this; 400 | } 401 | 402 | /** 403 | * Creates an instance of the given rule name 404 | * 405 | * @param string $name 406 | * @param mixed $parameters 407 | * 408 | * @return RuleInterface 409 | * 410 | * @throws InvalidRuleException 411 | * 412 | * @since 2.0 413 | */ 414 | public function createRuleInstance($name, $parameters = []) 415 | { 416 | $className = $this->getRuleClassName($name); 417 | 418 | if ( ! class_exists($className)) 419 | { 420 | throw new InvalidRuleException($name); 421 | } 422 | 423 | /* @var RuleInterface $instance */ 424 | $reflection = new \ReflectionClass($className); 425 | $instance = $reflection->newInstanceArgs($parameters); 426 | 427 | // Check if there is a custom message 428 | $message = $this->getGlobalMessage($name); 429 | 430 | if ($message !== null) 431 | { 432 | $instance->setMessage($message); 433 | } 434 | 435 | return $instance; 436 | } 437 | 438 | /** 439 | * Returns the full class name for the given validation rule 440 | * 441 | * @param string $name 442 | * 443 | * @return string 444 | * 445 | * @since 2.0 446 | */ 447 | protected function getRuleClassName($name) 448 | { 449 | // Check if we have a custom rule registered 450 | if (isset($this->customRules[$name])) 451 | { 452 | // We do so grab the class name from the store 453 | return $this->customRules[$name]; 454 | } 455 | 456 | return $this->ruleNamespace . ucfirst($name); 457 | } 458 | 459 | /** 460 | * Adds custom validation rules and allows for core rules to be overridden. 461 | * When wanting to override a core rule just specify the rule name as $name. 462 | * Eg, 'required', 'minLength'. Note the lowercase first letter. 463 | * 464 | * The name of the rule should not contain any whitespace or special characters as the name will be available 465 | * to use as a function name in the method chaining syntax. 466 | * 467 | * @param string $name 468 | * @param string $class 469 | * 470 | * @return $this 471 | * 472 | * @since 2.0 473 | */ 474 | public function addCustomRule($name, $class) 475 | { 476 | $this->customRules[$name] = $class; 477 | 478 | return $this; 479 | } 480 | 481 | /** 482 | * Sets a custom message for all fields of the given type that are created after the message has been set. 483 | * 484 | * @param string $ruleName Name of the rule to set a message for, eg, required, number, exactLength 485 | * @param string|null $message Set to null to disable the custom message 486 | * 487 | * @return $this 488 | * 489 | * @since 2.0 490 | */ 491 | public function setGlobalMessage($ruleName, $message) 492 | { 493 | $this->messages[$ruleName] = $message; 494 | 495 | if ($message === null) 496 | { 497 | $this->removeGlobalMessage($ruleName); 498 | } 499 | 500 | return $this; 501 | } 502 | 503 | /** 504 | * Sets custom messages for one or more rules. Setting the value to "null" will remove the message 505 | * 506 | * @param string[] $messages 507 | * 508 | * @return $this 509 | * 510 | * @since 2.0 511 | */ 512 | public function setGlobalMessages($messages) 513 | { 514 | foreach ($messages as $name => $value) 515 | { 516 | $this->setGlobalMessage($name, $value); 517 | } 518 | 519 | return $this; 520 | } 521 | 522 | /** 523 | * Removes a global rule message 524 | * 525 | * @param string $ruleName 526 | * 527 | * @return $this 528 | * 529 | * @since 2.0 530 | */ 531 | public function removeGlobalMessage($ruleName) 532 | { 533 | unset($this->messages[$ruleName]); 534 | 535 | return $this; 536 | } 537 | 538 | /** 539 | * Gets the global message set for a rule 540 | * 541 | * @param string $ruleName 542 | * 543 | * @return null|string Will be null if there is no message 544 | */ 545 | public function getGlobalMessage($ruleName) 546 | { 547 | if ( ! isset($this->messages[$ruleName])) 548 | { 549 | return null; 550 | } 551 | 552 | return $this->messages[$ruleName]; 553 | } 554 | 555 | } 556 | -------------------------------------------------------------------------------- /tests/_bootstrap.php: -------------------------------------------------------------------------------- 1 | object = new Required; 24 | } 25 | 26 | /** 27 | * @dataProvider validateProvider 28 | */ 29 | public function testValidate() 30 | { 31 | list($value, $field, $expected, $data) = func_get_args(); 32 | 33 | $this->assertEquals( 34 | $expected, 35 | $this->object->validate($value, $field, $data) 36 | ); 37 | } 38 | 39 | /** 40 | * {@inheritdocs} 41 | */ 42 | public function validateProvider() 43 | { 44 | return array( 45 | 0 => array('admin@test.com', null, false, null), 46 | 1 => array('', null, false, null), 47 | 2 => array(array(), null, false, null), 48 | 3 => array(null, null, false, null), 49 | 4 => array(false, null, false, null), 50 | 51 | 5 => array('test string 5', 'test', false, 52 | array() 53 | ), 54 | 55 | 6 => array('test string 6', 'test', false, 56 | array( 57 | 'foo' => 'bar', 58 | 'baz' => 'bat', 59 | ) 60 | ), 61 | 62 | 7 => array('test string 7', 'test', true, 63 | array( 64 | 'foo' => 'bar', 65 | 'test' => 'value', 66 | 'baz' => 'bat', 67 | ) 68 | ), 69 | 70 | 8 => array('bla', 'test', true, null), 71 | 9 => array('', 'test', false, null), 72 | 10 => array('bla', null, false, array()), 73 | 11 => array('', null, false, array()), 74 | 75 | 12 => array(false, 'foo', true, 76 | array( 77 | 'foo' => false, 78 | ) 79 | ), 80 | 13 => array(true, 'foo', true, 81 | array( 82 | 'foo' => true, 83 | ) 84 | ), 85 | 86 | 14 => array(false, 'bar', true, 87 | array( 88 | 'bar' => false, 89 | ) 90 | ), 91 | 15 => array(0, 'test', true, 92 | array( 93 | 'foo' => 'bar', 94 | 'test' => 0, 95 | 'baz' => 'bat', 96 | ) 97 | ), 98 | 16 => array(0, 'test', true, array('test' => 0)), 99 | 17 => array('0', 'foo', true, 100 | array( 101 | 'foo' => '0', 102 | ) 103 | ), 104 | ); 105 | } 106 | 107 | } 108 | -------------------------------------------------------------------------------- /tests/_helpers/AbstractRuleTest.php: -------------------------------------------------------------------------------- 1 | assertEquals( 31 | $this->message, 32 | $this->object->getMessage() 33 | ); 34 | } 35 | 36 | /** 37 | * @dataProvider validateProvider 38 | */ 39 | public function testValidate() 40 | { 41 | if (func_num_args() > 2) 42 | { 43 | $this->object->setParameter(func_get_arg(2)); 44 | } 45 | 46 | list($value, $expected) = func_get_args(); 47 | 48 | $this->assertEquals( 49 | $expected, 50 | $this->object->validate($value) 51 | ); 52 | } 53 | 54 | /** 55 | * Provides sample data for testing 56 | * 57 | * @return array 58 | */ 59 | abstract public function validateProvider(); 60 | 61 | } 62 | -------------------------------------------------------------------------------- /tests/_helpers/CodeGuy.php: -------------------------------------------------------------------------------- 1 | returnValue = $c_returnValue; 25 | } 26 | 27 | public function __toString() 28 | { 29 | return $this->returnValue; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /tests/stubs/DummyAbstractRule.php: -------------------------------------------------------------------------------- 1 | object = new DummyAbstractRule; 27 | } 28 | 29 | public function testConstruct() 30 | { 31 | $params = 'foobar'; 32 | $message = 'test message'; 33 | 34 | $abstractRule = new DummyAbstractRule($params, $message); 35 | 36 | $this->assertEquals( 37 | $params, 38 | $abstractRule->getParameter() 39 | ); 40 | 41 | $this->assertEquals( 42 | $message, 43 | $abstractRule->getMessage() 44 | ); 45 | } 46 | 47 | public function testDefaultMessage() 48 | { 49 | $this->assertEquals( 50 | '', 51 | $this->object->getMessage() 52 | ); 53 | } 54 | 55 | public function testGetSetMessage() 56 | { 57 | $message = 'This is a test message'; 58 | 59 | $this->object->setMessage($message); 60 | 61 | $this->assertEquals( 62 | $message, 63 | $this->object->getMessage() 64 | ); 65 | } 66 | 67 | public function testGetParam() 68 | { 69 | $this->assertNull( 70 | $this->object->getParameter() 71 | ); 72 | } 73 | 74 | /** 75 | * @dataProvider paramDataProvider 76 | */ 77 | public function testSetGetParam($param) 78 | { 79 | $this->object->setParameter($param); 80 | 81 | $this->assertEquals( 82 | $param, 83 | $this->object->getParameter() 84 | ); 85 | } 86 | 87 | /** 88 | * Returns various formats of data for testing rule parameter getting/setting 89 | * 90 | * @return array 91 | */ 92 | public function paramDataProvider() 93 | { 94 | return array( 95 | array('Test'), 96 | array(123), 97 | array(new \stdClass()), 98 | ); 99 | } 100 | 101 | public function testGetDefaultMessageParams() 102 | { 103 | $this->assertEquals( 104 | array(), 105 | $this->object->getMessageParameters() 106 | ); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /tests/unit/CodeGuy.php: -------------------------------------------------------------------------------- 1 | object = new Field; 27 | } 28 | 29 | public function testSetGetName() 30 | { 31 | $name = 'fieldName'; 32 | 33 | $this->object->setName($name); 34 | 35 | $this->assertEquals( 36 | $name, 37 | $this->object->getName() 38 | ); 39 | } 40 | 41 | public function testSetGetLabel() 42 | { 43 | $name = 'Joe'; 44 | 45 | $this->object->setLabel($name); 46 | 47 | $this->assertEquals( 48 | $name, 49 | $this->object->getLabel() 50 | ); 51 | } 52 | 53 | public function testAddGetRules() 54 | { 55 | $rule = Mockery::mock('Fuel\Validation\RuleInterface'); 56 | 57 | $this->object->addRule($rule); 58 | 59 | $this->assertEquals( 60 | array($rule), 61 | $this->object->getRules() 62 | ); 63 | } 64 | 65 | public function testGetNullLabel() 66 | { 67 | $name = 'test'; 68 | 69 | $this->object->setName($name); 70 | 71 | $this->assertEquals( 72 | $name, 73 | $this->object->getLabel() 74 | ); 75 | } 76 | 77 | public function testConstruct() 78 | { 79 | $name = 'test'; 80 | $label = 'My Awesome Test'; 81 | 82 | $object = new Field($name, $label); 83 | 84 | $this->assertEquals( 85 | $name, 86 | $object->getName() 87 | ); 88 | 89 | $this->assertEquals( 90 | $label, 91 | $object->getLabel() 92 | ); 93 | } 94 | 95 | } 96 | -------------------------------------------------------------------------------- /tests/unit/ResultTest.php: -------------------------------------------------------------------------------- 1 | object = new Result(); 26 | } 27 | 28 | public function testSetGetResult() 29 | { 30 | $this->object->setResult(true); 31 | 32 | $this->assertTrue( 33 | $this->object->isValid() 34 | ); 35 | } 36 | 37 | public function testSetGetErrors() 38 | { 39 | $this->object->setError('field1', 'msg1', 'one'); 40 | $this->object->setError('field2', 'msg2', 'two'); 41 | $this->object->setError('field3', 'msg3', 'three'); 42 | 43 | $this->assertEquals( 44 | 'msg1', 45 | $this->object->getError('field1') 46 | ); 47 | 48 | $this->assertEquals( 49 | 'msg2', 50 | $this->object->getError('field2') 51 | ); 52 | 53 | $this->assertEquals( 54 | 'msg3', 55 | $this->object->getError('field3') 56 | ); 57 | 58 | $this->assertEquals( 59 | array( 60 | 'field1' => 'msg1', 61 | 'field2' => 'msg2', 62 | 'field3' => 'msg3', 63 | ), 64 | $this->object->getErrors() 65 | ); 66 | 67 | $this->assertEquals( 68 | array( 69 | 'field1' => 'one', 70 | 'field2' => 'two', 71 | 'field3' => 'three', 72 | ), 73 | $this->object->getFailedRules() 74 | ); 75 | } 76 | 77 | /** 78 | * @expectedException \Fuel\Validation\InvalidFieldException 79 | */ 80 | public function testGetInvalidError() 81 | { 82 | $this->object->getError('test'); 83 | } 84 | 85 | public function testSetGetValidated() 86 | { 87 | $this->object->setValidated('test'); 88 | 89 | $this->assertEquals( 90 | array('test'), 91 | $this->object->getValidated() 92 | ); 93 | } 94 | 95 | public function testMerge() 96 | { 97 | $result1 = new Result; 98 | $result1->setResult(false); 99 | $result1->setError('foo', 'foo failed', 'foocheck'); 100 | $result1->setValidated('bar'); 101 | 102 | $result2 = new Result; 103 | $result2->setResult(true); 104 | $result2->setError('baz', 'baz failed', 'bazcheck'); 105 | $result2->setValidated('bat'); 106 | 107 | $result1->merge($result2, 'sub.'); 108 | 109 | $this->assertEquals( 110 | [ 111 | 'foo' => 'foo failed', 112 | 'sub.baz' => 'baz failed', 113 | ], 114 | $result1->getErrors() 115 | ); 116 | 117 | $this->assertEquals( 118 | [ 119 | 'foo' => 'foocheck', 120 | 'sub.baz' => 'bazcheck', 121 | ], 122 | $result1->getFailedRules() 123 | ); 124 | 125 | $this->assertEquals( 126 | [ 127 | 'bar', 128 | 'sub.bat', 129 | ], 130 | $result1->getValidated() 131 | ); 132 | } 133 | 134 | public function testMergeWithStatus() 135 | { 136 | $result1 = new Result(); 137 | $result1->setResult(true); 138 | 139 | // merging this should cause the $result1 to no longer be valid 140 | $result2 = new Result(); 141 | $result2->setResult(false); 142 | 143 | $result1->merge($result2); 144 | $this->assertFalse( 145 | $result1->isValid() 146 | ); 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /tests/unit/Rule/DateTest.php: -------------------------------------------------------------------------------- 1 | object = new Date; 24 | } 25 | 26 | /** 27 | * @dataProvider validateProvider 28 | */ 29 | public function testValidate() 30 | { 31 | list($dateValue, $format, $strict, $expected) = func_get_args(); 32 | 33 | $param = array('format' => $format, 'strict' => $strict); 34 | 35 | parent::testValidate($dateValue, $expected, $param); 36 | } 37 | 38 | /** 39 | * {@inheritdocs} 40 | */ 41 | public function validateProvider() 42 | { 43 | return array( 44 | 0 => array('admin@test.com', 'Y/m/d', true, false), 45 | 1 => array('admin@test.com', null, true, false), 46 | 2 => array('admin@test.com', 'Y/m/d', false, false), 47 | 3 => array('admin@test.com', null, false, false), 48 | 4 => array('10/41/10', 'Y/m/d', true, false), 49 | 5 => array('10/41/10', null, true, false), 50 | 6 => array('10/41/10', 'Y/m/d', false, false), 51 | 7 => array('10/41/10', null, false, false), 52 | 8 => array('10/10/10', 'Y/m/d', true, true), 53 | 9 => array('10/10/10', null, true, false), 54 | 10 => array('10/10/10', 'Y/m/d', false, true), 55 | 11 => array('10/10/10', null, false, false), 56 | 12 => array('2012/10/10', 'Y/m/d', true, true), 57 | 13 => array('2012/10/10', null, true, false), 58 | 14 => array('2012/10/10', 'Y/m/d', false, true), 59 | 15 => array('2012/10/10', 'Y.m.d', false, false), 60 | 16 => array('2012.10.10', 'Y.m.d', false, true), 61 | 17 => array('2012/10/10', null, false, false), 62 | 18 => array(new \stdClass(), "Y/m.d", false, false), 63 | 19 => array(new \stdClass(), null, true, false), 64 | 20 => array(new \ClassWithToString("1990/12/12"), "Y/m/d", true, true), 65 | 21 => array(new \ClassWithToString(), "D/m/Y", true, false), 66 | 22 => array(new \ClassWithToString(), null, true, false), 67 | 23 => array(new \ClassWithToString(), 100000, true, false), 68 | 24 => array(function(){ return "10/10/10"; }, "d/m/y", true, false), 69 | ); 70 | } 71 | 72 | public function testGetMessageParams() 73 | { 74 | $parameter = 'YYYY/MM/DD'; 75 | 76 | $this->object->setParameter(array('format' => $parameter)); 77 | 78 | $this->assertEquals( 79 | array('format' => $parameter), 80 | $this->object->getMessageParameters() 81 | ); 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /tests/unit/Rule/EmailTest.php: -------------------------------------------------------------------------------- 1 | object = new Email; 24 | } 25 | 26 | /** 27 | * {@inheritdocs} 28 | */ 29 | public function validateProvider() 30 | { 31 | return array( 32 | array('admin@test.com', true), 33 | array('', false), 34 | array('@.com', false), 35 | array('test.email.user@test.domain.tld', true), 36 | ); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /tests/unit/Rule/EnumMultiTest.php: -------------------------------------------------------------------------------- 1 | object = new EnumMulti; 24 | } 25 | 26 | /** 27 | * {@inheritdocs} 28 | */ 29 | public function validateProvider() 30 | { 31 | return array( 32 | array(['foo'], true, ['foo']), 33 | array(['foo', 'bar'], true, ['foo', 'bar', 'baz', 'bat']), 34 | array(['foo', 'bar', 'wombat'], false, ['foo', 'bar', 'baz', 'bat']), 35 | ); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /tests/unit/Rule/EnumTest.php: -------------------------------------------------------------------------------- 1 | object = new Enum; 24 | } 25 | 26 | /** 27 | * {@inheritdocs} 28 | */ 29 | public function validateProvider() 30 | { 31 | return array( 32 | array('admin@test.com', true, 'admin@test.com'), 33 | array('admin@test.com', false, 'admin'), 34 | array('admin@test.com', true, array('admin', 'admin@test.com')), 35 | array(1, true, '1'), 36 | array(1, false, array('strict' => true, 'values' => array('1'))), 37 | array(1, false, array('strict' => true, 'values' => array(1.00))), 38 | array(1, true, array('strict' => true, 'values' => array(1))), 39 | array(null, false, null), 40 | ); 41 | } 42 | 43 | public function testStrict() 44 | { 45 | $this->assertFalse($this->object->isStrict()); 46 | 47 | $this->object->setParameter(array('strict' => true, 'values' => array())); 48 | 49 | $this->assertTrue($this->object->isStrict()); 50 | 51 | $this->assertEquals( 52 | $this->object, 53 | $this->object->setStrict(false) 54 | ); 55 | 56 | $this->assertFalse($this->object->isStrict()); 57 | } 58 | 59 | public function testSetParameter() 60 | { 61 | $this->object->setParameter('test value'); 62 | $this->assertEquals(array('test value'), $this->object->getParameter()); 63 | 64 | $this->object->setParameter(array('strict' => true, 'values' => array('another value'))); 65 | $this->assertEquals(array('another value'), $this->object->getParameter()); 66 | 67 | $this->object->setParameter(array('value1', 'value2')); 68 | $this->assertEquals(array('value1', 'value2'), $this->object->getParameter()); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /tests/unit/Rule/ExactLengthTest.php: -------------------------------------------------------------------------------- 1 | object = new ExactLength; 25 | } 26 | 27 | /** 28 | * {@inheritdocs} 29 | */ 30 | public function validateProvider() 31 | { 32 | return array( 33 | 0 => array('hello', false, 1), 34 | 1 => array('', false, 1), 35 | 2 => array('12345', true, 5), 36 | 3 => array('test.email.user@test.domain.tld', false, 500), 37 | 4 => array('b', true, 1), 38 | 5 => array('ä', true, 1), 39 | 6 => array('', true, 0), 40 | 7 => array('', false, -1), 41 | 8 => array('z', false, 0), 42 | 9 => array(new \stdClass(), false, 100), 43 | 10 => array(new \stdClass(), false, null), 44 | 11 => array(new \ClassWithToString(), false, 1), 45 | 12 => array(new \ClassWithToString(), true, 10), 46 | 13 => array(new \ClassWithToString(), false, null), 47 | 14 => array(new \ClassWithToString(), false, 100000), 48 | 15 => array(function(){ return false; }, false, null), 49 | 16 => array(function(){ return false; }, false, 100), 50 | 17 => array('', false, null), 51 | 18 => array(null, false, 1), 52 | 19 => array("a", false, null), 53 | 20 => array(null, false, null) 54 | ); 55 | } 56 | 57 | public function testGetMessageParams() 58 | { 59 | $parameter = 12; 60 | 61 | $this->object->setParameter($parameter); 62 | 63 | $this->assertEquals( 64 | array('length' => $parameter), 65 | $this->object->getMessageParameters() 66 | ); 67 | } 68 | 69 | public function testSetParameter() 70 | { 71 | $parameter = array(12); 72 | 73 | $this->object->setParameter($parameter); 74 | 75 | $this->assertEquals( 76 | 12, 77 | $this->object->getParameter() 78 | ); 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /tests/unit/Rule/IpTest.php: -------------------------------------------------------------------------------- 1 | object = new Ip; 24 | } 25 | 26 | /** 27 | * {@inheritdocs} 28 | */ 29 | public function validateProvider() 30 | { 31 | return array( 32 | array('', false), 33 | array(1, false), 34 | array(true, false), 35 | array(new \stdClass, false), 36 | array('512.123.1254.34234', false), 37 | array('192.168.0.1', true), 38 | array('FE80::0202:B3FF:FE1E:8329', true), 39 | array('FE80:0000:0000:0000:0202:B3FF:FE1E:8329', true), 40 | array('ZZZZ::ZZZZ:ZZZZ', false), 41 | array('ZZZZ:ZZZZ', false), 42 | array('ZZZZ::ZZZZ:ZZZZ:ZZZZ:ZZZZ', false), 43 | array('ZZZZ:ZZZZ:ZZZZ:ZZZZ:ZZZZ:ZZZZ:ZZZZ:ZZZ', false), 44 | ); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /tests/unit/Rule/MacTest.php: -------------------------------------------------------------------------------- 1 | object = new Mac; 24 | } 25 | 26 | /** 27 | * {@inheritdocs} 28 | */ 29 | public function validateProvider() 30 | { 31 | return array( 32 | array('000CF15698AD', true), 33 | array('00:0C:F1:56:98:AD', true), 34 | array('00-0C-F1-56-98-AD', true), 35 | array('000Cf15698ad', true), 36 | array('00-0c:f1:56-98ad', true), 37 | array('CF15698AD', false), 38 | array('00:0C:Q1:56:98:AD', false), 39 | array('00-0C-F1/56-98-AD', false), 40 | array('000Cf15698aq', false), 41 | array('0c:f1:56-98ad', false), 42 | ); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /tests/unit/Rule/MatchFieldTest.php: -------------------------------------------------------------------------------- 1 | object = new MatchField; 24 | } 25 | 26 | public function testRequiredParameters() 27 | { 28 | $this->assertFalse( 29 | $this->object->validate('random value') 30 | ); 31 | } 32 | 33 | public function testNoParameter() 34 | { 35 | $data = array(); 36 | 37 | $this->assertFalse( 38 | $this->object->validate('random value', 'field_name', $data) 39 | ); 40 | } 41 | 42 | /** 43 | * @dataProvider validateProvider 44 | */ 45 | public function testValidate() 46 | { 47 | list($fieldA, $fieldB, $expected, $data) = func_get_args(); 48 | 49 | $this->object->setParameter($fieldB); 50 | 51 | $this->assertEquals( 52 | $expected, 53 | $this->object->validate($data[$fieldA], $fieldA, $data) 54 | ); 55 | } 56 | 57 | /** 58 | * {@inheritdocs} 59 | */ 60 | public function validateProvider() 61 | { 62 | return array( 63 | array('a', 'b', true, 64 | array( 65 | 'a' => 'a', 66 | 'b' => 'a', 67 | ), 68 | ), 69 | 70 | array('a', 'b', false, 71 | array( 72 | 'a' => 'a', 73 | 'b' => 'b', 74 | ), 75 | ), 76 | 77 | array('a', 'b', false, 78 | array( 79 | 'a' => 'a', 80 | ), 81 | ), 82 | ); 83 | } 84 | 85 | public function testGetMessageParams() 86 | { 87 | $parameter = 'some other field'; 88 | 89 | $this->object->setParameter($parameter); 90 | 91 | $this->assertEquals( 92 | array('field' => $parameter), 93 | $this->object->getMessageParameters() 94 | ); 95 | } 96 | 97 | public function testSetParameter() 98 | { 99 | $parameter = array('some other field'); 100 | 101 | $this->object->setParameter($parameter); 102 | 103 | $this->assertEquals( 104 | 'some other field', 105 | $this->object->getParameter() 106 | ); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /tests/unit/Rule/MaxLengthTest.php: -------------------------------------------------------------------------------- 1 | object = new MaxLength; 25 | } 26 | 27 | /** 28 | * {@inheritdocs} 29 | */ 30 | public function validateProvider() 31 | { 32 | return array( 33 | 0 => array('hello', false, 1), 34 | 1 => array('', true, 1), 35 | 2 => array('12345', true, 5), 36 | 3 => array('test.email.user@test.domain.tld', true, 500), 37 | 4 => array('b', true, 1), 38 | 5 => array('ä', true, 1), 39 | 6 => array('', true, 0), 40 | 7 => array('', false, -1), 41 | 8 => array('z', false, 0), 42 | 9 => array(new \stdClass(), false, 100), 43 | 10 => array(new \stdClass(), false, null), 44 | 11 => array(new \ClassWithToString(), false, 1), 45 | 12 => array(new \ClassWithToString(), false, null), 46 | 13 => array(new \ClassWithToString(), true, 100000), 47 | 14 => array(function(){ return false; }, false, null), 48 | 15 => array(function(){ return false; }, false, 100), 49 | 16 => array('', false, null), 50 | 17 => array(null, true, 1), 51 | 18 => array("a", false, null), 52 | 19 => array(null, false, null) 53 | ); 54 | } 55 | 56 | public function testGetMessageParams() 57 | { 58 | $parameter = 12; 59 | 60 | $this->object->setParameter($parameter); 61 | 62 | $this->assertEquals( 63 | array('maxLength' => $parameter), 64 | $this->object->getMessageParameters() 65 | ); 66 | } 67 | 68 | public function testSetParameter() 69 | { 70 | $parameter = array(12); 71 | 72 | $this->object->setParameter($parameter); 73 | 74 | $this->assertEquals( 75 | 12, 76 | $this->object->getParameter() 77 | ); 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /tests/unit/Rule/MinLengthTest.php: -------------------------------------------------------------------------------- 1 | object = new MinLength; 24 | } 25 | 26 | /** 27 | * {@inheritdocs} 28 | */ 29 | public function validateProvider() 30 | { 31 | return array( 32 | 0 => array('hello', true, 1), 33 | 1 => array('', false, 1), 34 | 2 => array('12345', true, 5), 35 | 3 => array('test.email.user@test.domain.tld', false, 500), 36 | 4 => array('ä', true, 1), 37 | 5 => array('', true, 0), 38 | 6 => array('', true, -1), 39 | 7 => array('z', true, 0), 40 | 8 => array(new \stdClass(), false, 100), 41 | 9 => array(new \stdClass(), false, null), 42 | 10 => array(new \ClassWithToString(), true, 1), 43 | 11 => array(new \ClassWithToString(), false, null), 44 | 12 => array(new \ClassWithToString(), false, 100000), 45 | 13 => array(function(){ return false; }, false, null), 46 | 14 => array('', false, null), 47 | 15 => array(null, false, 1), 48 | 16 => array(null, false, null) 49 | ); 50 | } 51 | 52 | public function testGetMessageParams() 53 | { 54 | $parameter = 12; 55 | 56 | $this->object->setParameter($parameter); 57 | 58 | $this->assertEquals( 59 | array('minLength' => $parameter), 60 | $this->object->getMessageParameters() 61 | ); 62 | } 63 | 64 | public function testSetParameter() 65 | { 66 | $parameter = array(12); 67 | 68 | $this->object->setParameter($parameter); 69 | 70 | $this->assertEquals( 71 | 12, 72 | $this->object->getParameter() 73 | ); 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /tests/unit/Rule/NumberTest.php: -------------------------------------------------------------------------------- 1 | object = new Number; 24 | } 25 | 26 | /** 27 | * {@inheritdocs} 28 | */ 29 | public function validateProvider() 30 | { 31 | return array( 32 | array('123', true), 33 | array('016547', true), 34 | array('ghjgsd(*^"36723863*&723', false), 35 | array('a', false), 36 | ); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /tests/unit/Rule/NumericBetweenTest.php: -------------------------------------------------------------------------------- 1 | object = new NumericBetween; 24 | } 25 | 26 | /** 27 | * {@inheritdocs} 28 | */ 29 | public function validateProvider() 30 | { 31 | return array( 32 | 0 => array('', false, array(1, 2)), 33 | 1 => array(true, false, array(1, 2)), 34 | 2 => array(new \stdClass, false, array(1, 2)), 35 | 3 => array(0, false, array(1, 10)), 36 | 4 => array(1, true, array(1, 10)), 37 | 5 => array(2, true, array(1, 10)), 38 | 6 => array(9, true, array(1, 10)), 39 | 7 => array(10, true, array(1, 10)), 40 | 8 => array(11, false, array(1, 10)), 41 | ); 42 | } 43 | 44 | public function testValidateWithNoParam() 45 | { 46 | $this->assertFalse( 47 | $this->object->validate(5) 48 | ); 49 | } 50 | 51 | public function testGetMessageParams() 52 | { 53 | $this->object->setParameter(array(1, 10)); 54 | 55 | $this->assertEquals( 56 | array( 57 | 'lowerBound' => 1, 58 | 'upperBound' => 10, 59 | ), 60 | $this->object->getMessageParameters() 61 | ); 62 | } 63 | 64 | public function testGetMessageParamsEmpty() 65 | { 66 | $this->assertEquals( 67 | array( 68 | 'lowerBound' => null, 69 | 'upperBound' => null, 70 | ), 71 | $this->object->getMessageParameters() 72 | ); 73 | } 74 | 75 | } 76 | -------------------------------------------------------------------------------- /tests/unit/Rule/NumericMaxTest.php: -------------------------------------------------------------------------------- 1 | object = new NumericMax; 24 | } 25 | 26 | /** 27 | * {@inheritdocs} 28 | */ 29 | public function validateProvider() 30 | { 31 | return array( 32 | 0 => array('', false, 1), 33 | 1 => array(true, false, 1), 34 | 2 => array(new \stdClass, false, 1), 35 | 3 => array(1, true, 1), 36 | 4 => array(0, true, 1), 37 | 5 => array(2, false, 1), 38 | 6 => array(20, false, 1), 39 | 7 => array(5, true, 20), 40 | 8 => array(19, true, 20), 41 | 9 => array(20, true, 20), 42 | 10 => array(21, false, 20), 43 | 11 => array(2100, false, 20), 44 | 12 => array(21, false, -10), 45 | 13 => array(-20, true, -10), 46 | 14 => array(-20, false, null), 47 | ); 48 | } 49 | 50 | public function testGetMessageParams() 51 | { 52 | $parameter = 12; 53 | 54 | $this->object->setParameter($parameter); 55 | 56 | $this->assertEquals( 57 | array('maxValue' => $parameter), 58 | $this->object->getMessageParameters() 59 | ); 60 | } 61 | 62 | public function testSetParameter() 63 | { 64 | $parameter = array(12); 65 | 66 | $this->object->setParameter($parameter); 67 | 68 | $this->assertEquals( 69 | 12, 70 | $this->object->getParameter() 71 | ); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /tests/unit/Rule/NumericMinTest.php: -------------------------------------------------------------------------------- 1 | object = new NumericMin; 24 | } 25 | 26 | /** 27 | * {@inheritdocs} 28 | */ 29 | public function validateProvider() 30 | { 31 | return array( 32 | 0 => array('', false, 1), 33 | 1 => array(true, false, 1), 34 | 2 => array(new \stdClass, false, 1), 35 | 3 => array(1, true, 1), 36 | 4 => array(0, false, 1), 37 | 5 => array(2, true, 1), 38 | 6 => array(20, true, 1), 39 | 7 => array(5, false, 20), 40 | 8 => array(19, false, 20), 41 | 9 => array(20, true, 20), 42 | 10 => array(21, true, 20), 43 | 11 => array(2100, true, 20), 44 | 12 => array(21, true, -10), 45 | 13 => array(-20, false, -10), 46 | 14 => array(-20, false, null), 47 | ); 48 | } 49 | 50 | public function testGetMessageParams() 51 | { 52 | $parameter = 12; 53 | 54 | $this->object->setParameter($parameter); 55 | 56 | $this->assertEquals( 57 | array('minValue' => $parameter), 58 | $this->object->getMessageParameters() 59 | ); 60 | } 61 | 62 | public function testSetParameter() 63 | { 64 | $parameter = array(12); 65 | 66 | $this->object->setParameter($parameter); 67 | 68 | $this->assertEquals( 69 | 12, 70 | $this->object->getParameter() 71 | ); 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /tests/unit/Rule/RegexTest.php: -------------------------------------------------------------------------------- 1 | object = new Regex; 24 | } 25 | 26 | /** 27 | * {@inheritdocs} 28 | */ 29 | public function validateProvider() 30 | { 31 | return array( 32 | 0 => array('', false, null), 33 | 1 => array(1, false, '/.*/'), 34 | 2 => array(true, false, '/.*/'), 35 | 3 => array(new \stdClass, false, '/.*/'), 36 | 4 => array('hkjsghfkjgJHga', true, '/[a-zA-Z]*/'), 37 | 5 => array('', true, '/.*/'), 38 | 6 => array('ads123', false, '/^[a-z]*$/'), 39 | 7 => array('ads', true, '/[a-z]*/'), 40 | ); 41 | } 42 | 43 | public function testGetMessageParams() 44 | { 45 | $parameter = '/.*/'; 46 | 47 | $this->object->setParameter($parameter); 48 | 49 | $this->assertEquals( 50 | array('pattern' => $parameter), 51 | $this->object->getMessageParameters() 52 | ); 53 | } 54 | 55 | public function testSetParameter() 56 | { 57 | $parameter = array(12); 58 | 59 | $this->object->setParameter($parameter); 60 | 61 | $this->assertEquals( 62 | 12, 63 | $this->object->getParameter() 64 | ); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /tests/unit/Rule/RequiredIfTest.php: -------------------------------------------------------------------------------- 1 | object = new RequiredIf('field'); 19 | } 20 | 21 | /** 22 | * {@inheritdocs} 23 | */ 24 | public function validateProvider() 25 | { 26 | return array( 27 | array('value', null, false, array('field' => 'value')), 28 | array('', null, true, null), 29 | array('value', null, false, array('field' => 'othervalue')), 30 | array('value', null, true, array('field' => '')), 31 | ); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /tests/unit/Rule/RequiredTest.php: -------------------------------------------------------------------------------- 1 | object = new RequiredWith('field'); 19 | } 20 | 21 | /** 22 | * {@inheritdocs} 23 | */ 24 | public function validateProvider() 25 | { 26 | return array( 27 | array('admin@test.com', null, false, array('field' => '')), 28 | array('admin@test.com', null, true, null), 29 | array('', null, true, null), 30 | array('', null, false, array('field' => '')), 31 | ); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /tests/unit/Rule/TypeTest.php: -------------------------------------------------------------------------------- 1 | object = new Type; 24 | } 25 | 26 | /** 27 | * {@inheritdocs} 28 | */ 29 | public function validateProvider() 30 | { 31 | return array( 32 | 0 => array('admin@test.com', true, 'string'), 33 | 1 => array('admin@test.com', false, 'numeric'), 34 | 2 => array('admin@test.com', false, 'stdClass'), 35 | 3 => array('admin@test.com', true, array('numeric', 'string')), 36 | 4 => array(1, true, 'numeric'), 37 | 5 => array(1, true, 'int'), 38 | 6 => array(1, false, 'string'), 39 | 7 => array(1, false, 'stdClass'), 40 | 8 => array(1, true, array('string', 'int')), 41 | 9 => array(1, false, null), 42 | 10 => array(new \stdClass(), true, 'stdClass'), 43 | 11 => array(new \stdClass(), false, 'string'), 44 | ); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /tests/unit/Rule/UrlTest.php: -------------------------------------------------------------------------------- 1 | object = new Url; 24 | } 25 | 26 | /** 27 | * {@inheritdocs} 28 | */ 29 | public function validateProvider() 30 | { 31 | return array( 32 | array('', false), 33 | array(1, false), 34 | array(true, false), 35 | array(new \stdClass, false), 36 | array('512.123.1254.34234', false), 37 | array('http://fuelphp.com', true), 38 | array('http://fuelphp', true), 39 | array('fuelphp.com', false), 40 | array('sftp://user:password@fuelphp.com', true), 41 | array('http://192.168.0.1', true), 42 | array('ftp://FE80::0202:B3FF:FE1E:8329', true), 43 | ); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /tests/unit/Rule/ValidatorTest.php: -------------------------------------------------------------------------------- 1 | object = new Validator(); 26 | } 27 | 28 | public function testValidate() 29 | { 30 | $mock = Mockery::mock('Fuel\Validation\ValidatableInterface'); 31 | $mock->shouldReceive('run') 32 | ->with('admin@test.com') 33 | ->once() 34 | ->andReturn(true); 35 | 36 | $this->object->setParameter($mock); 37 | $this->assertEquals( 38 | true, 39 | $this->object->validate('admin@test.com') 40 | ); 41 | } 42 | 43 | /** 44 | * {@inheritdocs} 45 | */ 46 | public function validateProvider() 47 | { 48 | return []; 49 | } 50 | 51 | /** 52 | * @expectedException \InvalidArgumentException 53 | * @expectedExceptionMessage VAL-009: Provided parameter does not implement ValidatableInterface 54 | */ 55 | public function testSetInvalidParameter() 56 | { 57 | $this->object->setParameter('foo'); 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /tests/unit/RuleProvider/FromArrayTest.php: -------------------------------------------------------------------------------- 1 | object = new FromArray; 28 | } 29 | 30 | /** 31 | * @expectedException \InvalidArgumentException 32 | */ 33 | public function testNoData() 34 | { 35 | $this->assertNull( 36 | $this->object->getData() 37 | ); 38 | 39 | $validator = \Mockery::mock('Fuel\Validation\Validator'); 40 | 41 | $this->object->populateValidator($validator); 42 | } 43 | 44 | public function testPopulate() 45 | { 46 | $data = array( 47 | 'test field' => array( 48 | 'required', 49 | 'minLength' => 12, 50 | ), 51 | ); 52 | 53 | $validator = \Mockery::mock('Fuel\Validation\Validator'); 54 | 55 | // Ensure the field gets added 56 | $validator->shouldReceive('addField')->once()->with('test field', null); 57 | 58 | // Create some expected rules 59 | $requiredRule = new Required; 60 | $minLengthRule = new MinLength(12); 61 | 62 | // Make sure the mocked object knows that the rules need to be created 63 | $validator->shouldReceive('createRuleInstance')->with('required', null)->once()->andReturn($requiredRule); 64 | $validator->shouldReceive('createRuleInstance')->with('minLength', 12)->once()->andReturn($minLengthRule); 65 | 66 | // Finally make sure the addRule function is called 67 | $validator->shouldReceive('addRule')->with('test field', $requiredRule)->once(); 68 | $validator->shouldReceive('addRule')->with('test field', $minLengthRule)->once(); 69 | 70 | $this->object->setData($data); 71 | $this->object->populateValidator($validator); 72 | } 73 | 74 | public function testLabel() 75 | { 76 | $object = new FromArray('label'); 77 | 78 | $data = array( 79 | 'test field' => array( 80 | 'label' => 'Test field', 81 | 'rules' => array( 82 | 'required', 83 | 'minLength' => 12, 84 | ), 85 | ), 86 | ); 87 | 88 | $validator = \Mockery::mock('Fuel\Validation\Validator'); 89 | 90 | // Ensure the field gets added 91 | $validator->shouldReceive('addField')->once()->with('test field', 'Test field'); 92 | 93 | // Create some expected rules 94 | $requiredRule = new Required; 95 | $minLengthRule = new MinLength(12); 96 | 97 | // Make sure the mocked object knows that the rules need to be created 98 | $validator->shouldReceive('createRuleInstance')->with('required', null)->once()->andReturn($requiredRule); 99 | $validator->shouldReceive('createRuleInstance')->with('minLength', 12)->once()->andReturn($minLengthRule); 100 | 101 | // Finally make sure the addRule function is called 102 | $validator->shouldReceive('addRule')->with('test field', $requiredRule)->once(); 103 | $validator->shouldReceive('addRule')->with('test field', $minLengthRule)->once(); 104 | 105 | $object->setData($data); 106 | $object->populateValidator($validator); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /tests/unit/ValidatorTest.php: -------------------------------------------------------------------------------- 1 | object = new Validator; 35 | 36 | $this->testFields = array( 37 | 'email' => array( 38 | new Email(), 39 | ), 40 | 'age' => array( 41 | new Number(), 42 | ), 43 | ); 44 | } 45 | 46 | /** 47 | * Adds sample fields and rules to the validation object 48 | */ 49 | protected function addTestRules() 50 | { 51 | foreach ($this->testFields as $field => $rules) 52 | { 53 | $this->object->addField($field); 54 | 55 | foreach ($rules as $rule) 56 | { 57 | $this->object->addRule($field, $rule); 58 | } 59 | } 60 | } 61 | 62 | public function testAddField() 63 | { 64 | $field = 'test field'; 65 | 66 | $this->object->addField($field); 67 | 68 | $this->assertInstanceOf( 69 | 'Fuel\Validation\FieldInterface', 70 | $this->object->getField($field) 71 | ); 72 | } 73 | 74 | public function testGetField() 75 | { 76 | $field = new Field('field'); 77 | 78 | $this->object->addField($field); 79 | 80 | $this->assertSame( 81 | $field, 82 | $this->object->getField('field') 83 | ); 84 | } 85 | 86 | /** 87 | * @expectedException \Fuel\Validation\InvalidFieldException 88 | */ 89 | public function testGetFieldFailure() 90 | { 91 | $this->object->getField('field'); 92 | } 93 | 94 | public function testAddRule() 95 | { 96 | $field = 'field'; 97 | $rule = new Email(); 98 | 99 | $this->assertInstanceOf( 100 | 'Fuel\Validation\Validator', 101 | $this->object->addRule($field, $rule) 102 | ); 103 | 104 | $rules = $this->object->getFieldRules($field); 105 | 106 | $this->assertEquals(reset($rules), $rule); 107 | } 108 | 109 | public function testRun() 110 | { 111 | $fieldName = 'email'; 112 | 113 | $this->object->addRule($fieldName, new Email()); 114 | 115 | $this->assertTrue( 116 | $this->object->run(array( 117 | $fieldName => 'user@domain.example', 118 | ) 119 | )->isValid() 120 | ); 121 | } 122 | 123 | public function testRunField() 124 | { 125 | $fieldName = 'email'; 126 | 127 | $this->object->addRule($fieldName, new Email()); 128 | 129 | $this->assertTrue( 130 | $this->object->runField( 131 | $fieldName, 132 | array( 133 | $fieldName => 'user@domain.example', 134 | ) 135 | )->isValid() 136 | ); 137 | 138 | $this->assertFalse( 139 | $this->object->runField( 140 | $fieldName, 141 | array( 142 | $fieldName => 'example', 143 | ) 144 | )->isValid() 145 | ); 146 | } 147 | 148 | public function testRunFailure() 149 | { 150 | $fieldName = 'email'; 151 | 152 | $this->object->addRule($fieldName, new Email()); 153 | 154 | $this->assertFalse( 155 | $this->object->run(array( 156 | $fieldName => 'example', 157 | ) 158 | )->isValid() 159 | ); 160 | } 161 | 162 | public function testRunFieldFailure() 163 | { 164 | $this->assertFalse( 165 | $this->object->runField( 166 | 'email', 167 | array() 168 | )->isValid() 169 | ); 170 | } 171 | 172 | /** 173 | * @dataProvider runMultipleFieldsData 174 | */ 175 | public function testRunMultipleFields($expected, $data) 176 | { 177 | $this->addTestRules(); 178 | 179 | $this->assertEquals( 180 | $expected, 181 | $this->object->run($data)->isValid() 182 | ); 183 | } 184 | 185 | /** 186 | * Provides various data sets to test validation running 187 | * 188 | * @return array 189 | */ 190 | public function runMultipleFieldsData() 191 | { 192 | return array( 193 | array(true, array('email' => 'user@domain.example', 'age' => 12)), 194 | array(false, array('email' => 'example', 'age' => 12)), 195 | array(false, array('email' => 'user@domain.example', 'age' => 'asdasd')), 196 | array(true, array('email' => 'user@domain.example')), 197 | array(true, array('age' => 12)), 198 | array(true, array()), 199 | ); 200 | } 201 | 202 | /** 203 | * @expectedException \Fuel\Validation\InvalidRuleException 204 | */ 205 | public function testMagicRuleInvalid() 206 | { 207 | $this->object->fakeTestRule(); 208 | } 209 | 210 | public function testAddMagicRule() 211 | { 212 | $this->object->addField('test') 213 | ->required(); 214 | 215 | $rules = $this->object->getField('test')->getRules(); 216 | 217 | $this->assertInstanceOf( 218 | 'Fuel\Validation\Rule\Required', 219 | $rules[0] 220 | ); 221 | } 222 | 223 | public function testSetMessage() 224 | { 225 | $rule = new Number; 226 | 227 | $this->object->addRule('test', $rule) 228 | ->setMessage('injected message'); 229 | 230 | $this->assertEquals( 231 | 'injected message', 232 | $rule->getMessage() 233 | ); 234 | } 235 | 236 | /** 237 | * @expectedException \LogicException 238 | */ 239 | public function testSetMessageException() 240 | { 241 | $this->object->setMessage('injected message'); 242 | } 243 | 244 | public function testMagicChain() 245 | { 246 | $this->object 247 | ->addField('first magic test') 248 | ->number() 249 | ->addField('test') 250 | ->required() 251 | ->matchField('first'); 252 | 253 | $firstRules = $this->object->getFieldRules('first magic test'); 254 | 255 | // Make sure the first rule has been added correctly 256 | $this->assertEquals( 257 | 1, 258 | count($firstRules) 259 | ); 260 | 261 | $this->assertInstanceOf( 262 | 'Fuel\Validation\Rule\Number', 263 | $firstRules[0] 264 | ); 265 | 266 | // Make sure the second field's rules are added correctly 267 | $testRules = $this->object->getFieldRules('test'); 268 | 269 | // Make sure there are two entries 270 | $this->assertEquals( 271 | 2, 272 | count($testRules) 273 | ); 274 | 275 | // And that the right rules have been added 276 | $this->assertInstanceOf( 277 | 'Fuel\Validation\Rule\Required', 278 | $testRules[0] 279 | ); 280 | 281 | $this->assertInstanceOf( 282 | 'Fuel\Validation\Rule\MatchField', 283 | $testRules[1] 284 | ); 285 | } 286 | 287 | /** 288 | * @expectedException \InvalidArgumentException 289 | */ 290 | public function testAddInvalidField() 291 | { 292 | $this->object->addField(new \stdClass()); 293 | } 294 | 295 | public function testGetInvalidFieldRules() 296 | { 297 | $this->assertEquals( 298 | array(), 299 | $this->object->getFieldRules('fake test field') 300 | ); 301 | } 302 | 303 | public function testAddCustomRule() 304 | { 305 | $this->object->addCustomRule('testRule', '\DummyAbstractRule'); 306 | 307 | $this->assertInstanceOf( 308 | '\DummyAbstractRule', 309 | $this->object->createRuleInstance('testRule') 310 | ); 311 | 312 | // Check that our magic methods are working 313 | } 314 | 315 | /** 316 | * @expectedException \Fuel\Validation\InvalidRuleException 317 | */ 318 | public function testCreateRuleInstanceFailure() 319 | { 320 | $this->object->createRuleInstance('testRule'); 321 | } 322 | 323 | public function testAddCoreRuleOverride() 324 | { 325 | $this->object->addCustomRule('required', '\DummyAbstractRule'); 326 | 327 | $this->assertInstanceOf( 328 | '\DummyAbstractRule', 329 | $this->object->createRuleInstance('required') 330 | ); 331 | } 332 | 333 | public function testMessageReplacement() 334 | { 335 | $this->object->addField('test', 'My Field') 336 | ->number() 337 | ->setMessage('{label} with the data from {name} must be a number but I got {value}!'); 338 | 339 | $result = $this->object->run(array('test' => 'abc')); 340 | 341 | $this->assertEquals( 342 | 'My Field with the data from test must be a number but I got abc!', 343 | $result->getError('test') 344 | ); 345 | } 346 | 347 | public function testGetSetGlobalMessage() 348 | { 349 | $message = 'Test message'; 350 | $ruleName = 'test'; 351 | 352 | $this->assertNull( 353 | $this->object->getGlobalMessage($ruleName) 354 | ); 355 | 356 | $this->object->setGlobalMessage($ruleName, $message); 357 | 358 | $this->assertEquals( 359 | $message, 360 | $this->object->getGlobalMessage($ruleName) 361 | ); 362 | 363 | $this->object->setGlobalMessage($ruleName, null); 364 | 365 | $this->assertNull( 366 | $this->object->getGlobalMessage($ruleName) 367 | ); 368 | } 369 | 370 | public function testCreateRuleInstanceWithGlobalMessage() 371 | { 372 | $message = 'Test message'; 373 | $ruleName = 'test'; 374 | $class = '\DummyAbstractRule'; 375 | 376 | $this->object->setGlobalMessage($ruleName, $message); 377 | 378 | $this->object->addCustomRule($ruleName, $class); 379 | 380 | $instance = $this->object->createRuleInstance($ruleName); 381 | 382 | $this->assertEquals( 383 | $message, 384 | $instance->getMessage() 385 | ); 386 | } 387 | 388 | /** 389 | * The required rule was not being run if the data did not contain the required field, resulting in a false positive 390 | * @link https://github.com/fuelphp/validation/issues/30 391 | */ 392 | public function testRequired() 393 | { 394 | $this->object->addField('foobar') 395 | ->required(); 396 | 397 | $data = []; 398 | 399 | $result = $this->object->run($data); 400 | 401 | $this->assertFalse( 402 | $result->isValid() 403 | ); 404 | } 405 | 406 | public function testBuildWithArrayParameter() 407 | { 408 | $this->object->addField('date') 409 | ->date(['format' => 'Y-m-d']); 410 | 411 | $data = [ 412 | 'date' => '2014-10-11', 413 | ]; 414 | 415 | $result = $this->object->run($data); 416 | 417 | $this->assertTrue($result->isValid()); 418 | } 419 | 420 | public function testValidateFieldWithEmptyString() 421 | { 422 | $this->object 423 | ->addField('tel_no') 424 | ->number(); 425 | 426 | $data = array( 427 | 'tel_no' => '', 428 | ); 429 | 430 | $result = $this->object->run($data); 431 | 432 | $this->assertTrue($result->isValid()); 433 | 434 | $data = array( 435 | 'tel_no' => '0', 436 | ); 437 | 438 | $result = $this->object->run($data); 439 | 440 | $this->assertTrue($result->isValid()); 441 | } 442 | 443 | public function testNestedValidator() 444 | { 445 | $validator = new Validator(); 446 | $validator 447 | ->addField('test') 448 | ->maxLength(5); 449 | 450 | $this->object 451 | ->addField('child') 452 | ->validator($validator); 453 | 454 | $this->object 455 | ->addField('foobar') 456 | ->required(); 457 | 458 | $result = $this->object->run([ 459 | 'foobar' => 'test', 460 | 'child' => ['test' => '1234'] 461 | ]); 462 | 463 | $this->assertTrue($result->isValid()); 464 | $this->assertEquals( 465 | [ 466 | 'child.test', 467 | 'foobar', 468 | ], 469 | $result->getValidated() 470 | ); 471 | } 472 | public function testNestedValidatorFailure() 473 | { 474 | $validator = new Validator(); 475 | $validator 476 | ->addField('test') 477 | ->maxLength(5); 478 | 479 | $this->object 480 | ->addField('child') 481 | ->validator($validator); 482 | 483 | $this->object 484 | ->addField('foobar') 485 | ->required(); 486 | 487 | $result = $this->object->run([ 488 | 'foobar' => 'test', 489 | 'child' => ['test' => '1234567890'] 490 | ]); 491 | 492 | $this->assertFalse($result->isValid()); 493 | $this->assertEquals( 494 | ['foobar'], 495 | $result->getValidated() 496 | ); 497 | $this->assertEquals( 498 | ['child.test' => 'The field is longer than the allowed maximum length.'], 499 | $result->getErrors() 500 | ); 501 | } 502 | 503 | 504 | } 505 | -------------------------------------------------------------------------------- /tests/unit/_bootstrap.php: -------------------------------------------------------------------------------- 1 |