Skip to content

Commit e3fd23e

Browse files
committed
* New Validator: RequiredUnless with validation data: anotherField:value,... - The field under validation must be present and not empty unless the anotherfield field is equal to the passed value.
* New Validator: `RequiredIf` with validation data: `anotherField:value,...` - The field under validation must be present and not empty if the `anotherfield` field is equal to the passed `value`.
1 parent f9e4b72 commit e3fd23e

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+687
-207
lines changed

changelog.md

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,29 @@
22

33
## 2.0.0
44

5-
* `Features` : Removed all interface usages since all cfml engines suck on it.
6-
* `Improvements` : Consistency on all validators to ignore null or empty values except the `Required` validator
7-
* `Improvements` : Formatting consistencies
8-
* `Improvements` : Improve error messages to describe better validation
9-
* `Improvements` : Get away from `evaluate()` instead use `invoke()`
5+
### Features
6+
7+
* No more manual discovery of validators, automated registration and lookup process, cleaned lots of code on this one!
8+
* New Validator: `Accepted` - The field under validation must be yes, on, 1, or true. This is useful for validating "Terms of Service" acceptance.
9+
* New Validator: `Alpha` - Only allows alphabetic characters
10+
* New Validator: `RequiredUnless` with validation data: `anotherField:value,...` - The field under validation must be present and not empty unless the `anotherfield` field is equal to the passed `value`.
11+
* New Validator: `RequiredIf` with validation data: `anotherField:value,...` - The field under validation must be present and not empty if the `anotherfield` field is equal to the passed `value`.
12+
13+
### Improvements
14+
15+
* Consistency on all validators to ignore null or empty values except the `Required` validator
16+
* Formatting consistencies
17+
* Improve error messages to describe better validation
18+
* Get away from `evaluate()` instead use `invoke()`
19+
20+
### Compat & Bugs
21+
1022
* `Bugs` : Fixed lots of wrong type exceptions
1123
* `Compat` : Remove ACF11 support
1224

25+
`requiredUnless=role,test
26+
---
27+
1328
## 1.5.2
1429

1530
* `bug` : Added `float` to the type validator which was missing

models/GenericObject.cfc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
/**
2-
* *******************************************************************************
3-
* Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
2+
* Copyright since 2020 by Ortus Solutions, Corp
43
* www.ortussolutions.com
5-
* *******************************************************************************
4+
* ---
65
* Great for when you want to validate a form that is not represented by an object.
76
* A generic object that can simulate an object getters from a collection structure.
87
*/

models/IValidationManager.cfc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
/**
2-
* *******************************************************************************
3-
* Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
2+
* Copyright since 2020 by Ortus Solutions, Corp
43
* www.ortussolutions.com
5-
* *******************************************************************************
4+
* ---
65
* The ColdBox validation manager interface, all inspired by awesome Hyrule Validation Framework by Dan Vega
76
*/
87
import cbvalidation.models.*;

models/ValidationManager.cfc

Lines changed: 32 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
/**
2-
* ********************************************************************************
3-
* Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
2+
* Copyright since 2020 by Ortus Solutions, Corp
43
* www.ortussolutions.com
5-
* ********************************************************************************
4+
* ---
65
*
76
* The ColdBox Validation Manager, all inspired by awesome Hyrule Validation Framework by Dan Vega.
87
*
@@ -70,6 +69,12 @@ component accessors="true" serialize="false" implements="IValidationManager" sin
7069
*/
7170
property name="sharedConstraints" type="struct";
7271

72+
/**
73+
* The collection of registered validators on disk
74+
*/
75+
property name="registeredValidators" type="Struct";
76+
77+
// Unique manager id
7378
this.id = createUUID();
7479

7580
/**
@@ -82,6 +87,23 @@ component accessors="true" serialize="false" implements="IValidationManager" sin
8287
variables.validValidators = "required,type,size,range,regex,sameAs,sameAsNoCase,inList,discrete,udf,method,validator,min,max";
8388
// store shared constraints if passed
8489
variables.sharedConstraints = arguments.sharedConstraints;
90+
// Validators Path
91+
variables.validatorsPath = getDirectoryFromPath( getMetadata( this ).path ) & "validators";
92+
// Register validators
93+
variables.registeredValidators = directoryList( variables.validatorsPath , false, "name", "*.cfc" )
94+
// don't do the interfaces
95+
.filter( function( item ){
96+
return ( item != "IValidator.cfc" );
97+
} )
98+
// Purge extension
99+
.map( function( item ){
100+
return listFirst( item, "." );
101+
} )
102+
// Build out wirebox map
103+
.reduce( function( result, item ){
104+
result[ item.replaceNoCase( "Validator", "" ) ] = "cbvalidation.models.validators.#item#";
105+
return result;
106+
}, {} );
85107

86108
return this;
87109
}
@@ -250,54 +272,21 @@ component accessors="true" serialize="false" implements="IValidationManager" sin
250272
required string validatorType,
251273
required any validationData
252274
){
253-
var cfcPrefix = "cbvalidation.models.validators";
275+
// Are we a core validator?
276+
if( structKeyExists( variables.registeredValidators, arguments.validatorType ) ){
277+
return wirebox.getInstance( variables.registeredValidators[ arguments.validatorType ] );
278+
}
254279

280+
// Else switch checks
255281
switch ( arguments.validatorType ) {
256-
case "required": {
257-
return wirebox.getInstance( "#cfcPrefix#.RequiredValidator" );
258-
}
259-
case "type": {
260-
return wirebox.getInstance( "#cfcPrefix#.TypeValidator" );
261-
}
262-
case "size": {
263-
return wirebox.getInstance( "#cfcPrefix#.SizeValidator" );
264-
}
265-
case "range": {
266-
return wirebox.getInstance( "#cfcPrefix#.RangeValidator" );
267-
}
268-
case "regex": {
269-
return wirebox.getInstance( "#cfcPrefix#.RegexValidator" );
270-
}
271-
case "sameAs": {
272-
return wirebox.getInstance( "#cfcPrefix#.SameAsValidator" );
273-
}
274-
case "sameAsNoCase": {
275-
return wirebox.getInstance( "#cfcPrefix#.SameAsNoCaseValidator" );
276-
}
277-
case "inList": {
278-
return wirebox.getInstance( "#cfcPrefix#.InListValidator" );
279-
}
280-
case "discrete": {
281-
return wirebox.getInstance( "#cfcPrefix#.DiscreteValidator" );
282-
}
283-
case "min": {
284-
return wirebox.getInstance( "#cfcPrefix#.MinValidator" );
285-
}
286-
case "max": {
287-
return wirebox.getInstance( "#cfcPrefix#.MaxValidator" );
288-
}
289-
case "udf": {
290-
return wirebox.getInstance( "#cfcPrefix#.UDFValidator" );
291-
}
292-
case "method": {
293-
return wirebox.getInstance( "#cfcPrefix#.MethodValidator" );
294-
}
282+
// Custom Validator
295283
case "validator": {
296284
if ( find( ":", arguments.validationData ) ) {
297285
return wirebox.getInstance( getToken( arguments.validationData, 2, ":" ) );
298286
}
299287
return wirebox.getInstance( arguments.validationData );
300288
}
289+
// See if it's a WireBox Mapping
301290
default: {
302291
if ( wirebox.getBinder().mappingExists( validatorType ) ) {
303292
return wirebox.getInstance( validatorType );

models/result/IValidationError.cfc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
/**
2-
********************************************************************************
3-
Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
4-
www.coldbox.org | www.luismajano.com | www.ortussolutions.com
5-
********************************************************************************
6-
The ColdBox validation error interface, all inspired by awesome Hyrule Validation Framework by Dan Vega
7-
*/
2+
* Copyright since 2020 by Ortus Solutions, Corp
3+
* www.ortussolutions.com
4+
* ---
5+
* The ColdBox validation error interface, all inspired by awesome Hyrule Validation Framework by Dan Vega
6+
*/
87
import cbvalidation.models.result.*;
98
interface {
109

models/result/IValidationResult.cfc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
/**
2-
********************************************************************************
3-
Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
4-
www.coldbox.org | www.luismajano.com | www.ortussolutions.com
5-
********************************************************************************
6-
The ColdBox validation results interface, all inspired by awesome Hyrule Validation Framework by Dan Vega
7-
*/
2+
* Copyright since 2020 by Ortus Solutions, Corp
3+
* www.ortussolutions.com
4+
* ---
5+
* The ColdBox validation results interface, all inspired by awesome Hyrule Validation Framework by Dan Vega
6+
*/
87
import cbvalidation.models.result.*;
98
interface{
109

models/result/ValidationError.cfc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
/**
2-
********************************************************************************
3-
Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
4-
www.coldbox.org | www.luismajano.com | www.ortussolutions.com
5-
********************************************************************************
6-
The ColdBox validation error, all inspired by awesome Hyrule Validation Framework by Dan Vega
7-
*/
2+
* Copyright since 2020 by Ortus Solutions, Corp
3+
* www.ortussolutions.com
4+
* ---
5+
* The ColdBox validation error, all inspired by awesome Hyrule Validation Framework by Dan Vega
6+
*/
87
component accessors="true" implements="cbvalidation.models.result.IValidationError" {
98

109
// constructor

models/result/ValidationResult.cfc

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
/**
2-
********************************************************************************
3-
Copyright Since 2005 ColdBox Framework by Luis Majano and Ortus Solutions, Corp
4-
www.coldbox.org | www.luismajano.com | www.ortussolutions.com
5-
********************************************************************************
6-
The ColdBox validation results
7-
*/
2+
* Copyright since 2020 by Ortus Solutions, Corp
3+
* www.ortussolutions.com
4+
* ---
5+
* The ColdBox validation results
6+
*/
87
component accessors="true" implements="cbvalidation.models.result.IValidationResult"{
98

109
/**
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* Copyright since 2020 by Ortus Solutions, Corp
3+
* www.ortussolutions.com
4+
* ---
5+
* The field under validation must be yes, on, 1, or true. This is useful for validating "Terms of Service" acceptance.
6+
*/
7+
component accessors="true" implements="cbvalidation.models.validators.IValidator" singleton {
8+
9+
property name="name";
10+
11+
/**
12+
* Constructor
13+
*/
14+
AcceptedValidator function init(){
15+
variables.name = "Accepted";
16+
return this;
17+
}
18+
19+
/**
20+
* Will check if an incoming value validates
21+
* @validationResultThe result object of the validation
22+
* @targetThe target object to validate on
23+
* @fieldThe field on the target object to validate on
24+
* @targetValueThe target value to validate
25+
* @validationDataThe validation data the validator was created with
26+
*/
27+
boolean function validate(
28+
required cbvalidation.models.result.IValidationResult validationResult,
29+
required any target,
30+
required string field,
31+
any targetValue,
32+
any validationData
33+
){
34+
// return true if no data to check, type needs a data element to be checked.
35+
if ( isNull( arguments.targetValue ) || ( isSimpleValue( arguments.targetValue ) && !len( arguments.targetValue ) ) ) {
36+
return true;
37+
}
38+
39+
if ( listFindNoCase( "1,yes,true,on", arguments.targetValue ) ) {
40+
return true;
41+
}
42+
43+
var args = {
44+
message : "The '#arguments.field#' is not a 1, yes, true or on",
45+
field : arguments.field,
46+
validationType : getName(),
47+
rejectedValue : ( isSimpleValue( arguments.targetValue ) ? arguments.targetValue : "" ),
48+
validationData : arguments.validationData
49+
};
50+
var error = validationResult.newError( argumentCollection = args ).setErrorMetadata( { max : arguments.validationData } );
51+
validationResult.addError( error );
52+
return false;
53+
}
54+
55+
/**
56+
* Get the name of the validator
57+
*/
58+
string function getName(){
59+
return variables.name;
60+
}
61+
62+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**
2+
* Copyright since 2020 by Ortus Solutions, Corp
3+
* www.ortussolutions.com
4+
* ---
5+
* The field under validation must be yes, on, 1, or true. This is useful for validating "Terms of Service" acceptance.
6+
*/
7+
component accessors="true" implements="cbvalidation.models.validators.IValidator" singleton {
8+
9+
property name="name";
10+
11+
/**
12+
* Constructor
13+
*/
14+
AlphaValidator function init(){
15+
variables.name = "Alpha";
16+
return this;
17+
}
18+
19+
/**
20+
* Will check if an incoming value validates
21+
* @validationResultThe result object of the validation
22+
* @targetThe target object to validate on
23+
* @fieldThe field on the target object to validate on
24+
* @targetValueThe target value to validate
25+
* @validationDataThe validation data the validator was created with
26+
*/
27+
boolean function validate(
28+
required cbvalidation.models.result.IValidationResult validationResult,
29+
required any target,
30+
required string field,
31+
any targetValue,
32+
any validationData
33+
){
34+
// return true if no data to check, type needs a data element to be checked.
35+
if ( isNull( arguments.targetValue ) || ( isSimpleValue( arguments.targetValue ) && !len( arguments.targetValue ) ) ) {
36+
return true;
37+
}
38+
39+
// Alpha only
40+
if ( reFindNoCase( "^[A-Za-z]+$", arguments.targetValue ) ) {
41+
return true;
42+
}
43+
44+
var args = {
45+
message : "The '#arguments.field#' is not alpha only",
46+
field : arguments.field,
47+
validationType : getName(),
48+
rejectedValue : ( isSimpleValue( arguments.targetValue ) ? arguments.targetValue : "" ),
49+
validationData : arguments.validationData
50+
};
51+
var error = validationResult.newError( argumentCollection = args ).setErrorMetadata( { max : arguments.validationData } );
52+
validationResult.addError( error );
53+
return false;
54+
}
55+
56+
/**
57+
* Get the name of the validator
58+
*/
59+
string function getName(){
60+
return variables.name;
61+
}
62+
63+
}

0 commit comments

Comments
 (0)